<?xml version="1.0"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title>Second Life Wiki - User contributions [en]</title>
		<link>https://wiki.secondlife.com/wiki/Special:Contributions/Flennan_Roffo</link>
		<description>User contributions</description>
		<language>en</language>
		<generator>MediaWiki 1.42.1</generator>
		<lastBuildDate>Wed, 01 Jul 2026 10:08:38 GMT</lastBuildDate>
		<item>
			<title>Shoutcast - radio controller v0.3 (remake of similar scripts)</title>
			<link>https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133927</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133927</guid>
			<description>&lt;p&gt;Flennan Roffo: /* Shoutcast - radio controller */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}}&lt;br /&gt;
=Shoutcast - radio controller=&lt;br /&gt;
This script controls a shoutcast radio receiver and lets you select the stations that you configured on a notecard. Menu driven. Output of station description, genre and current song title using Xy text.&lt;br /&gt;
Credits for this script go to previous developers of similar scripts:&lt;br /&gt;
* &#039;&#039;&#039;Scripter Coba&#039;&#039;&#039; who wrote the &#039;&#039;LandOwnersRadio (V2.0)&#039;&#039; script. Menu driven / notecard config script to select genre and station to set parcel music url.&lt;br /&gt;
* &#039;&#039;&#039;Jamie Otis&#039;&#039;&#039; who wrote the &#039;&#039;Raven radio infoboard&#039;&#039; script. Shows what song is playing by fetching info using the sis.slserver.info/sis.php service (now offline). Display on Xytext.&lt;br /&gt;
* &#039;&#039;&#039;Darkie Minotaur&#039;&#039;&#039; who wrote the &#039;&#039;currentPlaying&#039;&#039; script. Shows what song is currently playing by fetching info from the /7.html shoutcast page.&lt;br /&gt;
&lt;br /&gt;
Although this script is based upon similar functionality as provided in these scripts, this script is not simply a merge/copy of those scripts, but a complete make-over. &lt;br /&gt;
I use my own notecard format and processing of notecard info, and own menu system.&lt;br /&gt;
&lt;br /&gt;
==Versions==&lt;br /&gt;
&lt;br /&gt;
Current version: v0.3 released 10-2-2011&lt;br /&gt;
&lt;br /&gt;
==Scripts==&lt;br /&gt;
&lt;br /&gt;
===Shoutcast - radio controller===&lt;br /&gt;
This script should be put into the shoutcast - radio controller device.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// Script:  Shoutcast - radio controller&lt;br /&gt;
// Version: 0.3 - released 10-2-2011&lt;br /&gt;
// Logic Scripts (Flennan Roffo)&lt;br /&gt;
// (c) 2010 - Flennan Roffo (Logic Scripts)&lt;br /&gt;
// &lt;br /&gt;
// This script is a remake of a couple of similar script:&lt;br /&gt;
// + LandOwnersRadio V2.0 by Scripter Coba  (( menu driven / notecard config script to select the radio station and sets parcel music url ))&lt;br /&gt;
// + Raven radio infoboard by Jamie Otis    (( worked at the basis of sis service [sis.slserver.com/sis.php] used Xy text display         ))&lt;br /&gt;
// + currentPlaying by Darkie Minotaur      (( used the /7.html info to fetch current song title info, displayed as float text            ))&lt;br /&gt;
//&lt;br /&gt;
// Purpose:&lt;br /&gt;
// * Sets the parcel audio URL and displays the channel info&lt;br /&gt;
// * Uses Xytext to display the info.&lt;br /&gt;
// * Fetches song title info from the shoutcast url&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.1 release&lt;br /&gt;
// * On/Off option&lt;br /&gt;
// * Allows multiple menus (if options per menu &amp;gt; 12) using a prev/next button&lt;br /&gt;
// * Checks if your url is well-formatted&lt;br /&gt;
// * Will delete genres for which no stations exist&lt;br /&gt;
// * Will skip stations that have same url and same genre (you can however have an identical station url under different genres).&lt;br /&gt;
// * New notecard format&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.2 release&lt;br /&gt;
// * Configurable button text&lt;br /&gt;
// * Gets parcel URL and automatically sets the genre/station and on/off status accordingly (&amp;lt;-- doesn&#039;t work)&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Update -- 0.3 release&lt;br /&gt;
// * Fixed bug (only first station in genre displayed in menu)&lt;br /&gt;
// * Auto reset script when config card updated&lt;br /&gt;
// Notes:&lt;br /&gt;
// * Expects url to be in the format: &amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;, where &amp;lt;ip&amp;gt; has the format: xxx.xxx.xxx.xxx  (0 &amp;lt;= xxx &amp;lt;= 255) &lt;br /&gt;
// * Deletes entries in category (genre) for which no stations are configured with notice.&lt;br /&gt;
// * Skips stations which have identical url AND same category (genre).&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Upcoming release -- 0.4&lt;br /&gt;
// * Will add functions for remote controller(s) and remote display(s) using llRegionSay to communicate over a channel.&lt;br /&gt;
// * Should relax on the constraints about the input format of URL&#039;s (currently requires that URL has format: xxx.xxx.xxx.xxx/yyyy).&lt;br /&gt;
// * Fix button placement. Control buttons should be on the first line.&lt;br /&gt;
// * Implement script reset on change of owner.&lt;br /&gt;
// * Permit station to be put under multiple genres, using a comma-seperated list of genres in the section [STATION]&lt;br /&gt;
//   (currently this is only possible by duplicating the entire line and change the genre.)&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Future plans:&lt;br /&gt;
// * Individual user preferences that can be stored on seperate note cards. A user has access to his own list of genres and stations and the system available genres/stations.&lt;br /&gt;
// * Feature for accessing online playlists (M3U, PLS, other formats) to play a list of songs provided by that playlist.&lt;br /&gt;
// * User provided url.&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// BUGS &amp;amp; FEATURE REQUESTS&lt;br /&gt;
//&lt;br /&gt;
// Please inform the author, Logic Scripts (flennan.roffo) about any bugs or annoyances.&lt;br /&gt;
// Feature requests can also be submitted to the author.&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// LICENCE INFO&lt;br /&gt;
//&lt;br /&gt;
// This program is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string info_notecard=&amp;quot;Radio Control info&amp;quot;;              ///////    EDITABLE  \\\\\\&lt;br /&gt;
string config_notecard=&amp;quot;Radio Control config&amp;quot;;          ///////    EDITABLE  \\\\\\&lt;br /&gt;
string comment_char=&amp;quot;#&amp;quot;;                                ///////    EDITABLE  \\\\\\&lt;br /&gt;
list sep_char_list= [&amp;quot;|&amp;quot;];                              ///////    EDITABLE  \\\\\\&lt;br /&gt;
float update_time=5.0;                                  ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string no_title_info=&amp;quot;(no title info available)&amp;quot;;       ///////    EDITABLE  \\\\\\&lt;br /&gt;
&lt;br /&gt;
// not used currently - for showing info on current song title elsewhere in the region&lt;br /&gt;
integer broadcast_channel=-1234;                        ///////    EDITABLE  \\\\\\ &lt;br /&gt;
&lt;br /&gt;
// Buttons&lt;br /&gt;
&lt;br /&gt;
string button_MAIN = &amp;quot;MAIN&amp;quot;;                            ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string button_HELP = &amp;quot;HELP&amp;quot;;                            ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string button_NEXT = &amp;quot;&amp;gt;&amp;gt;&amp;quot;;                              ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string button_PREV = &amp;quot;&amp;lt;&amp;lt;&amp;quot;;                              ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string button_ON   = &amp;quot;ON&amp;quot;;                              ///////    EDITABLE  \\\\\\  &lt;br /&gt;
string button_OFF  = &amp;quot;OFF&amp;quot;;                             ///////    EDITABLE  \\\\\\ &lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// Don&#039;t touch the variables below &lt;br /&gt;
/////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
// List of categories (=genres)&lt;br /&gt;
&lt;br /&gt;
list category_list=[];&lt;br /&gt;
&lt;br /&gt;
// List of stations. KEEP THESE LISTS IN SYNCH!&lt;br /&gt;
&lt;br /&gt;
list station_category=[];&lt;br /&gt;
list station_name=[];&lt;br /&gt;
list station_desc=[];&lt;br /&gt;
list station_url=[];&lt;br /&gt;
&lt;br /&gt;
// Last song title played&lt;br /&gt;
string last_title_info=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
integer radio_status=0;    // 0 - OFF   1 - ON&lt;br /&gt;
string parcel_url=&amp;quot;&amp;quot;;&lt;br /&gt;
integer lineno=0;&lt;br /&gt;
key reqid=NULL_KEY;&lt;br /&gt;
key httpreq_id=NULL_KEY;&lt;br /&gt;
integer config_error=FALSE;&lt;br /&gt;
integer flag;&lt;br /&gt;
integer section=0;&lt;br /&gt;
&lt;br /&gt;
// Access values. Note that users who are banned can not access the device even when access is public&lt;br /&gt;
integer owner_access=TRUE;&lt;br /&gt;
integer group_access=FALSE;&lt;br /&gt;
integer public_access=TRUE;&lt;br /&gt;
list banned_keys=[];&lt;br /&gt;
&lt;br /&gt;
// Channels for menu and user input&lt;br /&gt;
integer menu_channel;&lt;br /&gt;
integer listen_handle;&lt;br /&gt;
&lt;br /&gt;
// Menu&lt;br /&gt;
integer menu_type=0;         // 0 - Main menu (genres)   1 - Station menu (stations)&lt;br /&gt;
integer menu_num=0;          // When more menu options need to be selectable then can be displayed on a menu (12), this is the menu number - menu number 0 is the first menu.&lt;br /&gt;
&lt;br /&gt;
// Genres and stations&lt;br /&gt;
&lt;br /&gt;
integer category_index=0;    // Current index in category_list  (genre)&lt;br /&gt;
integer station_index=0;     // Current index in station_*      (station)&lt;br /&gt;
&lt;br /&gt;
integer num_categories=0;&lt;br /&gt;
integer num_stations=0;&lt;br /&gt;
&lt;br /&gt;
// Make request for title info using HTTP request&lt;br /&gt;
retrieve_titelinfo()&lt;br /&gt;
{&lt;br /&gt;
    string url=llList2String(station_url,station_index);&lt;br /&gt;
    httpreq_id=llHTTPRequest(url + &amp;quot;/7.html  HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n&amp;quot;,[],&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Display a line on an Xytext device linked in&lt;br /&gt;
display_line(string line, string message)&lt;br /&gt;
{&lt;br /&gt;
    // Setup XYtext Variables&lt;br /&gt;
    integer DISPLAY_STRING      = 204000; &lt;br /&gt;
//    integer DISPLAY_EXTENDED    = 204001;     (not used)&lt;br /&gt;
//    integer REMAP_INDICES       = 204002;     (not used) &lt;br /&gt;
//    integer RESET_INDICES       = 204003;     (not used)&lt;br /&gt;
//    integer SET_CELL_INFO       = 204004;     (not used)&lt;br /&gt;
//    integer SET_FONT_TEXTURE    = 204005;     (not used)&lt;br /&gt;
//    integer SET_THICKNESS       = 204006;     (not used)&lt;br /&gt;
//    integer SET_COLOR           = 204007;     (not used)&lt;br /&gt;
&lt;br /&gt;
    llMessageLinked(LINK_SET,DISPLAY_STRING,message,line);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Clear the Xytext display&lt;br /&gt;
clear_display() &lt;br /&gt;
{&lt;br /&gt;
    // Clears the display&lt;br /&gt;
    display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio Station ID&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;2&amp;quot;,&amp;quot;Music Genre....&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;3&amp;quot;,&amp;quot;Now Playing....&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Make a menu / dialog&lt;br /&gt;
make_menu(key id)&lt;br /&gt;
{&lt;br /&gt;
     menu_channel=random_channel();&lt;br /&gt;
&lt;br /&gt;
    if (radio_status == 0)&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        llDialog(id,&amp;quot;Menu: Status\n\nRadio is OFF&amp;quot;, [ &amp;quot;ON&amp;quot;, &amp;quot;HELP&amp;quot; ],menu_channel);&lt;br /&gt;
    }&lt;br /&gt;
    else &lt;br /&gt;
    {&lt;br /&gt;
        if (menu_type ==0)&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Genres&amp;quot;, category_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Stations\nGenre: &amp;quot; + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (listen_handle != 0)    llListenRemove(listen_handle);&lt;br /&gt;
    listen_handle=llListen(menu_channel,&amp;quot;&amp;quot;,id,&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Make the menu option list for menu: catagories (genres)&lt;br /&gt;
list category_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
&lt;br /&gt;
    if (len &amp;gt; 9)   // If more then 9 items (12 minus the 3 buttons for MAIN/HELP and PREV, NEXT)&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;   // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc. &lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt; last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
&lt;br /&gt;
             while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_HELP;&lt;br /&gt;
             else&lt;br /&gt;
                 menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_OFF;&lt;br /&gt;
             else&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num != last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;       &lt;br /&gt;
        }            &lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
        menu+=(list)button_OFF;&lt;br /&gt;
        menu+=(list)button_HELP;&lt;br /&gt;
    }        &lt;br /&gt;
    &lt;br /&gt;
    return menu;    // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns the number of stations in a certain category&lt;br /&gt;
integer stations_in_category(integer cat)&lt;br /&gt;
{&lt;br /&gt;
    integer count=0;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
    string category=llList2String(category_list,cat);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (category == llList2String(category_list,i))&lt;br /&gt;
            count++;&lt;br /&gt;
&lt;br /&gt;
    return count;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Not used currently -- to fix button placement&lt;br /&gt;
list order_buttons(list buttons)&lt;br /&gt;
{&lt;br /&gt;
    integer offset;&lt;br /&gt;
    list fixt;&lt;br /&gt;
    integer flag=0;&lt;br /&gt;
&lt;br /&gt;
    while((offset = llGetListLength(buttons)))&lt;br /&gt;
    {&lt;br /&gt;
        if (offset &amp;gt; 3)&lt;br /&gt;
            flag=1;&lt;br /&gt;
        else&lt;br /&gt;
            flag=0;&lt;br /&gt;
&lt;br /&gt;
        fixt += llList2List(buttons, offset = -3 * flag, -1);&lt;br /&gt;
        buttons = llDeleteSubList(buttons, offset, -1);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return fixt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns a list of station names in a certain category (genre)&lt;br /&gt;
list station_list(integer category)&lt;br /&gt;
{&lt;br /&gt;
    list s=[];&lt;br /&gt;
    integer i;&lt;br /&gt;
    string cname=llList2String(category_list,category_index);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; llGetListLength(station_name); i++)&lt;br /&gt;
        if (llList2String(station_category,i) == cname)&lt;br /&gt;
            s+=(list)llList2String(station_name,i);&lt;br /&gt;
&lt;br /&gt;
    return s;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns the list of stations for the station menu, depending on the submenu number&lt;br /&gt;
list station_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
    list stations=station_list(category_index);&lt;br /&gt;
    integer len=llGetListLength(stations);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
        &lt;br /&gt;
    if (len &amp;gt; 11)       // 12 - 1 for MAIN menu&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;&lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt;= last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
             integer last=9*num+8;&lt;br /&gt;
&lt;br /&gt;
             menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;gt; 0)&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;lt; last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;                      &lt;br /&gt;
&lt;br /&gt;
            if (len &amp;gt; last)&lt;br /&gt;
                len =last;&lt;br /&gt;
                &lt;br /&gt;
            while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(stations,len);&lt;br /&gt;
        }&lt;br /&gt;
    }            &lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(stations,len);&lt;br /&gt;
    }        &lt;br /&gt;
&lt;br /&gt;
    return menu; // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns whether av with key id has access&lt;br /&gt;
integer has_access(key id)&lt;br /&gt;
{&lt;br /&gt;
    if (llListFindList(banned_keys,(list)id) != -1)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    if (owner_access &amp;amp;&amp;amp; id == llGetOwner())&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (group_access &amp;amp;&amp;amp; llSameGroup(id))&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (public_access)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Gets a random channel -- uses a wide range of big negative channel numbers seldomly used&lt;br /&gt;
integer random_channel()&lt;br /&gt;
{&lt;br /&gt;
    integer min=-2147483647;&lt;br /&gt;
    integer max=-1000;&lt;br /&gt;
&lt;br /&gt;
    return (integer) (min + llFrand(max-min));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Check for the format of the url string  -- is very selective about url format&lt;br /&gt;
// expects:   xxx.xxx.xxx.xxx:xxxx    (ip adress in number notation with port adress)&lt;br /&gt;
// Next release will relax on this constraint.&lt;br /&gt;
integer check_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    integer pos=0;&lt;br /&gt;
&lt;br /&gt;
    if (llGetSubString(url,0,6) == &amp;quot;http://&amp;quot;)&lt;br /&gt;
        pos=7;        &lt;br /&gt;
    if (llGetSubString(url,0,7) == &amp;quot;https://&amp;quot;)&lt;br /&gt;
        pos=8;&lt;br /&gt;
&lt;br /&gt;
    if (pos==0)   return FALSE;&lt;br /&gt;
&lt;br /&gt;
    string str_ip_port=llGetSubString(url,pos,-1);&lt;br /&gt;
    list list_ip_port=llParseString2List(str_ip_port,[&amp;quot;:&amp;quot;],[]);                 // split in ip-adress and port&lt;br /&gt;
    list list_ip=llParseString2List(llList2String(list_ip_port,0),[&amp;quot;.&amp;quot;],[]);    // split ip-adress elements&lt;br /&gt;
&lt;br /&gt;
    if (llGetListLength(list_ip_port) != 2 || llGetListLength(list_ip) != 4)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer test;&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;4;i++)&lt;br /&gt;
    {&lt;br /&gt;
        test=llList2Integer(list_ip,i);&lt;br /&gt;
        if (llList2String(list_ip,i) != (string)test)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        if (test &amp;lt; 0 || test &amp;gt; 255)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    test=llList2Integer(list_ip_port,1);&lt;br /&gt;
    if (llList2String(list_ip_port,1) != (string)test)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns a true value depending on the first character in input - anything else is assumed false.&lt;br /&gt;
integer true_value(string input)&lt;br /&gt;
{&lt;br /&gt;
    string value=llToLower(llGetSubString(input,0,0));&lt;br /&gt;
&lt;br /&gt;
    if (value == &amp;quot;y&amp;quot; || value == &amp;quot;t&amp;quot; || value ==&amp;quot;1&amp;quot;)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Return if more input should be processed (if not at EOF) - sets ConfigError if any config error found. Reading config card stops at the first error.&lt;br /&gt;
integer process_line(string dataline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(dataline,STRING_TRIM);&lt;br /&gt;
    integer index=llSubStringIndex(line,comment_char);&lt;br /&gt;
    &lt;br /&gt;
    if (index==0)       // line starts with comment - ignore line&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (index!=-1)&lt;br /&gt;
        line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL);   // skip everything after comment_char and trim tail&lt;br /&gt;
&lt;br /&gt;
    if (line==&amp;quot;&amp;quot;)       // Ignore blank lines&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (llToLower(line) == &amp;quot;[access]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 1;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[banned]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 2;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[genre]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 3;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[station]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 4;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llGetSubString(line,0,0) == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; llGetSubString(line,-1,-1) == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: malformed section found at line &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
        config_error=TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: no section found on line: &amp;quot; + (string) lineno);&lt;br /&gt;
        config_error = TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    list breakup=llParseString2List(line,[&amp;quot;=&amp;quot;],[]);&lt;br /&gt;
    string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);&lt;br /&gt;
    string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);&lt;br /&gt;
&lt;br /&gt;
    if (section == 1)            // access&lt;br /&gt;
    {&lt;br /&gt;
        field=llToLower(field);&lt;br /&gt;
&lt;br /&gt;
        if (field==&amp;quot;owner&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            owner_access=true_value(values);                       &lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;group&amp;quot;)&lt;br /&gt;
        {    &lt;br /&gt;
            group_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;public&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            public_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: invalid option on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 2)         // ban list&lt;br /&gt;
    {&lt;br /&gt;
        key try=(key) field;&lt;br /&gt;
&lt;br /&gt;
        if (try)&lt;br /&gt;
        {&lt;br /&gt;
            banned_keys+=(list)((key) field);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 3)           // categories&lt;br /&gt;
    {&lt;br /&gt;
        if (llListFindList(category_list,(list)field) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            category_list+=(list)field;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;genre: &#039;&amp;quot; + field + &amp;quot;&#039; already entered; double entry skipped.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 4)            // stations&lt;br /&gt;
    {&lt;br /&gt;
        list parse=llParseString2List(line,sep_char_list, []);&lt;br /&gt;
        string category=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);&lt;br /&gt;
        string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);&lt;br /&gt;
    &lt;br /&gt;
        if (!available_category(category))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: unknown genre on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (check_url(url))&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                num_stations++;&lt;br /&gt;
                station_category+=(list)category;&lt;br /&gt;
                station_name+=(list)name;&lt;br /&gt;
                station_desc+=(list)desc;&lt;br /&gt;
                station_url+=(list)url;&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llWhisper(0,&amp;quot;This station is already entered under the same genre and same url and is skipped.\nStation: &amp;quot; + name + &amp;quot;\nGenre: &#039;&amp;quot; + category + &amp;quot;&#039;\nURL: &amp;quot; + url);&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: malformed url on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
     &lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Sets the parcel URL and updates the display&lt;br /&gt;
set_parcel_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    parcel_url=url;&lt;br /&gt;
    llSetParcelMusicURL(parcel_url);&lt;br /&gt;
&lt;br /&gt;
    if (parcel_url==&amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        clear_display();&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is OFF&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;station now set to &amp;quot; + llList2String(station_desc,station_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Station: &amp;quot; + llList2String(station_desc,station_index));&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;Genre  : &amp;quot; + llList2String(category_list,category_index));&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;Now playing.....&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns if a category (genre) exists.&lt;br /&gt;
integer available_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;len;i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(category_list,i)))&lt;br /&gt;
            return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns if a category (genre) is empty (i.e. there are no stations for this catagory (genre))&lt;br /&gt;
integer empty_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(station_category,i)))&lt;br /&gt;
            return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Removes categories (genres) for which no station is known.&lt;br /&gt;
skip_empty_categories()&lt;br /&gt;
{&lt;br /&gt;
    integer i=0;&lt;br /&gt;
&lt;br /&gt;
    while (i&amp;lt;llGetListLength(category_list))&lt;br /&gt;
    {&lt;br /&gt;
        if (empty_category(llList2String(category_list,i)))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;Warning: Genre &#039;&amp;quot; + llList2String(category_list,i) + &amp;quot;&#039; contains no stations and is deleted.&amp;quot;);&lt;br /&gt;
            category_list=llDeleteSubList(category_list,i,i);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            i++;&lt;br /&gt;
    }&lt;br /&gt;
            &lt;br /&gt;
    num_categories=llGetListLength(category_list);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state default&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        flag=FALSE;&lt;br /&gt;
        lineno=0;&lt;br /&gt;
        config_error=FALSE;&lt;br /&gt;
        num_stations=0;&lt;br /&gt;
        num_categories=0;&lt;br /&gt;
        radio_status=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(config_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
           reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
           llWhisper(0, &amp;quot;Reading config notecard...&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;1&amp;quot;,&amp;quot;Reading configuration.&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;2&amp;quot;,&amp;quot;Wait....&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;No config notecard &#039;&amp;quot; +  config_notecard + &amp;quot;&#039; present.&amp;quot;);&lt;br /&gt;
            state offline;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (reqid==id)&lt;br /&gt;
        {        &lt;br /&gt;
            if (data==EOF)&lt;br /&gt;
            {&lt;br /&gt;
                skip_empty_categories();&lt;br /&gt;
                llWhisper(0,&amp;quot;Configuration ok.\n&amp;quot; + (string)num_categories + &amp;quot; genres and &amp;quot; + (string)num_stations + &amp;quot; stations.&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Configuration OK&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;2&amp;quot;,&amp;quot;Genres  : &amp;quot; + (string)num_categories);&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Stations: &amp;quot; + (string)num_stations);&lt;br /&gt;
                state menu;&lt;br /&gt;
            }&lt;br /&gt;
            else &lt;br /&gt;
            {&lt;br /&gt;
                if (process_line(data))&lt;br /&gt;
                    reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
                else if (config_error)&lt;br /&gt;
                {&lt;br /&gt;
                    llWhisper(0,&amp;quot;errors found in configuration. please correct them.&amp;quot;);&lt;br /&gt;
                    state offline;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state offline&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state offline&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;Reset on owner touch or when notecard updated.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    touch_start(integer t)&lt;br /&gt;
    {&lt;br /&gt;
        if (llDetectedKey(0)==llGetOwner())&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state menu&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state menu&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        listen_handle=0;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
        key toucher=llDetectedKey(0);&lt;br /&gt;
&lt;br /&gt;
        if (has_access(toucher))&lt;br /&gt;
        {&lt;br /&gt;
            make_menu(toucher);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;sorry, no access.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    listen(integer chan, string name,key id,string msg)&lt;br /&gt;
    {&lt;br /&gt;
        integer index;&lt;br /&gt;
&lt;br /&gt;
        if (menu_type == 0)          // main menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_ON)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=1;&lt;br /&gt;
                set_parcel_url(parcel_url);               &lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is ON&amp;quot;);&lt;br /&gt;
                menu_num=0;&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned on.&amp;quot;);&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=0;&lt;br /&gt;
                set_parcel_url(&amp;quot;&amp;quot;);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned off.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
                {&lt;br /&gt;
                    llGiveInventory(id,info_notecard);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                    llWhisper(0,&amp;quot;sorry, help not available.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (radio_status == 1)&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(category_list, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: genre not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    category_index=index;&lt;br /&gt;
                    llWhisper(0,&amp;quot;Genre now set to &amp;quot; + llList2String(category_list,category_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
                    menu_type=1;&lt;br /&gt;
                    menu_num=0;&lt;br /&gt;
                    make_menu(id);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (menu_type == 1 &amp;amp;&amp;amp; radio_status == 1)     // station menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(station_name, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: station not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    station_index=index;&lt;br /&gt;
                    string new_url=llList2String(station_url,station_index);&lt;br /&gt;
&lt;br /&gt;
                    if (new_url != parcel_url)&lt;br /&gt;
                    {&lt;br /&gt;
                        set_parcel_url(new_url);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        retrieve_titelinfo();&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_response(key id, integer status, list meta, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == httpreq_id)&lt;br /&gt;
        {&lt;br /&gt;
            if (status == 200)&lt;br /&gt;
            {&lt;br /&gt;
                string feed = llGetSubString(body,llSubStringIndex(body, &amp;quot;&amp;lt;body&amp;gt;&amp;quot;) + llStringLength(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;), llSubStringIndex(body,&amp;quot;&amp;lt;/body&amp;gt;&amp;quot;) - 1);&lt;br /&gt;
                list feed_list = llParseString2List(feed,[&amp;quot;,&amp;quot;],[]);&lt;br /&gt;
                string current_title_info= llList2String(feed_list,6);&lt;br /&gt;
                integer length = llGetListLength(feed_list);&lt;br /&gt;
        &lt;br /&gt;
                if(llList2String(feed_list,7))&lt;br /&gt;
                {&lt;br /&gt;
                    integer a = 7;&lt;br /&gt;
                    for(; a&amp;lt;length; ++a)&lt;br /&gt;
                    {&lt;br /&gt;
                        current_title_info += &amp;quot;, &amp;quot; + llList2String(feed_list,a);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
         &lt;br /&gt;
                if (current_title_info != last_title_info)&lt;br /&gt;
                {&lt;br /&gt;
                    last_title_info = current_title_info;&lt;br /&gt;
                    display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + current_title_info);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + no_title_info);&lt;br /&gt;
            }&lt;br /&gt;
        }    &lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
// end of script&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Notecard format===&lt;br /&gt;
Example notecard&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# New format Shoutcast - radio controller config notecard&lt;br /&gt;
# The format is divided in 4 sections:&lt;br /&gt;
# 1 - Access configuration&lt;br /&gt;
# 2 - Ban list (keys)&lt;br /&gt;
# 3 - Categories  (same as genres)&lt;br /&gt;
# 4 - Station info (category, name, desc, url)&lt;br /&gt;
# The &#039;#&#039; character defines the start of a comment and can be anywhere on a line. &lt;br /&gt;
# Everything after the &#039;#&#039; incuding the &#039;#&#039; itself is ignored.&lt;br /&gt;
# Case is not important (but information on display will show as entered)&lt;br /&gt;
# Spaces before and/or after fields are trimmed.&lt;br /&gt;
# Empty lines are ignored.&lt;br /&gt;
&lt;br /&gt;
[ACCESS]&lt;br /&gt;
owner=yes       # yes, true,1      means owner has access. everything else not.&lt;br /&gt;
group=yes       #  ,,  ,,  ,,      means group has acess.    ,,        ,,   ,,&lt;br /&gt;
public=yes      #  ,,  ,,  ,,      means public has access.  ,,        ,,   ,, &lt;br /&gt;
&lt;br /&gt;
[BANNED]&lt;br /&gt;
# keys of banned residents&lt;br /&gt;
&lt;br /&gt;
[GENRE]&lt;br /&gt;
# genre name -- Use short genre names as the the length of menu buttons is short!&lt;br /&gt;
Hard Rock&lt;br /&gt;
Classic Rock&lt;br /&gt;
Oldies&lt;br /&gt;
Rap/Urban&lt;br /&gt;
Comedy&lt;br /&gt;
News&lt;br /&gt;
Dance&lt;br /&gt;
Country&lt;br /&gt;
Gothic&lt;br /&gt;
# etc.&lt;br /&gt;
[STATION]&lt;br /&gt;
# Shoutcast radio stations&lt;br /&gt;
# Use a &#039;|&#039; between each field - don&#039;t mind spaces before and after fields, they will be trimmed&lt;br /&gt;
# field1:genre, field2:station name, field3: station description, field4: station http://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt; or https://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;&lt;br /&gt;
# Note that genre must match case-insensitive a value previously entered in section [GENRE]&lt;br /&gt;
Classic Rock    | Absolute         |    Absolute Radio                  | http://205.188.215.226:8018&lt;br /&gt;
# etc.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===TODO===&lt;br /&gt;
&lt;br /&gt;
Planned for upcoming release 0.4:&lt;br /&gt;
* Add a llRegionSay to broadcast the &amp;lt;station&amp;gt;|&amp;lt;genre&amp;gt;|&amp;lt;current songtitle&amp;gt;|&amp;lt;url&amp;gt; to the region and add a script that displays that info on a remote Xytext board. (for use with a remote controller and/or remote display board anywhere in the region/parcel)&lt;br /&gt;
* llResetScript on owner change&lt;br /&gt;
* Relax on URL format&lt;br /&gt;
* Allow multiple genres per station&lt;/div&gt;</description>
			<pubDate>Thu, 10 Feb 2011 01:08:05 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)</comments>
		</item>
		<item>
			<title>Shoutcast - radio controller v0.3 (remake of similar scripts)</title>
			<link>https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133926</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133926</guid>
			<description>&lt;p&gt;Flennan Roffo: /* Shoutcast - radio controller */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}}&lt;br /&gt;
=Shoutcast - radio controller=&lt;br /&gt;
This script controls a shoutcast radio receiver and lets you select the stations that you configured on a notecard. Menu driven. Output of station description, genre and current song title using Xy text.&lt;br /&gt;
Credits for this script go to previous developers of similar scripts:&lt;br /&gt;
* &#039;&#039;&#039;Scripter Coba&#039;&#039;&#039; who wrote the &#039;&#039;LandOwnersRadio (V2.0)&#039;&#039; script. Menu driven / notecard config script to select genre and station to set parcel music url.&lt;br /&gt;
* &#039;&#039;&#039;Jamie Otis&#039;&#039;&#039; who wrote the &#039;&#039;Raven radio infoboard&#039;&#039; script. Shows what song is playing by fetching info using the sis.slserver.info/sis.php service (now offline). Display on Xytext.&lt;br /&gt;
* &#039;&#039;&#039;Darkie Minotaur&#039;&#039;&#039; who wrote the &#039;&#039;currentPlaying&#039;&#039; script. Shows what song is currently playing by fetching info from the /7.html shoutcast page.&lt;br /&gt;
&lt;br /&gt;
Although this script is based upon similar functionality as provided in these scripts, this script is not simply a merge/copy of those scripts, but a complete make-over. &lt;br /&gt;
I use my own notecard format and processing of notecard info, and own menu system.&lt;br /&gt;
&lt;br /&gt;
==Versions==&lt;br /&gt;
&lt;br /&gt;
Current version: v0.3 released 10-2-2011&lt;br /&gt;
&lt;br /&gt;
==Scripts==&lt;br /&gt;
&lt;br /&gt;
===Shoutcast - radio controller===&lt;br /&gt;
This script should be put into the shoutcast - radio controller device.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// Script:  Shoutcast - radio controller&lt;br /&gt;
// Version: 0.3 - released 10-2-2011&lt;br /&gt;
// Logic Scripts (Flennan Roffo)&lt;br /&gt;
// (c) 2010 - Flennan Roffo (Logic Scripts)&lt;br /&gt;
// &lt;br /&gt;
// This script is a remake of a couple of similar script:&lt;br /&gt;
// + LandOwnersRadio V2.0 by Scripter Coba  (( menu driven / notecard config script to select the radio station and sets parcel music url ))&lt;br /&gt;
// + Raven radio infoboard by Jamie Otis    (( worked at the basis of sis service [sis.slserver.com/sis.php] used Xy text display         ))&lt;br /&gt;
// + currentPlaying by Darkie Minotaur      (( used the /7.html info to fetch current song title info, displayed as float text            ))&lt;br /&gt;
//&lt;br /&gt;
// Purpose:&lt;br /&gt;
// * Sets the parcel audio URL and displays the channel info&lt;br /&gt;
// * Uses Xytext to display the info.&lt;br /&gt;
// * Fetches song title info from the shoutcast url&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.1 release&lt;br /&gt;
// * On/Off option&lt;br /&gt;
// * Allows multiple menus (if options per menu &amp;gt; 12) using a prev/next button&lt;br /&gt;
// * Checks if your url is well-formatted&lt;br /&gt;
// * Will delete genres for which no stations exist&lt;br /&gt;
// * Will skip stations that have same url and same genre (you can however have an identical station url under different genres).&lt;br /&gt;
// * New notecard format&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.2 release&lt;br /&gt;
// * Configurable button text&lt;br /&gt;
// * Gets parcel URL and automatically sets the genre/station and on/off status accordingly (&amp;lt;-- doesn&#039;t work)&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Update -- 0.3 release&lt;br /&gt;
// * Fixed bug (only first station in genre displayed in menu)&lt;br /&gt;
// * Auto reset script when config card updated&lt;br /&gt;
// Notes:&lt;br /&gt;
// * Expects url to be in the format: &amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;, where &amp;lt;ip&amp;gt; has the format: xxx.xxx.xxx.xxx  (0 &amp;lt;= xxx &amp;lt;= 255) &lt;br /&gt;
// * Deletes entries in category (genre) for which no stations are configured with notice.&lt;br /&gt;
// * Skips stations which have identical url AND same category (genre).&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Upcoming release -- 0.4&lt;br /&gt;
// * Will add functions for remote controller(s) and remote display(s) using llRegionSay to communicate over a channel.&lt;br /&gt;
// * Should relax on the constraints about the input format of URL&#039;s (currently requires that URL has format: xxx.xxx.xxx.xxx/yyyy).&lt;br /&gt;
// * Fix button placement. Control buttons should be on the first line.&lt;br /&gt;
// * Implement script reset on change of owner.&lt;br /&gt;
// * Permit station to be put under multiple genres, using a comma-seperated list of genres in the section [STATION]&lt;br /&gt;
//   (currently this is only possible by duplicating the entire line and change the genre.)&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Future plans:&lt;br /&gt;
// * Individual user preferences that can be stored on seperate note cards. A user has access to his own list of genres and stations and the system available genres/stations.&lt;br /&gt;
// * Feature for accessing online playlists (M3U, PLS, other formats) to play a list of songs provided by that playlist.&lt;br /&gt;
// * User provided url.&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// BUGS &amp;amp; FEATURE REQUESTS&lt;br /&gt;
//&lt;br /&gt;
// Please inform the author, Logic Scripts (flennan.roffo) about any bugs or annoyances.&lt;br /&gt;
// Feature requests can also be submitted to the author.&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// LICENCE INFO&lt;br /&gt;
//&lt;br /&gt;
// This program is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string info_notecard=&amp;quot;Radio Control info&amp;quot;;              ///////    EDITABLE  \\\\\\&lt;br /&gt;
string config_notecard=&amp;quot;Radio Control config&amp;quot;;          ///////    EDITABLE  \\\\\\&lt;br /&gt;
string comment_char=&amp;quot;#&amp;quot;;                                ///////    EDITABLE  \\\\\\&lt;br /&gt;
list sep_char_list= [&amp;quot;|&amp;quot;];                              ///////    EDITABLE  \\\\\\&lt;br /&gt;
float update_time=5.0;                                  ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string no_title_info=&amp;quot;(no title info available)&amp;quot;;       ///////    EDITABLE  \\\\\\&lt;br /&gt;
&lt;br /&gt;
// not used currently - for showing info on current song title elsewhere in the region&lt;br /&gt;
integer broadcast_channel=-1234;                        ///////    EDITABLE  \\\\\\ &lt;br /&gt;
&lt;br /&gt;
// Buttons&lt;br /&gt;
&lt;br /&gt;
string button_MAIN = &amp;quot;MAIN&amp;quot;;                            ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string button_HELP = &amp;quot;HELP&amp;quot;;                            ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string button_NEXT = &amp;quot;&amp;gt;&amp;gt;&amp;quot;;                              ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string button_PREV = &amp;quot;&amp;lt;&amp;lt;&amp;quot;;                              ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string button_ON   = &amp;quot;ON&amp;quot;;                              ///////    EDITABLE  \\\\\\  &lt;br /&gt;
string button_OFF  = &amp;quot;OFF&amp;quot;;                             ///////    EDITABLE  \\\\\\ &lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// Don&#039;t touch the variables below &lt;br /&gt;
/////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
// List of categories (=genres)&lt;br /&gt;
&lt;br /&gt;
list category_list=[];&lt;br /&gt;
&lt;br /&gt;
// List of stations. KEEP THESE LISTS IN SYNCH!&lt;br /&gt;
&lt;br /&gt;
list station_category=[];&lt;br /&gt;
list station_name=[];&lt;br /&gt;
list station_desc=[];&lt;br /&gt;
list station_url=[];&lt;br /&gt;
&lt;br /&gt;
// Last song title played&lt;br /&gt;
string last_title_info=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
integer radio_status=0;    // 0 - OFF   1 - ON&lt;br /&gt;
string parcel_url=&amp;quot;&amp;quot;;&lt;br /&gt;
integer lineno=0;&lt;br /&gt;
key reqid=NULL_KEY;&lt;br /&gt;
key httpreq_id=NULL_KEY;&lt;br /&gt;
integer config_error=FALSE;&lt;br /&gt;
integer flag;&lt;br /&gt;
integer section=0;&lt;br /&gt;
&lt;br /&gt;
// Access values. Note that users who are banned can not access the device even when access is public&lt;br /&gt;
integer owner_access=TRUE;&lt;br /&gt;
integer group_access=FALSE;&lt;br /&gt;
integer public_access=TRUE;&lt;br /&gt;
list banned_keys=[];&lt;br /&gt;
&lt;br /&gt;
// Channels for menu and user input&lt;br /&gt;
integer menu_channel;&lt;br /&gt;
integer listen_handle;&lt;br /&gt;
&lt;br /&gt;
// Menu&lt;br /&gt;
integer menu_type=0;         // 0 - Main menu (genres)   1 - Station menu (stations)&lt;br /&gt;
integer menu_num=0;          // When more menu options need to be selectable then can be displayed on a menu (12), this is the menu number - menu number 0 is the first menu.&lt;br /&gt;
&lt;br /&gt;
// Genres and stations&lt;br /&gt;
&lt;br /&gt;
integer category_index=0;    // Current index in category_list  (genre)&lt;br /&gt;
integer station_index=0;     // Current index in station_*      (station)&lt;br /&gt;
&lt;br /&gt;
integer num_categories=0;&lt;br /&gt;
integer num_stations=0;&lt;br /&gt;
&lt;br /&gt;
// Make request for title info using HTTP request&lt;br /&gt;
retrieve_titelinfo()&lt;br /&gt;
{&lt;br /&gt;
    string url=llList2String(station_url,station_index);&lt;br /&gt;
    httpreq_id=llHTTPRequest(url + &amp;quot;/7.html  HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n&amp;quot;,[],&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Display a line on an Xytext device linked in&lt;br /&gt;
display_line(string line, string message)&lt;br /&gt;
{&lt;br /&gt;
    // Setup XYtext Variables&lt;br /&gt;
    integer DISPLAY_STRING      = 204000; &lt;br /&gt;
//    integer DISPLAY_EXTENDED    = 204001;     (not used)&lt;br /&gt;
//    integer REMAP_INDICES       = 204002;     (not used) &lt;br /&gt;
//    integer RESET_INDICES       = 204003;     (not used)&lt;br /&gt;
//    integer SET_CELL_INFO       = 204004;     (not used)&lt;br /&gt;
//    integer SET_FONT_TEXTURE    = 204005;     (not used)&lt;br /&gt;
//    integer SET_THICKNESS       = 204006;     (not used)&lt;br /&gt;
//    integer SET_COLOR           = 204007;     (not used)&lt;br /&gt;
&lt;br /&gt;
    llMessageLinked(LINK_SET,DISPLAY_STRING,message,line);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Clear the Xytext display&lt;br /&gt;
clear_display() &lt;br /&gt;
{&lt;br /&gt;
    // Clears the display&lt;br /&gt;
    display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio Station ID&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;2&amp;quot;,&amp;quot;Music Genre....&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;3&amp;quot;,&amp;quot;Now Playing....&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Make a menu / dialog&lt;br /&gt;
make_menu(key id)&lt;br /&gt;
{&lt;br /&gt;
     menu_channel=random_channel();&lt;br /&gt;
&lt;br /&gt;
    if (radio_status == 0)&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        llDialog(id,&amp;quot;Menu: Status\n\nRadio is OFF&amp;quot;, [ &amp;quot;ON&amp;quot;, &amp;quot;HELP&amp;quot; ],menu_channel);&lt;br /&gt;
    }&lt;br /&gt;
    else &lt;br /&gt;
    {&lt;br /&gt;
        if (menu_type ==0)&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Genres&amp;quot;, category_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Stations\nGenre: &amp;quot; + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (listen_handle != 0)    llListenRemove(listen_handle);&lt;br /&gt;
    listen_handle=llListen(menu_channel,&amp;quot;&amp;quot;,id,&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Make the menu option list for menu: catagories (genres)&lt;br /&gt;
list category_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
&lt;br /&gt;
    if (len &amp;gt; 9)   // If more then 9 items (12 minus the 3 buttons for MAIN/HELP and PREV, NEXT)&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;   // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc. &lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt; last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
&lt;br /&gt;
             while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_HELP;&lt;br /&gt;
             else&lt;br /&gt;
                 menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_OFF;&lt;br /&gt;
             else&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num != last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;       &lt;br /&gt;
        }            &lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
        menu+=(list)button_OFF;&lt;br /&gt;
        menu+=(list)button_HELP;&lt;br /&gt;
    }        &lt;br /&gt;
    &lt;br /&gt;
    return menu;    // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns the number of stations in a certain category&lt;br /&gt;
integer stations_in_category(integer cat)&lt;br /&gt;
{&lt;br /&gt;
    integer count=0;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
    string category=llList2String(category_list,cat);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (category == llList2String(category_list,i))&lt;br /&gt;
            count++;&lt;br /&gt;
&lt;br /&gt;
    return count;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Not used currently -- to fix button placement&lt;br /&gt;
list order_buttons(list buttons)&lt;br /&gt;
{&lt;br /&gt;
    integer offset;&lt;br /&gt;
    list fixt;&lt;br /&gt;
    integer flag=0;&lt;br /&gt;
&lt;br /&gt;
    while((offset = llGetListLength(buttons)))&lt;br /&gt;
    {&lt;br /&gt;
        if (offset &amp;gt; 3)&lt;br /&gt;
            flag=1;&lt;br /&gt;
        else&lt;br /&gt;
            flag=0;&lt;br /&gt;
&lt;br /&gt;
        fixt += llList2List(buttons, offset = -3 * flag, -1);&lt;br /&gt;
        buttons = llDeleteSubList(buttons, offset, -1);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return fixt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns a list of station names in a certain category (genre)&lt;br /&gt;
list station_list(integer category)&lt;br /&gt;
{&lt;br /&gt;
    list s=[];&lt;br /&gt;
    integer i;&lt;br /&gt;
    string cname=llList2String(category_list,category_index);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; llGetListLength(station_name); i++)&lt;br /&gt;
        if (llList2String(station_category,i) == cname)&lt;br /&gt;
            s+=(list)llList2String(station_name,i);&lt;br /&gt;
&lt;br /&gt;
    return s;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns the list of stations for the station menu, depending on the submenu number&lt;br /&gt;
list station_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
    list stations=station_list(category_index);&lt;br /&gt;
    integer len=llGetListLength(stations);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
        &lt;br /&gt;
    if (len &amp;gt; 11)       // 12 - 1 for MAIN menu&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;&lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt;= last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
             integer last=9*num+8;&lt;br /&gt;
&lt;br /&gt;
             menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;gt; 0)&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;lt; last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;                      &lt;br /&gt;
&lt;br /&gt;
            if (len &amp;gt; last)&lt;br /&gt;
                len =last;&lt;br /&gt;
                &lt;br /&gt;
            while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(stations,len);&lt;br /&gt;
        }&lt;br /&gt;
    }            &lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(stations,len);&lt;br /&gt;
    }        &lt;br /&gt;
&lt;br /&gt;
    return menu; // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns whether av with key id has access&lt;br /&gt;
integer has_access(key id)&lt;br /&gt;
{&lt;br /&gt;
    if (llListFindList(banned_keys,(list)id) != -1)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    if (owner_access &amp;amp;&amp;amp; id == llGetOwner())&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (group_access &amp;amp;&amp;amp; llSameGroup(id))&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (public_access)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Gets a random channel -- uses a wide range of big negative channel numbers seldomly used&lt;br /&gt;
integer random_channel()&lt;br /&gt;
{&lt;br /&gt;
    integer min=-2147483647;&lt;br /&gt;
    integer max=-1000;&lt;br /&gt;
&lt;br /&gt;
    return (integer) (min + llFrand(max-min));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Check for the format of the url string  -- is very selective about url format&lt;br /&gt;
// expects:   xxx.xxx.xxx.xxx:xxxx    (ip adress in number notation with port adress)&lt;br /&gt;
// Next release will relax on this constraint.&lt;br /&gt;
integer check_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    integer pos=0;&lt;br /&gt;
&lt;br /&gt;
    if (llGetSubString(url,0,6) == &amp;quot;http://&amp;quot;)&lt;br /&gt;
        pos=7;        &lt;br /&gt;
    if (llGetSubString(url,0,7) == &amp;quot;https://&amp;quot;)&lt;br /&gt;
        pos=8;&lt;br /&gt;
&lt;br /&gt;
    if (pos==0)   return FALSE;&lt;br /&gt;
&lt;br /&gt;
    string str_ip_port=llGetSubString(url,pos,-1);&lt;br /&gt;
    list list_ip_port=llParseString2List(str_ip_port,[&amp;quot;:&amp;quot;],[]);                 // split in ip-adress and port&lt;br /&gt;
    list list_ip=llParseString2List(llList2String(list_ip_port,0),[&amp;quot;.&amp;quot;],[]);    // split ip-adress elements&lt;br /&gt;
&lt;br /&gt;
    if (llGetListLength(list_ip_port) != 2 || llGetListLength(list_ip) != 4)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer test;&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;4;i++)&lt;br /&gt;
    {&lt;br /&gt;
        test=llList2Integer(list_ip,i);&lt;br /&gt;
        if (llList2String(list_ip,i) != (string)test)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        if (test &amp;lt; 0 || test &amp;gt; 255)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    test=llList2Integer(list_ip_port,1);&lt;br /&gt;
    if (llList2String(list_ip_port,1) != (string)test)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns a true value depending on the first character in input - anything else is assumed false.&lt;br /&gt;
integer true_value(string input)&lt;br /&gt;
{&lt;br /&gt;
    string value=llToLower(llGetSubString(input,0,0));&lt;br /&gt;
&lt;br /&gt;
    if (value == &amp;quot;y&amp;quot; || value == &amp;quot;t&amp;quot; || value ==&amp;quot;1&amp;quot;)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Return if more input should be processed (if not at EOF) - sets ConfigError if any config error found. Reading config card stops at the first error.&lt;br /&gt;
integer process_line(string dataline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(dataline,STRING_TRIM);&lt;br /&gt;
    integer index=llSubStringIndex(line,comment_char);&lt;br /&gt;
    &lt;br /&gt;
    if (index==0)       // line starts with comment - ignore line&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (index!=-1)&lt;br /&gt;
        line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL);   // skip everything after comment_char and trim tail&lt;br /&gt;
&lt;br /&gt;
    if (line==&amp;quot;&amp;quot;)       // Ignore blank lines&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (llToLower(line) == &amp;quot;[access]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 1;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[banned]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 2;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[genre]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 3;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[station]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 4;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llGetSubString(line,0,0) == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; llGetSubString(line,-1,-1) == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: malformed section found at line &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
        config_error=TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: no section found on line: &amp;quot; + (string) lineno);&lt;br /&gt;
        config_error = TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    list breakup=llParseString2List(line,[&amp;quot;=&amp;quot;],[]);&lt;br /&gt;
    string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);&lt;br /&gt;
    string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);&lt;br /&gt;
&lt;br /&gt;
    if (section == 1)            // access&lt;br /&gt;
    {&lt;br /&gt;
        field=llToLower(field);&lt;br /&gt;
&lt;br /&gt;
        if (field==&amp;quot;owner&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            owner_access=true_value(values);                       &lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;group&amp;quot;)&lt;br /&gt;
        {    &lt;br /&gt;
            group_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;public&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            public_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: invalid option on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 2)         // ban list&lt;br /&gt;
    {&lt;br /&gt;
        key try=(key) field;&lt;br /&gt;
&lt;br /&gt;
        if (try)&lt;br /&gt;
        {&lt;br /&gt;
            banned_keys+=(list)((key) field);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 3)           // categories&lt;br /&gt;
    {&lt;br /&gt;
        if (llListFindList(category_list,(list)field) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            category_list+=(list)field;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;genre: &#039;&amp;quot; + field + &amp;quot;&#039; already entered; double entry skipped.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 4)            // stations&lt;br /&gt;
    {&lt;br /&gt;
        list parse=llParseString2List(line,sep_char_list, []);&lt;br /&gt;
        string category=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);&lt;br /&gt;
        string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);&lt;br /&gt;
    &lt;br /&gt;
        if (!available_category(category))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: unknown genre on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (check_url(url))&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                num_stations++;&lt;br /&gt;
                station_category+=(list)category;&lt;br /&gt;
                station_name+=(list)name;&lt;br /&gt;
                station_desc+=(list)desc;&lt;br /&gt;
                station_url+=(list)url;&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llWhisper(0,&amp;quot;This station is already entered under the same genre and same url and is skipped.\nStation: &amp;quot; + name + &amp;quot;\nGenre: &#039;&amp;quot; + category + &amp;quot;&#039;\nURL: &amp;quot; + url);&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: malformed url on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
     &lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Sets the parcel URL and updates the display&lt;br /&gt;
set_parcel_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    parcel_url=url;&lt;br /&gt;
    llSetParcelMusicURL(parcel_url);&lt;br /&gt;
&lt;br /&gt;
    if (parcel_url==&amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        clear_display();&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is OFF&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;station now set to &amp;quot; + llList2String(station_desc,station_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Station: &amp;quot; + llList2String(station_desc,station_index));&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;Genre  : &amp;quot; + llList2String(category_list,category_index));&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;Now playing.....&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns if a category (genre) exists.&lt;br /&gt;
integer available_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;len;i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(category_list,i)))&lt;br /&gt;
            return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns if a category (genre) is empty (i.e. there are no stations for this catagory (genre))&lt;br /&gt;
integer empty_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(station_category,i)))&lt;br /&gt;
            return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Removes categories (genres) for which no station is known.&lt;br /&gt;
skip_empty_categories()&lt;br /&gt;
{&lt;br /&gt;
    integer i=0;&lt;br /&gt;
&lt;br /&gt;
    while (i&amp;lt;llGetListLength(category_list))&lt;br /&gt;
    {&lt;br /&gt;
        if (empty_category(llList2String(category_list,i)))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;Warning: Genre &#039;&amp;quot; + llList2String(category_list,i) + &amp;quot;&#039; contains no stations and is deleted.&amp;quot;);&lt;br /&gt;
            category_list=llDeleteSubList(category_list,i,i);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            i++;&lt;br /&gt;
    }&lt;br /&gt;
            &lt;br /&gt;
    num_categories=llGetListLength(category_list);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state default&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        flag=FALSE;&lt;br /&gt;
        lineno=0;&lt;br /&gt;
        config_error=FALSE;&lt;br /&gt;
        num_stations=0;&lt;br /&gt;
        num_categories=0;&lt;br /&gt;
        radio_status=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(config_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
           reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
           llWhisper(0, &amp;quot;Reading config notecard...&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;1&amp;quot;,&amp;quot;Reading configuration.&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;2&amp;quot;,&amp;quot;Wait....&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;No config notecard &#039;&amp;quot; +  config_notecard + &amp;quot;&#039; present.&amp;quot;);&lt;br /&gt;
            state offline;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (reqid==id)&lt;br /&gt;
        {        &lt;br /&gt;
            if (data==EOF)&lt;br /&gt;
            {&lt;br /&gt;
                skip_empty_categories();&lt;br /&gt;
                llWhisper(0,&amp;quot;Configuration ok.\n&amp;quot; + (string)num_categories + &amp;quot; genres and &amp;quot; + (string)num_stations + &amp;quot; stations.&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Configuration OK&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;2&amp;quot;,&amp;quot;Genres  : &amp;quot; + (string)num_categories);&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Stations: &amp;quot; + (string)num_stations);&lt;br /&gt;
                state menu;&lt;br /&gt;
            }&lt;br /&gt;
            else &lt;br /&gt;
            {&lt;br /&gt;
                if (process_line(data))&lt;br /&gt;
                    reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
                else if (config_error)&lt;br /&gt;
                {&lt;br /&gt;
                    llWhisper(0,&amp;quot;errors found in configuration. please correct them.&amp;quot;);&lt;br /&gt;
                    state offline;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state offline&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state offline&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;Reset on owner touch or when notecard updated.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    touch_start(integer t)&lt;br /&gt;
    {&lt;br /&gt;
        if (llDetectedKey(0)==llGetOwner())&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state menu&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state menu&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        listen_handle=0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        if (param &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
        key toucher=llDetectedKey(0);&lt;br /&gt;
&lt;br /&gt;
        if (has_access(toucher))&lt;br /&gt;
        {&lt;br /&gt;
            make_menu(toucher);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;sorry, no access.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    listen(integer chan, string name,key id,string msg)&lt;br /&gt;
    {&lt;br /&gt;
        integer index;&lt;br /&gt;
&lt;br /&gt;
        if (menu_type == 0)          // main menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_ON)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=1;&lt;br /&gt;
                set_parcel_url(parcel_url);               &lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is ON&amp;quot;);&lt;br /&gt;
                menu_num=0;&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned on.&amp;quot;);&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=0;&lt;br /&gt;
                set_parcel_url(&amp;quot;&amp;quot;);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned off.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
                {&lt;br /&gt;
                    llGiveInventory(id,info_notecard);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                    llWhisper(0,&amp;quot;sorry, help not available.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (radio_status == 1)&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(category_list, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: genre not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    category_index=index;&lt;br /&gt;
                    llWhisper(0,&amp;quot;Genre now set to &amp;quot; + llList2String(category_list,category_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
                    menu_type=1;&lt;br /&gt;
                    menu_num=0;&lt;br /&gt;
                    make_menu(id);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (menu_type == 1 &amp;amp;&amp;amp; radio_status == 1)     // station menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(station_name, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: station not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    station_index=index;&lt;br /&gt;
                    string new_url=llList2String(station_url,station_index);&lt;br /&gt;
&lt;br /&gt;
                    if (new_url != parcel_url)&lt;br /&gt;
                    {&lt;br /&gt;
                        set_parcel_url(new_url);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        retrieve_titelinfo();&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_response(key id, integer status, list meta, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == httpreq_id)&lt;br /&gt;
        {&lt;br /&gt;
            if (status == 200)&lt;br /&gt;
            {&lt;br /&gt;
                string feed = llGetSubString(body,llSubStringIndex(body, &amp;quot;&amp;lt;body&amp;gt;&amp;quot;) + llStringLength(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;), llSubStringIndex(body,&amp;quot;&amp;lt;/body&amp;gt;&amp;quot;) - 1);&lt;br /&gt;
                list feed_list = llParseString2List(feed,[&amp;quot;,&amp;quot;],[]);&lt;br /&gt;
                string current_title_info= llList2String(feed_list,6);&lt;br /&gt;
                integer length = llGetListLength(feed_list);&lt;br /&gt;
        &lt;br /&gt;
                if(llList2String(feed_list,7))&lt;br /&gt;
                {&lt;br /&gt;
                    integer a = 7;&lt;br /&gt;
                    for(; a&amp;lt;length; ++a)&lt;br /&gt;
                    {&lt;br /&gt;
                        current_title_info += &amp;quot;, &amp;quot; + llList2String(feed_list,a);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
         &lt;br /&gt;
                if (current_title_info != last_title_info)&lt;br /&gt;
                {&lt;br /&gt;
                    last_title_info = current_title_info;&lt;br /&gt;
                    display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + current_title_info);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + no_title_info);&lt;br /&gt;
            }&lt;br /&gt;
        }    &lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
// end of script&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Notecard format===&lt;br /&gt;
Example notecard&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# New format Shoutcast - radio controller config notecard&lt;br /&gt;
# The format is divided in 4 sections:&lt;br /&gt;
# 1 - Access configuration&lt;br /&gt;
# 2 - Ban list (keys)&lt;br /&gt;
# 3 - Categories  (same as genres)&lt;br /&gt;
# 4 - Station info (category, name, desc, url)&lt;br /&gt;
# The &#039;#&#039; character defines the start of a comment and can be anywhere on a line. &lt;br /&gt;
# Everything after the &#039;#&#039; incuding the &#039;#&#039; itself is ignored.&lt;br /&gt;
# Case is not important (but information on display will show as entered)&lt;br /&gt;
# Spaces before and/or after fields are trimmed.&lt;br /&gt;
# Empty lines are ignored.&lt;br /&gt;
&lt;br /&gt;
[ACCESS]&lt;br /&gt;
owner=yes       # yes, true,1      means owner has access. everything else not.&lt;br /&gt;
group=yes       #  ,,  ,,  ,,      means group has acess.    ,,        ,,   ,,&lt;br /&gt;
public=yes      #  ,,  ,,  ,,      means public has access.  ,,        ,,   ,, &lt;br /&gt;
&lt;br /&gt;
[BANNED]&lt;br /&gt;
# keys of banned residents&lt;br /&gt;
&lt;br /&gt;
[GENRE]&lt;br /&gt;
# genre name -- Use short genre names as the the length of menu buttons is short!&lt;br /&gt;
Hard Rock&lt;br /&gt;
Classic Rock&lt;br /&gt;
Oldies&lt;br /&gt;
Rap/Urban&lt;br /&gt;
Comedy&lt;br /&gt;
News&lt;br /&gt;
Dance&lt;br /&gt;
Country&lt;br /&gt;
Gothic&lt;br /&gt;
# etc.&lt;br /&gt;
[STATION]&lt;br /&gt;
# Shoutcast radio stations&lt;br /&gt;
# Use a &#039;|&#039; between each field - don&#039;t mind spaces before and after fields, they will be trimmed&lt;br /&gt;
# field1:genre, field2:station name, field3: station description, field4: station http://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt; or https://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;&lt;br /&gt;
# Note that genre must match case-insensitive a value previously entered in section [GENRE]&lt;br /&gt;
Classic Rock    | Absolute         |    Absolute Radio                  | http://205.188.215.226:8018&lt;br /&gt;
# etc.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===TODO===&lt;br /&gt;
&lt;br /&gt;
Planned for upcoming release 0.4:&lt;br /&gt;
* Add a llRegionSay to broadcast the &amp;lt;station&amp;gt;|&amp;lt;genre&amp;gt;|&amp;lt;current songtitle&amp;gt;|&amp;lt;url&amp;gt; to the region and add a script that displays that info on a remote Xytext board. (for use with a remote controller and/or remote display board anywhere in the region/parcel)&lt;br /&gt;
* llResetScript on owner change&lt;br /&gt;
* Relax on URL format&lt;br /&gt;
* Allow multiple genres per station&lt;/div&gt;</description>
			<pubDate>Thu, 10 Feb 2011 01:03:12 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)</comments>
		</item>
		<item>
			<title>Shoutcast - radio controller v0.3 (remake of similar scripts)</title>
			<link>https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133925</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133925</guid>
			<description>&lt;p&gt;Flennan Roffo: /* Shoutcast - radio controller */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}}&lt;br /&gt;
=Shoutcast - radio controller=&lt;br /&gt;
This script controls a shoutcast radio receiver and lets you select the stations that you configured on a notecard. Menu driven. Output of station description, genre and current song title using Xy text.&lt;br /&gt;
Credits for this script go to previous developers of similar scripts:&lt;br /&gt;
* &#039;&#039;&#039;Scripter Coba&#039;&#039;&#039; who wrote the &#039;&#039;LandOwnersRadio (V2.0)&#039;&#039; script. Menu driven / notecard config script to select genre and station to set parcel music url.&lt;br /&gt;
* &#039;&#039;&#039;Jamie Otis&#039;&#039;&#039; who wrote the &#039;&#039;Raven radio infoboard&#039;&#039; script. Shows what song is playing by fetching info using the sis.slserver.info/sis.php service (now offline). Display on Xytext.&lt;br /&gt;
* &#039;&#039;&#039;Darkie Minotaur&#039;&#039;&#039; who wrote the &#039;&#039;currentPlaying&#039;&#039; script. Shows what song is currently playing by fetching info from the /7.html shoutcast page.&lt;br /&gt;
&lt;br /&gt;
Although this script is based upon similar functionality as provided in these scripts, this script is not simply a merge/copy of those scripts, but a complete make-over. &lt;br /&gt;
I use my own notecard format and processing of notecard info, and own menu system.&lt;br /&gt;
&lt;br /&gt;
==Versions==&lt;br /&gt;
&lt;br /&gt;
Current version: v0.3 released 10-2-2011&lt;br /&gt;
&lt;br /&gt;
==Scripts==&lt;br /&gt;
&lt;br /&gt;
===Shoutcast - radio controller===&lt;br /&gt;
This script should be put into the shoutcast - radio controller device.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// Script:  Shoutcast - radio controller&lt;br /&gt;
// Version: 0.3 - released 10-2-2011&lt;br /&gt;
// Logic Scripts (Flennan Roffo)&lt;br /&gt;
// (c) 2010 - Flennan Roffo (Logic Scripts)&lt;br /&gt;
// &lt;br /&gt;
// This script is a remake of a couple of similar script:&lt;br /&gt;
// + LandOwnersRadio V2.0 by Scripter Coba  (( menu driven / notecard config script to select the radio station and sets parcel music url ))&lt;br /&gt;
// + Raven radio infoboard by Jamie Otis    (( worked at the basis of sis service [sis.slserver.com/sis.php] used Xy text display         ))&lt;br /&gt;
// + currentPlaying by Darkie Minotaur      (( used the /7.html info to fetch current song title info, displayed as float text            ))&lt;br /&gt;
//&lt;br /&gt;
// Purpose:&lt;br /&gt;
// * Sets the parcel audio URL and displays the channel info&lt;br /&gt;
// * Uses Xytext to display the info.&lt;br /&gt;
// * Fetches song title info from the shoutcast url&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.1 release&lt;br /&gt;
// * On/Off option&lt;br /&gt;
// * Allows multiple menus (if options per menu &amp;gt; 12) using a prev/next button&lt;br /&gt;
// * Checks if your url is well-formatted&lt;br /&gt;
// * Will delete genres for which no stations exist&lt;br /&gt;
// * Will skip stations that have same url and same genre (you can however have an identical station url under different genres).&lt;br /&gt;
// * New notecard format&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.2 release&lt;br /&gt;
// * Configurable button text&lt;br /&gt;
// * Gets parcel URL and automatically sets the genre/station and on/off status accordingly (&amp;lt;-- doesn&#039;t work)&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Update -- 0.3 release&lt;br /&gt;
// * Fixed bug (only first station in genre displayed in menu)&lt;br /&gt;
// * Auto reset script when config card updated&lt;br /&gt;
// Notes:&lt;br /&gt;
// * Expects url to be in the format: &amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;, where &amp;lt;ip&amp;gt; has the format: xxx.xxx.xxx.xxx  (0 &amp;lt;= xxx &amp;lt;= 255) &lt;br /&gt;
// * Deletes entries in category (genre) for which no stations are configured with notice.&lt;br /&gt;
// * Skips stations which have identical url AND same category (genre).&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Upcoming release -- 0.4&lt;br /&gt;
// * Will add functions for remote controller(s) and remote display(s) using llRegionSay to communicate over a channel.&lt;br /&gt;
// * Should relax on the constraints about the input format of URL&#039;s (currently requires that URL has format: xxx.xxx.xxx.xxx/yyyy).&lt;br /&gt;
// * Fix button placement. Control buttons should be on the first line.&lt;br /&gt;
// * Implement script reset on change of owner.&lt;br /&gt;
// * Permit station to be put under multiple genres, using a comma-seperated list of genres in the section [STATION]&lt;br /&gt;
//   (currently this is only possible by duplicating the entire line and change the genre.)&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Future plans:&lt;br /&gt;
// * Individual user preferences that can be stored on seperate note cards. A user has access to his own list of genres and stations and the system available genres/stations.&lt;br /&gt;
// * Feature for accessing online playlists (M3U, PLS, other formats) to play a list of songs provided by that playlist.&lt;br /&gt;
// * User provided url.&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// BUGS &amp;amp; FEATURE REQUESTS&lt;br /&gt;
//&lt;br /&gt;
// Please inform the author, Logic Scripts (flennan.roffo) about any bugs or annoyances.&lt;br /&gt;
// Feature requests can also be submitted to the author.&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// LICENCE INFO&lt;br /&gt;
//&lt;br /&gt;
// This program is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string info_notecard=&amp;quot;Radio Control info&amp;quot;;              ///////    EDITABLE  \\\\\\&lt;br /&gt;
string config_notecard=&amp;quot;Radio Control config&amp;quot;;          ///////    EDITABLE  \\\\\\&lt;br /&gt;
string comment_char=&amp;quot;#&amp;quot;;                                ///////    EDITABLE  \\\\\\&lt;br /&gt;
list sep_char_list= [&amp;quot;|&amp;quot;];                              ///////    EDITABLE  \\\\\\&lt;br /&gt;
float update_time=5.0;                                  ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string no_title_info=&amp;quot;(no title info available)&amp;quot;;       ///////    EDITABLE  \\\\\\&lt;br /&gt;
&lt;br /&gt;
// not used currently - for showing info on current song title elsewhere in the region&lt;br /&gt;
integer broadcast_channel=-1234;                        ///////    EDITABLE  \\\\\\ &lt;br /&gt;
&lt;br /&gt;
// Buttons&lt;br /&gt;
&lt;br /&gt;
string button_MAIN = &amp;quot;MAIN&amp;quot;;                            ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string button_HELP = &amp;quot;HELP&amp;quot;;                            ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string button_NEXT = &amp;quot;&amp;gt;&amp;gt;&amp;quot;;                              ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string button_PREV = &amp;quot;&amp;lt;&amp;lt;&amp;quot;;                              ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string button_ON   = &amp;quot;ON&amp;quot;;                              ///////    EDITABLE  \\\\\\  &lt;br /&gt;
string button_OFF  = &amp;quot;OFF&amp;quot;;                             ///////    EDITABLE  \\\\\\ &lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// Don&#039;t touch the variables below &lt;br /&gt;
/////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
// List of categories (=genres)&lt;br /&gt;
&lt;br /&gt;
list category_list=[];&lt;br /&gt;
&lt;br /&gt;
// List of stations. KEEP THESE LISTS IN SYNCH!&lt;br /&gt;
&lt;br /&gt;
list station_category=[];&lt;br /&gt;
list station_name=[];&lt;br /&gt;
list station_desc=[];&lt;br /&gt;
list station_url=[];&lt;br /&gt;
&lt;br /&gt;
// Last song title played&lt;br /&gt;
string last_title_info=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
integer radio_status=0;    // 0 - OFF   1 - ON&lt;br /&gt;
string parcel_url=&amp;quot;&amp;quot;;&lt;br /&gt;
integer lineno=0;&lt;br /&gt;
key reqid=NULL_KEY;&lt;br /&gt;
key httpreq_id=NULL_KEY;&lt;br /&gt;
integer config_error=FALSE;&lt;br /&gt;
integer flag;&lt;br /&gt;
integer section=0;&lt;br /&gt;
&lt;br /&gt;
// Access values. Note that users who are banned can not access the device even when access is public&lt;br /&gt;
integer owner_access=TRUE;&lt;br /&gt;
integer group_access=FALSE;&lt;br /&gt;
integer public_access=TRUE;&lt;br /&gt;
list banned_keys=[];&lt;br /&gt;
&lt;br /&gt;
// Channels for menu and user input&lt;br /&gt;
integer menu_channel;&lt;br /&gt;
integer listen_handle;&lt;br /&gt;
&lt;br /&gt;
// Menu&lt;br /&gt;
integer menu_type=0;         // 0 - Main menu (genres)   1 - Station menu (stations)&lt;br /&gt;
integer menu_num=0;          // When more menu options need to be selectable then can be displayed on a menu (12), this is the menu number - menu number 0 is the first menu.&lt;br /&gt;
&lt;br /&gt;
// Genres and stations&lt;br /&gt;
&lt;br /&gt;
integer category_index=0;    // Current index in category_list  (genre)&lt;br /&gt;
integer station_index=0;     // Current index in station_*      (station)&lt;br /&gt;
&lt;br /&gt;
integer num_categories=0;&lt;br /&gt;
integer num_stations=0;&lt;br /&gt;
&lt;br /&gt;
// Make request for title info using HTTP request&lt;br /&gt;
retrieve_titelinfo()&lt;br /&gt;
{&lt;br /&gt;
    string url=llList2String(station_url,station_index);&lt;br /&gt;
    httpreq_id=llHTTPRequest(url + &amp;quot;/7.html  HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n&amp;quot;,[],&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Display a line on an Xytext device linked in&lt;br /&gt;
display_line(string line, string message)&lt;br /&gt;
{&lt;br /&gt;
    // Setup XYtext Variables&lt;br /&gt;
    integer DISPLAY_STRING      = 204000; &lt;br /&gt;
//    integer DISPLAY_EXTENDED    = 204001;     (not used)&lt;br /&gt;
//    integer REMAP_INDICES       = 204002;     (not used) &lt;br /&gt;
//    integer RESET_INDICES       = 204003;     (not used)&lt;br /&gt;
//    integer SET_CELL_INFO       = 204004;     (not used)&lt;br /&gt;
//    integer SET_FONT_TEXTURE    = 204005;     (not used)&lt;br /&gt;
//    integer SET_THICKNESS       = 204006;     (not used)&lt;br /&gt;
//    integer SET_COLOR           = 204007;     (not used)&lt;br /&gt;
&lt;br /&gt;
    llMessageLinked(LINK_SET,DISPLAY_STRING,message,line);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Clear the Xytext display&lt;br /&gt;
clear_display() &lt;br /&gt;
{&lt;br /&gt;
    // Clears the display&lt;br /&gt;
    display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio Station ID&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;2&amp;quot;,&amp;quot;Music Genre....&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;3&amp;quot;,&amp;quot;Now Playing....&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Make a menu / dialog&lt;br /&gt;
make_menu(key id)&lt;br /&gt;
{&lt;br /&gt;
     menu_channel=random_channel();&lt;br /&gt;
&lt;br /&gt;
    if (radio_status == 0)&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        llDialog(id,&amp;quot;Menu: Status\n\nRadio is OFF&amp;quot;, [ &amp;quot;ON&amp;quot;, &amp;quot;HELP&amp;quot; ],menu_channel);&lt;br /&gt;
    }&lt;br /&gt;
    else &lt;br /&gt;
    {&lt;br /&gt;
        if (menu_type ==0)&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Genres&amp;quot;, category_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Stations\nGenre: &amp;quot; + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (listen_handle != 0)    llListenRemove(listen_handle);&lt;br /&gt;
    listen_handle=llListen(menu_channel,&amp;quot;&amp;quot;,id,&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Make the menu option list for menu: catagories (genres)&lt;br /&gt;
list category_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
&lt;br /&gt;
    if (len &amp;gt; 9)   // If more then 9 items (12 minus the 3 buttons for MAIN/HELP and PREV, NEXT)&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;   // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc. &lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt; last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
&lt;br /&gt;
             while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_HELP;&lt;br /&gt;
             else&lt;br /&gt;
                 menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_OFF;&lt;br /&gt;
             else&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num != last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;       &lt;br /&gt;
        }            &lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
        menu+=(list)button_OFF;&lt;br /&gt;
        menu+=(list)button_HELP;&lt;br /&gt;
    }        &lt;br /&gt;
    &lt;br /&gt;
    return menu;    // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns the number of stations in a certain category&lt;br /&gt;
integer stations_in_category(integer cat)&lt;br /&gt;
{&lt;br /&gt;
    integer count=0;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
    string category=llList2String(category_list,cat);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (category == llList2String(category_list,i))&lt;br /&gt;
            count++;&lt;br /&gt;
&lt;br /&gt;
    return count;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Not used currently -- to fix button placement&lt;br /&gt;
list order_buttons(list buttons)&lt;br /&gt;
{&lt;br /&gt;
    integer offset;&lt;br /&gt;
    list fixt;&lt;br /&gt;
    integer flag=0;&lt;br /&gt;
&lt;br /&gt;
    while((offset = llGetListLength(buttons)))&lt;br /&gt;
    {&lt;br /&gt;
        if (offset &amp;gt; 3)&lt;br /&gt;
            flag=1;&lt;br /&gt;
        else&lt;br /&gt;
            flag=0;&lt;br /&gt;
&lt;br /&gt;
        fixt += llList2List(buttons, offset = -3 * flag, -1);&lt;br /&gt;
        buttons = llDeleteSubList(buttons, offset, -1);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return fixt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns a list of station names in a certain category (genre)&lt;br /&gt;
list station_list(integer category)&lt;br /&gt;
{&lt;br /&gt;
    list s=[];&lt;br /&gt;
    integer i;&lt;br /&gt;
    string cname=llList2String(category_list,category_index);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; llGetListLength(station_name); i++)&lt;br /&gt;
        if (llList2String(station_category,i) == cname)&lt;br /&gt;
            s+=(list)llList2String(station_name,i);&lt;br /&gt;
&lt;br /&gt;
    return s;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns the list of stations for the station menu, depending on the submenu number&lt;br /&gt;
list station_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
    list stations=station_list(category_index);&lt;br /&gt;
    integer len=llGetListLength(stations);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
        &lt;br /&gt;
    if (len &amp;gt; 11)       // 12 - 1 for MAIN menu&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;&lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt;= last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
             integer last=9*num+8;&lt;br /&gt;
&lt;br /&gt;
             menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;gt; 0)&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;lt; last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;                      &lt;br /&gt;
&lt;br /&gt;
            if (len &amp;gt; last)&lt;br /&gt;
                len =last;&lt;br /&gt;
                &lt;br /&gt;
            while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(stations,len);&lt;br /&gt;
        }&lt;br /&gt;
    }            &lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(stations,len);&lt;br /&gt;
    }        &lt;br /&gt;
&lt;br /&gt;
    return menu; // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns whether av with key id has access&lt;br /&gt;
integer has_access(key id)&lt;br /&gt;
{&lt;br /&gt;
    if (llListFindList(banned_keys,(list)id) != -1)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    if (owner_access &amp;amp;&amp;amp; id == llGetOwner())&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (group_access &amp;amp;&amp;amp; llSameGroup(id))&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (public_access)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Gets a random channel -- uses a wide range of big negative channel numbers seldomly used&lt;br /&gt;
integer random_channel()&lt;br /&gt;
{&lt;br /&gt;
    integer min=-2147483647;&lt;br /&gt;
    integer max=-1000;&lt;br /&gt;
&lt;br /&gt;
    return (integer) (min + llFrand(max-min));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Check for the format of the url string  -- is very selective about url format&lt;br /&gt;
// expects:   xxx.xxx.xxx.xxx:xxxx    (ip adress in number notation with port adress)&lt;br /&gt;
// Next release will relax on this constraint.&lt;br /&gt;
integer check_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    integer pos=0;&lt;br /&gt;
&lt;br /&gt;
    if (llGetSubString(url,0,6) == &amp;quot;http://&amp;quot;)&lt;br /&gt;
        pos=7;        &lt;br /&gt;
    if (llGetSubString(url,0,7) == &amp;quot;https://&amp;quot;)&lt;br /&gt;
        pos=8;&lt;br /&gt;
&lt;br /&gt;
    if (pos==0)   return FALSE;&lt;br /&gt;
&lt;br /&gt;
    string str_ip_port=llGetSubString(url,pos,-1);&lt;br /&gt;
    list list_ip_port=llParseString2List(str_ip_port,[&amp;quot;:&amp;quot;],[]);                 // split in ip-adress and port&lt;br /&gt;
    list list_ip=llParseString2List(llList2String(list_ip_port,0),[&amp;quot;.&amp;quot;],[]);    // split ip-adress elements&lt;br /&gt;
&lt;br /&gt;
    if (llGetListLength(list_ip_port) != 2 || llGetListLength(list_ip) != 4)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer test;&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;4;i++)&lt;br /&gt;
    {&lt;br /&gt;
        test=llList2Integer(list_ip,i);&lt;br /&gt;
        if (llList2String(list_ip,i) != (string)test)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        if (test &amp;lt; 0 || test &amp;gt; 255)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    test=llList2Integer(list_ip_port,1);&lt;br /&gt;
    if (llList2String(list_ip_port,1) != (string)test)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns a true value depending on the first character in input - anything else is assumed false.&lt;br /&gt;
integer true_value(string input)&lt;br /&gt;
{&lt;br /&gt;
    string value=llToLower(llGetSubString(input,0,0));&lt;br /&gt;
&lt;br /&gt;
    if (value == &amp;quot;y&amp;quot; || value == &amp;quot;t&amp;quot; || value ==&amp;quot;1&amp;quot;)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Return if more input should be processed (if not at EOF) - sets ConfigError if any config error found. Reading config card stops at the first error.&lt;br /&gt;
integer process_line(string dataline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(dataline,STRING_TRIM);&lt;br /&gt;
    integer index=llSubStringIndex(line,comment_char);&lt;br /&gt;
    &lt;br /&gt;
    if (index==0)       // line starts with comment - ignore line&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (index!=-1)&lt;br /&gt;
        line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL);   // skip everything after comment_char and trim tail&lt;br /&gt;
&lt;br /&gt;
    if (line==&amp;quot;&amp;quot;)       // Ignore blank lines&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (llToLower(line) == &amp;quot;[access]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 1;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[banned]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 2;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[genre]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 3;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[station]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 4;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llGetSubString(line,0,0) == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; llGetSubString(line,-1,-1) == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: malformed section found at line &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
        config_error=TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: no section found on line: &amp;quot; + (string) lineno);&lt;br /&gt;
        config_error = TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    list breakup=llParseString2List(line,[&amp;quot;=&amp;quot;],[]);&lt;br /&gt;
    string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);&lt;br /&gt;
    string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);&lt;br /&gt;
&lt;br /&gt;
    if (section == 1)            // access&lt;br /&gt;
    {&lt;br /&gt;
        field=llToLower(field);&lt;br /&gt;
&lt;br /&gt;
        if (field==&amp;quot;owner&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            owner_access=true_value(values);                       &lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;group&amp;quot;)&lt;br /&gt;
        {    &lt;br /&gt;
            group_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;public&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            public_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: invalid option on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 2)         // ban list&lt;br /&gt;
    {&lt;br /&gt;
        key try=(key) field;&lt;br /&gt;
&lt;br /&gt;
        if (try)&lt;br /&gt;
        {&lt;br /&gt;
            banned_keys+=(list)((key) field);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 3)           // categories&lt;br /&gt;
    {&lt;br /&gt;
        if (llListFindList(category_list,(list)field) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            category_list+=(list)field;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;genre: &#039;&amp;quot; + field + &amp;quot;&#039; already entered; double entry skipped.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 4)            // stations&lt;br /&gt;
    {&lt;br /&gt;
        list parse=llParseString2List(line,sep_char_list, []);&lt;br /&gt;
        string category=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);&lt;br /&gt;
        string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);&lt;br /&gt;
    &lt;br /&gt;
        if (!available_category(category))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: unknown genre on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (check_url(url))&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                num_stations++;&lt;br /&gt;
                station_category+=(list)category;&lt;br /&gt;
                station_name+=(list)name;&lt;br /&gt;
                station_desc+=(list)desc;&lt;br /&gt;
                station_url+=(list)url;&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llWhisper(0,&amp;quot;This station is already entered under the same genre and same url and is skipped.\nStation: &amp;quot; + name + &amp;quot;\nGenre: &#039;&amp;quot; + category + &amp;quot;&#039;\nURL: &amp;quot; + url);&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: malformed url on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
     &lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Sets the parcel URL and updates the display&lt;br /&gt;
set_parcel_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    parcel_url=url;&lt;br /&gt;
    llSetParcelMusicURL(parcel_url);&lt;br /&gt;
&lt;br /&gt;
    if (parcel_url==&amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        clear_display();&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is OFF&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;station now set to &amp;quot; + llList2String(station_desc,station_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Station: &amp;quot; + llList2String(station_desc,station_index));&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;Genre  : &amp;quot; + llList2String(category_list,category_index));&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;Now playing.....&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns if a category (genre) exists.&lt;br /&gt;
integer available_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;len;i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(category_list,i)))&lt;br /&gt;
            return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns if a category (genre) is empty (i.e. there are no stations for this catagory (genre))&lt;br /&gt;
integer empty_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(station_category,i)))&lt;br /&gt;
            return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Removes categories (genres) for which no station is known.&lt;br /&gt;
skip_empty_categories()&lt;br /&gt;
{&lt;br /&gt;
    integer i=0;&lt;br /&gt;
&lt;br /&gt;
    while (i&amp;lt;llGetListLength(category_list))&lt;br /&gt;
    {&lt;br /&gt;
        if (empty_category(llList2String(category_list,i)))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;Warning: Genre &#039;&amp;quot; + llList2String(category_list,i) + &amp;quot;&#039; contains no stations and is deleted.&amp;quot;);&lt;br /&gt;
            category_list=llDeleteSubList(category_list,i,i);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            i++;&lt;br /&gt;
    }&lt;br /&gt;
            &lt;br /&gt;
    num_categories=llGetListLength(category_list);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state default&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        flag=FALSE;&lt;br /&gt;
        lineno=0;&lt;br /&gt;
        config_error=FALSE;&lt;br /&gt;
        num_stations=0;&lt;br /&gt;
        num_categories=0;&lt;br /&gt;
        radio_status=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(config_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
           reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
           llWhisper(0, &amp;quot;Reading config notecard...&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;1&amp;quot;,&amp;quot;Reading configuration.&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;2&amp;quot;,&amp;quot;Wait....&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;No config notecard &#039;&amp;quot; +  config_notecard + &amp;quot;&#039; present.&amp;quot;);&lt;br /&gt;
            state offline;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (reqid==id)&lt;br /&gt;
        {        &lt;br /&gt;
            if (data==EOF)&lt;br /&gt;
            {&lt;br /&gt;
                skip_empty_categories();&lt;br /&gt;
                llWhisper(0,&amp;quot;Configuration ok.\n&amp;quot; + (string)num_categories + &amp;quot; genres and &amp;quot; + (string)num_stations + &amp;quot; stations.&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Configuration OK&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;2&amp;quot;,&amp;quot;Genres  : &amp;quot; + (string)num_categories);&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Stations: &amp;quot; + (string)num_stations);&lt;br /&gt;
                state menu;&lt;br /&gt;
            }&lt;br /&gt;
            else &lt;br /&gt;
            {&lt;br /&gt;
                if (process_line(data))&lt;br /&gt;
                    reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
                else if (config_error)&lt;br /&gt;
                {&lt;br /&gt;
                    llWhisper(0,&amp;quot;errors found in configuration. please correct them.&amp;quot;);&lt;br /&gt;
                    state offline;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state offline&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state offline&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;Reset on owner touch or when notecard updated.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    touch_start(integer t)&lt;br /&gt;
    {&lt;br /&gt;
        if (llDetectedKey(0)==llGetOwner())&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY &amp;amp;&amp;amp; flag)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state menu&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state menu&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        listen_handle=0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        if (param &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
        key toucher=llDetectedKey(0);&lt;br /&gt;
&lt;br /&gt;
        if (has_access(toucher))&lt;br /&gt;
        {&lt;br /&gt;
            make_menu(toucher);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;sorry, no access.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    listen(integer chan, string name,key id,string msg)&lt;br /&gt;
    {&lt;br /&gt;
        integer index;&lt;br /&gt;
&lt;br /&gt;
        if (menu_type == 0)          // main menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_ON)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=1;&lt;br /&gt;
                set_parcel_url(parcel_url);               &lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is ON&amp;quot;);&lt;br /&gt;
                menu_num=0;&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned on.&amp;quot;);&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=0;&lt;br /&gt;
                set_parcel_url(&amp;quot;&amp;quot;);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned off.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
                {&lt;br /&gt;
                    llGiveInventory(id,info_notecard);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                    llWhisper(0,&amp;quot;sorry, help not available.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (radio_status == 1)&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(category_list, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: genre not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    category_index=index;&lt;br /&gt;
                    llWhisper(0,&amp;quot;Genre now set to &amp;quot; + llList2String(category_list,category_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
                    menu_type=1;&lt;br /&gt;
                    menu_num=0;&lt;br /&gt;
                    make_menu(id);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (menu_type == 1 &amp;amp;&amp;amp; radio_status == 1)     // station menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(station_name, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: station not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    station_index=index;&lt;br /&gt;
                    string new_url=llList2String(station_url,station_index);&lt;br /&gt;
&lt;br /&gt;
                    if (new_url != parcel_url)&lt;br /&gt;
                    {&lt;br /&gt;
                        set_parcel_url(new_url);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        retrieve_titelinfo();&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_response(key id, integer status, list meta, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == httpreq_id)&lt;br /&gt;
        {&lt;br /&gt;
            if (status == 200)&lt;br /&gt;
            {&lt;br /&gt;
                string feed = llGetSubString(body,llSubStringIndex(body, &amp;quot;&amp;lt;body&amp;gt;&amp;quot;) + llStringLength(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;), llSubStringIndex(body,&amp;quot;&amp;lt;/body&amp;gt;&amp;quot;) - 1);&lt;br /&gt;
                list feed_list = llParseString2List(feed,[&amp;quot;,&amp;quot;],[]);&lt;br /&gt;
                string current_title_info= llList2String(feed_list,6);&lt;br /&gt;
                integer length = llGetListLength(feed_list);&lt;br /&gt;
        &lt;br /&gt;
                if(llList2String(feed_list,7))&lt;br /&gt;
                {&lt;br /&gt;
                    integer a = 7;&lt;br /&gt;
                    for(; a&amp;lt;length; ++a)&lt;br /&gt;
                    {&lt;br /&gt;
                        current_title_info += &amp;quot;, &amp;quot; + llList2String(feed_list,a);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
         &lt;br /&gt;
                if (current_title_info != last_title_info)&lt;br /&gt;
                {&lt;br /&gt;
                    last_title_info = current_title_info;&lt;br /&gt;
                    display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + current_title_info);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + no_title_info);&lt;br /&gt;
            }&lt;br /&gt;
        }    &lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY &amp;amp;&amp;amp; flag)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
// end of script&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Notecard format===&lt;br /&gt;
Example notecard&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# New format Shoutcast - radio controller config notecard&lt;br /&gt;
# The format is divided in 4 sections:&lt;br /&gt;
# 1 - Access configuration&lt;br /&gt;
# 2 - Ban list (keys)&lt;br /&gt;
# 3 - Categories  (same as genres)&lt;br /&gt;
# 4 - Station info (category, name, desc, url)&lt;br /&gt;
# The &#039;#&#039; character defines the start of a comment and can be anywhere on a line. &lt;br /&gt;
# Everything after the &#039;#&#039; incuding the &#039;#&#039; itself is ignored.&lt;br /&gt;
# Case is not important (but information on display will show as entered)&lt;br /&gt;
# Spaces before and/or after fields are trimmed.&lt;br /&gt;
# Empty lines are ignored.&lt;br /&gt;
&lt;br /&gt;
[ACCESS]&lt;br /&gt;
owner=yes       # yes, true,1      means owner has access. everything else not.&lt;br /&gt;
group=yes       #  ,,  ,,  ,,      means group has acess.    ,,        ,,   ,,&lt;br /&gt;
public=yes      #  ,,  ,,  ,,      means public has access.  ,,        ,,   ,, &lt;br /&gt;
&lt;br /&gt;
[BANNED]&lt;br /&gt;
# keys of banned residents&lt;br /&gt;
&lt;br /&gt;
[GENRE]&lt;br /&gt;
# genre name -- Use short genre names as the the length of menu buttons is short!&lt;br /&gt;
Hard Rock&lt;br /&gt;
Classic Rock&lt;br /&gt;
Oldies&lt;br /&gt;
Rap/Urban&lt;br /&gt;
Comedy&lt;br /&gt;
News&lt;br /&gt;
Dance&lt;br /&gt;
Country&lt;br /&gt;
Gothic&lt;br /&gt;
# etc.&lt;br /&gt;
[STATION]&lt;br /&gt;
# Shoutcast radio stations&lt;br /&gt;
# Use a &#039;|&#039; between each field - don&#039;t mind spaces before and after fields, they will be trimmed&lt;br /&gt;
# field1:genre, field2:station name, field3: station description, field4: station http://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt; or https://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;&lt;br /&gt;
# Note that genre must match case-insensitive a value previously entered in section [GENRE]&lt;br /&gt;
Classic Rock    | Absolute         |    Absolute Radio                  | http://205.188.215.226:8018&lt;br /&gt;
# etc.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===TODO===&lt;br /&gt;
&lt;br /&gt;
Planned for upcoming release 0.4:&lt;br /&gt;
* Add a llRegionSay to broadcast the &amp;lt;station&amp;gt;|&amp;lt;genre&amp;gt;|&amp;lt;current songtitle&amp;gt;|&amp;lt;url&amp;gt; to the region and add a script that displays that info on a remote Xytext board. (for use with a remote controller and/or remote display board anywhere in the region/parcel)&lt;br /&gt;
* llResetScript on owner change&lt;br /&gt;
* Relax on URL format&lt;br /&gt;
* Allow multiple genres per station&lt;/div&gt;</description>
			<pubDate>Thu, 10 Feb 2011 00:59:44 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)</comments>
		</item>
		<item>
			<title>Shoutcast - radio controller v0.3 (remake of similar scripts)</title>
			<link>https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133924</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133924</guid>
			<description>&lt;p&gt;Flennan Roffo: /* Shoutcast - radio controller */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}}&lt;br /&gt;
=Shoutcast - radio controller=&lt;br /&gt;
This script controls a shoutcast radio receiver and lets you select the stations that you configured on a notecard. Menu driven. Output of station description, genre and current song title using Xy text.&lt;br /&gt;
Credits for this script go to previous developers of similar scripts:&lt;br /&gt;
* &#039;&#039;Scripter Coba&#039;&#039; who wrote the LandOwnersRadio (V2.0) script. Menu driven / notecard config script to select genre and station to set parcel music url.&lt;br /&gt;
* &#039;&#039;Jamie Otis&#039;&#039; who wrote the Raven radio infoboard script. Shows what song is playing by fetching info using the sis.slserver.info/sis.php service (now offline). Display on Xytext.&lt;br /&gt;
* &#039;&#039;Darkie Minotaur&#039;&#039; who wrote the currentPlaying script. Shows what song is currently playing by fetching info from the /7.html shoutcast page.&lt;br /&gt;
&lt;br /&gt;
Although this script is based upon similar functionality as provided in these scripts, this script is not simply a merge/copy of those scripts, but a complete make-over. &lt;br /&gt;
I use my own notecard format and processing of notecard info, and own menu system.&lt;br /&gt;
&lt;br /&gt;
==Versions==&lt;br /&gt;
&lt;br /&gt;
Current version: v0.3 released 10-2-2011&lt;br /&gt;
&lt;br /&gt;
==Scripts==&lt;br /&gt;
&lt;br /&gt;
===Shoutcast - radio controller===&lt;br /&gt;
This script should be put into the shoutcast - radio controller device.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// Script:  Shoutcast - radio controller&lt;br /&gt;
// Version: 0.3 - released 10-2-2011&lt;br /&gt;
// Logic Scripts (Flennan Roffo)&lt;br /&gt;
// (c) 2010 - Flennan Roffo (Logic Scripts)&lt;br /&gt;
// &lt;br /&gt;
// This script is a remake of a couple of similar script:&lt;br /&gt;
// + LandOwnersRadio V2.0 by Scripter Coba  (( menu driven / notecard config script to select the radio station and sets parcel music url ))&lt;br /&gt;
// + Raven radio infoboard by Jamie Otis    (( worked at the basis of sis service [sis.slserver.com/sis.php] used Xy text display         ))&lt;br /&gt;
// + currentPlaying by Darkie Minotaur      (( used the /7.html info to fetch current song title info, displayed as float text            ))&lt;br /&gt;
//&lt;br /&gt;
// Purpose:&lt;br /&gt;
// * Sets the parcel audio URL and displays the channel info&lt;br /&gt;
// * Uses Xytext to display the info.&lt;br /&gt;
// * Fetches song title info from the shoutcast url&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.1 release&lt;br /&gt;
// * On/Off option&lt;br /&gt;
// * Allows multiple menus (if options per menu &amp;gt; 12) using a prev/next button&lt;br /&gt;
// * Checks if your url is well-formatted&lt;br /&gt;
// * Will delete genres for which no stations exist&lt;br /&gt;
// * Will skip stations that have same url and same genre (you can however have an identical station url under different genres).&lt;br /&gt;
// * New notecard format&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.2 release&lt;br /&gt;
// * Configurable button text&lt;br /&gt;
// * Gets parcel URL and automatically sets the genre/station and on/off status accordingly (&amp;lt;-- doesn&#039;t work)&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Update -- 0.3 release&lt;br /&gt;
// * Fixed bug (only first station in genre displayed in menu)&lt;br /&gt;
// * Auto reset script when config card updated&lt;br /&gt;
// Notes:&lt;br /&gt;
// * Expects url to be in the format: &amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;, where &amp;lt;ip&amp;gt; has the format: xxx.xxx.xxx.xxx  (0 &amp;lt;= xxx &amp;lt;= 255) &lt;br /&gt;
// * Deletes entries in category (genre) for which no stations are configured with notice.&lt;br /&gt;
// * Skips stations which have identical url AND same category (genre).&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Upcoming release -- 0.4&lt;br /&gt;
// * Will add functions for remote controller(s) and remote display(s) using llRegionSay to communicate over a channel.&lt;br /&gt;
// * Should relax on the constraints about the input format of URL&#039;s (currently requires that URL has format: xxx.xxx.xxx.xxx/yyyy).&lt;br /&gt;
// * Fix button placement. Control buttons should be on the first line.&lt;br /&gt;
// * Implement script reset on change of owner.&lt;br /&gt;
// * Permit station to be put under multiple genres, using a comma-seperated list of genres in the section [STATION]&lt;br /&gt;
//   (currently this is only possible by duplicating the entire line and change the genre.)&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Future plans:&lt;br /&gt;
// * Individual user preferences that can be stored on seperate note cards. A user has access to his own list of genres and stations and the system available genres/stations.&lt;br /&gt;
// * Feature for accessing online playlists (M3U, PLS, other formats) to play a list of songs provided by that playlist.&lt;br /&gt;
// * User provided url.&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// BUGS &amp;amp; FEATURE REQUESTS&lt;br /&gt;
//&lt;br /&gt;
// Please inform the author, Logic Scripts (flennan.roffo) about any bugs or annoyances.&lt;br /&gt;
// Feature requests can also be submitted to the author.&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// LICENCE INFO&lt;br /&gt;
//&lt;br /&gt;
// This program is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string info_notecard=&amp;quot;Radio Control info&amp;quot;;              ///////    EDITABLE  \\\\\\&lt;br /&gt;
string config_notecard=&amp;quot;Radio Control config&amp;quot;;          ///////    EDITABLE  \\\\\\&lt;br /&gt;
string comment_char=&amp;quot;#&amp;quot;;                                ///////    EDITABLE  \\\\\\&lt;br /&gt;
list sep_char_list= [&amp;quot;|&amp;quot;];                              ///////    EDITABLE  \\\\\\&lt;br /&gt;
float update_time=5.0;                                  ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string no_title_info=&amp;quot;(no title info available)&amp;quot;;       ///////    EDITABLE  \\\\\\&lt;br /&gt;
&lt;br /&gt;
// not used currently - for showing info on current song title elsewhere in the region&lt;br /&gt;
integer broadcast_channel=-1234;                        ///////    EDITABLE  \\\\\\ &lt;br /&gt;
&lt;br /&gt;
// Buttons&lt;br /&gt;
&lt;br /&gt;
string button_MAIN = &amp;quot;MAIN&amp;quot;;                            ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string button_HELP = &amp;quot;HELP&amp;quot;;                            ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string button_NEXT = &amp;quot;&amp;gt;&amp;gt;&amp;quot;;                              ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string button_PREV = &amp;quot;&amp;lt;&amp;lt;&amp;quot;;                              ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string button_ON   = &amp;quot;ON&amp;quot;;                              ///////    EDITABLE  \\\\\\  &lt;br /&gt;
string button_OFF  = &amp;quot;OFF&amp;quot;;                             ///////    EDITABLE  \\\\\\ &lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// Don&#039;t touch the variables below &lt;br /&gt;
/////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
// List of categories (=genres)&lt;br /&gt;
&lt;br /&gt;
list category_list=[];&lt;br /&gt;
&lt;br /&gt;
// List of stations. KEEP THESE LISTS IN SYNCH!&lt;br /&gt;
&lt;br /&gt;
list station_category=[];&lt;br /&gt;
list station_name=[];&lt;br /&gt;
list station_desc=[];&lt;br /&gt;
list station_url=[];&lt;br /&gt;
&lt;br /&gt;
// Last song title played&lt;br /&gt;
string last_title_info=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
integer radio_status=0;    // 0 - OFF   1 - ON&lt;br /&gt;
string parcel_url=&amp;quot;&amp;quot;;&lt;br /&gt;
integer lineno=0;&lt;br /&gt;
key reqid=NULL_KEY;&lt;br /&gt;
key httpreq_id=NULL_KEY;&lt;br /&gt;
integer config_error=FALSE;&lt;br /&gt;
integer flag;&lt;br /&gt;
integer section=0;&lt;br /&gt;
&lt;br /&gt;
// Access values. Note that users who are banned can not access the device even when access is public&lt;br /&gt;
integer owner_access=TRUE;&lt;br /&gt;
integer group_access=FALSE;&lt;br /&gt;
integer public_access=TRUE;&lt;br /&gt;
list banned_keys=[];&lt;br /&gt;
&lt;br /&gt;
// Channels for menu and user input&lt;br /&gt;
integer menu_channel;&lt;br /&gt;
integer listen_handle;&lt;br /&gt;
&lt;br /&gt;
// Menu&lt;br /&gt;
integer menu_type=0;         // 0 - Main menu (genres)   1 - Station menu (stations)&lt;br /&gt;
integer menu_num=0;          // When more menu options need to be selectable then can be displayed on a menu (12), this is the menu number - menu number 0 is the first menu.&lt;br /&gt;
&lt;br /&gt;
// Genres and stations&lt;br /&gt;
&lt;br /&gt;
integer category_index=0;    // Current index in category_list  (genre)&lt;br /&gt;
integer station_index=0;     // Current index in station_*      (station)&lt;br /&gt;
&lt;br /&gt;
integer num_categories=0;&lt;br /&gt;
integer num_stations=0;&lt;br /&gt;
&lt;br /&gt;
// Make request for title info using HTTP request&lt;br /&gt;
retrieve_titelinfo()&lt;br /&gt;
{&lt;br /&gt;
    string url=llList2String(station_url,station_index);&lt;br /&gt;
    httpreq_id=llHTTPRequest(url + &amp;quot;/7.html  HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n&amp;quot;,[],&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Display a line on an Xytext device linked in&lt;br /&gt;
display_line(string line, string message)&lt;br /&gt;
{&lt;br /&gt;
    // Setup XYtext Variables&lt;br /&gt;
    integer DISPLAY_STRING      = 204000; &lt;br /&gt;
//    integer DISPLAY_EXTENDED    = 204001;     (not used)&lt;br /&gt;
//    integer REMAP_INDICES       = 204002;     (not used) &lt;br /&gt;
//    integer RESET_INDICES       = 204003;     (not used)&lt;br /&gt;
//    integer SET_CELL_INFO       = 204004;     (not used)&lt;br /&gt;
//    integer SET_FONT_TEXTURE    = 204005;     (not used)&lt;br /&gt;
//    integer SET_THICKNESS       = 204006;     (not used)&lt;br /&gt;
//    integer SET_COLOR           = 204007;     (not used)&lt;br /&gt;
&lt;br /&gt;
    llMessageLinked(LINK_SET,DISPLAY_STRING,message,line);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Clear the Xytext display&lt;br /&gt;
clear_display() &lt;br /&gt;
{&lt;br /&gt;
    // Clears the display&lt;br /&gt;
    display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio Station ID&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;2&amp;quot;,&amp;quot;Music Genre....&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;3&amp;quot;,&amp;quot;Now Playing....&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Make a menu / dialog&lt;br /&gt;
make_menu(key id)&lt;br /&gt;
{&lt;br /&gt;
     menu_channel=random_channel();&lt;br /&gt;
&lt;br /&gt;
    if (radio_status == 0)&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        llDialog(id,&amp;quot;Menu: Status\n\nRadio is OFF&amp;quot;, [ &amp;quot;ON&amp;quot;, &amp;quot;HELP&amp;quot; ],menu_channel);&lt;br /&gt;
    }&lt;br /&gt;
    else &lt;br /&gt;
    {&lt;br /&gt;
        if (menu_type ==0)&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Genres&amp;quot;, category_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Stations\nGenre: &amp;quot; + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (listen_handle != 0)    llListenRemove(listen_handle);&lt;br /&gt;
    listen_handle=llListen(menu_channel,&amp;quot;&amp;quot;,id,&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Make the menu option list for menu: catagories (genres)&lt;br /&gt;
list category_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
&lt;br /&gt;
    if (len &amp;gt; 9)   // If more then 9 items (12 minus the 3 buttons for MAIN/HELP and PREV, NEXT)&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;   // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc. &lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt; last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
&lt;br /&gt;
             while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_HELP;&lt;br /&gt;
             else&lt;br /&gt;
                 menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_OFF;&lt;br /&gt;
             else&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num != last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;       &lt;br /&gt;
        }            &lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
        menu+=(list)button_OFF;&lt;br /&gt;
        menu+=(list)button_HELP;&lt;br /&gt;
    }        &lt;br /&gt;
    &lt;br /&gt;
    return menu;    // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns the number of stations in a certain category&lt;br /&gt;
integer stations_in_category(integer cat)&lt;br /&gt;
{&lt;br /&gt;
    integer count=0;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
    string category=llList2String(category_list,cat);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (category == llList2String(category_list,i))&lt;br /&gt;
            count++;&lt;br /&gt;
&lt;br /&gt;
    return count;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Not used currently -- to fix button placement&lt;br /&gt;
list order_buttons(list buttons)&lt;br /&gt;
{&lt;br /&gt;
    integer offset;&lt;br /&gt;
    list fixt;&lt;br /&gt;
    integer flag=0;&lt;br /&gt;
&lt;br /&gt;
    while((offset = llGetListLength(buttons)))&lt;br /&gt;
    {&lt;br /&gt;
        if (offset &amp;gt; 3)&lt;br /&gt;
            flag=1;&lt;br /&gt;
        else&lt;br /&gt;
            flag=0;&lt;br /&gt;
&lt;br /&gt;
        fixt += llList2List(buttons, offset = -3 * flag, -1);&lt;br /&gt;
        buttons = llDeleteSubList(buttons, offset, -1);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return fixt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns a list of station names in a certain category (genre)&lt;br /&gt;
list station_list(integer category)&lt;br /&gt;
{&lt;br /&gt;
    list s=[];&lt;br /&gt;
    integer i;&lt;br /&gt;
    string cname=llList2String(category_list,category_index);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; llGetListLength(station_name); i++)&lt;br /&gt;
        if (llList2String(station_category,i) == cname)&lt;br /&gt;
            s+=(list)llList2String(station_name,i);&lt;br /&gt;
&lt;br /&gt;
    return s;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns the list of stations for the station menu, depending on the submenu number&lt;br /&gt;
list station_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
    list stations=station_list(category_index);&lt;br /&gt;
    integer len=llGetListLength(stations);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
        &lt;br /&gt;
    if (len &amp;gt; 11)       // 12 - 1 for MAIN menu&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;&lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt;= last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
             integer last=9*num+8;&lt;br /&gt;
&lt;br /&gt;
             menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;gt; 0)&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;lt; last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;                      &lt;br /&gt;
&lt;br /&gt;
            if (len &amp;gt; last)&lt;br /&gt;
                len =last;&lt;br /&gt;
                &lt;br /&gt;
            while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(stations,len);&lt;br /&gt;
        }&lt;br /&gt;
    }            &lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(stations,len);&lt;br /&gt;
    }        &lt;br /&gt;
&lt;br /&gt;
    return menu; // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns whether av with key id has access&lt;br /&gt;
integer has_access(key id)&lt;br /&gt;
{&lt;br /&gt;
    if (llListFindList(banned_keys,(list)id) != -1)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    if (owner_access &amp;amp;&amp;amp; id == llGetOwner())&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (group_access &amp;amp;&amp;amp; llSameGroup(id))&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (public_access)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Gets a random channel -- uses a wide range of big negative channel numbers seldomly used&lt;br /&gt;
integer random_channel()&lt;br /&gt;
{&lt;br /&gt;
    integer min=-2147483647;&lt;br /&gt;
    integer max=-1000;&lt;br /&gt;
&lt;br /&gt;
    return (integer) (min + llFrand(max-min));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Check for the format of the url string  -- is very selective about url format&lt;br /&gt;
// expects:   xxx.xxx.xxx.xxx:xxxx    (ip adress in number notation with port adress)&lt;br /&gt;
// Next release will relax on this constraint.&lt;br /&gt;
integer check_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    integer pos=0;&lt;br /&gt;
&lt;br /&gt;
    if (llGetSubString(url,0,6) == &amp;quot;http://&amp;quot;)&lt;br /&gt;
        pos=7;        &lt;br /&gt;
    if (llGetSubString(url,0,7) == &amp;quot;https://&amp;quot;)&lt;br /&gt;
        pos=8;&lt;br /&gt;
&lt;br /&gt;
    if (pos==0)   return FALSE;&lt;br /&gt;
&lt;br /&gt;
    string str_ip_port=llGetSubString(url,pos,-1);&lt;br /&gt;
    list list_ip_port=llParseString2List(str_ip_port,[&amp;quot;:&amp;quot;],[]);                 // split in ip-adress and port&lt;br /&gt;
    list list_ip=llParseString2List(llList2String(list_ip_port,0),[&amp;quot;.&amp;quot;],[]);    // split ip-adress elements&lt;br /&gt;
&lt;br /&gt;
    if (llGetListLength(list_ip_port) != 2 || llGetListLength(list_ip) != 4)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer test;&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;4;i++)&lt;br /&gt;
    {&lt;br /&gt;
        test=llList2Integer(list_ip,i);&lt;br /&gt;
        if (llList2String(list_ip,i) != (string)test)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        if (test &amp;lt; 0 || test &amp;gt; 255)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    test=llList2Integer(list_ip_port,1);&lt;br /&gt;
    if (llList2String(list_ip_port,1) != (string)test)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns a true value depending on the first character in input - anything else is assumed false.&lt;br /&gt;
integer true_value(string input)&lt;br /&gt;
{&lt;br /&gt;
    string value=llToLower(llGetSubString(input,0,0));&lt;br /&gt;
&lt;br /&gt;
    if (value == &amp;quot;y&amp;quot; || value == &amp;quot;t&amp;quot; || value ==&amp;quot;1&amp;quot;)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Return if more input should be processed (if not at EOF) - sets ConfigError if any config error found. Reading config card stops at the first error.&lt;br /&gt;
integer process_line(string dataline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(dataline,STRING_TRIM);&lt;br /&gt;
    integer index=llSubStringIndex(line,comment_char);&lt;br /&gt;
    &lt;br /&gt;
    if (index==0)       // line starts with comment - ignore line&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (index!=-1)&lt;br /&gt;
        line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL);   // skip everything after comment_char and trim tail&lt;br /&gt;
&lt;br /&gt;
    if (line==&amp;quot;&amp;quot;)       // Ignore blank lines&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (llToLower(line) == &amp;quot;[access]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 1;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[banned]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 2;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[genre]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 3;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[station]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 4;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llGetSubString(line,0,0) == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; llGetSubString(line,-1,-1) == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: malformed section found at line &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
        config_error=TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: no section found on line: &amp;quot; + (string) lineno);&lt;br /&gt;
        config_error = TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    list breakup=llParseString2List(line,[&amp;quot;=&amp;quot;],[]);&lt;br /&gt;
    string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);&lt;br /&gt;
    string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);&lt;br /&gt;
&lt;br /&gt;
    if (section == 1)            // access&lt;br /&gt;
    {&lt;br /&gt;
        field=llToLower(field);&lt;br /&gt;
&lt;br /&gt;
        if (field==&amp;quot;owner&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            owner_access=true_value(values);                       &lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;group&amp;quot;)&lt;br /&gt;
        {    &lt;br /&gt;
            group_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;public&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            public_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: invalid option on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 2)         // ban list&lt;br /&gt;
    {&lt;br /&gt;
        key try=(key) field;&lt;br /&gt;
&lt;br /&gt;
        if (try)&lt;br /&gt;
        {&lt;br /&gt;
            banned_keys+=(list)((key) field);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 3)           // categories&lt;br /&gt;
    {&lt;br /&gt;
        if (llListFindList(category_list,(list)field) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            category_list+=(list)field;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;genre: &#039;&amp;quot; + field + &amp;quot;&#039; already entered; double entry skipped.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 4)            // stations&lt;br /&gt;
    {&lt;br /&gt;
        list parse=llParseString2List(line,sep_char_list, []);&lt;br /&gt;
        string category=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);&lt;br /&gt;
        string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);&lt;br /&gt;
    &lt;br /&gt;
        if (!available_category(category))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: unknown genre on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (check_url(url))&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                num_stations++;&lt;br /&gt;
                station_category+=(list)category;&lt;br /&gt;
                station_name+=(list)name;&lt;br /&gt;
                station_desc+=(list)desc;&lt;br /&gt;
                station_url+=(list)url;&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llWhisper(0,&amp;quot;This station is already entered under the same genre and same url and is skipped.\nStation: &amp;quot; + name + &amp;quot;\nGenre: &#039;&amp;quot; + category + &amp;quot;&#039;\nURL: &amp;quot; + url);&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: malformed url on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
     &lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Sets the parcel URL and updates the display&lt;br /&gt;
set_parcel_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    parcel_url=url;&lt;br /&gt;
    llSetParcelMusicURL(parcel_url);&lt;br /&gt;
&lt;br /&gt;
    if (parcel_url==&amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        clear_display();&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is OFF&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;station now set to &amp;quot; + llList2String(station_desc,station_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Station: &amp;quot; + llList2String(station_desc,station_index));&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;Genre  : &amp;quot; + llList2String(category_list,category_index));&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;Now playing.....&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns if a category (genre) exists.&lt;br /&gt;
integer available_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;len;i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(category_list,i)))&lt;br /&gt;
            return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns if a category (genre) is empty (i.e. there are no stations for this catagory (genre))&lt;br /&gt;
integer empty_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(station_category,i)))&lt;br /&gt;
            return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Removes categories (genres) for which no station is known.&lt;br /&gt;
skip_empty_categories()&lt;br /&gt;
{&lt;br /&gt;
    integer i=0;&lt;br /&gt;
&lt;br /&gt;
    while (i&amp;lt;llGetListLength(category_list))&lt;br /&gt;
    {&lt;br /&gt;
        if (empty_category(llList2String(category_list,i)))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;Warning: Genre &#039;&amp;quot; + llList2String(category_list,i) + &amp;quot;&#039; contains no stations and is deleted.&amp;quot;);&lt;br /&gt;
            category_list=llDeleteSubList(category_list,i,i);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            i++;&lt;br /&gt;
    }&lt;br /&gt;
            &lt;br /&gt;
    num_categories=llGetListLength(category_list);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state default&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        flag=FALSE;&lt;br /&gt;
        lineno=0;&lt;br /&gt;
        config_error=FALSE;&lt;br /&gt;
        num_stations=0;&lt;br /&gt;
        num_categories=0;&lt;br /&gt;
        radio_status=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(config_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
           reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
           llWhisper(0, &amp;quot;Reading config notecard...&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;1&amp;quot;,&amp;quot;Reading configuration.&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;2&amp;quot;,&amp;quot;Wait....&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;No config notecard &#039;&amp;quot; +  config_notecard + &amp;quot;&#039; present.&amp;quot;);&lt;br /&gt;
            state offline;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (reqid==id)&lt;br /&gt;
        {        &lt;br /&gt;
            if (data==EOF)&lt;br /&gt;
            {&lt;br /&gt;
                skip_empty_categories();&lt;br /&gt;
                llWhisper(0,&amp;quot;Configuration ok.\n&amp;quot; + (string)num_categories + &amp;quot; genres and &amp;quot; + (string)num_stations + &amp;quot; stations.&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Configuration OK&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;2&amp;quot;,&amp;quot;Genres  : &amp;quot; + (string)num_categories);&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Stations: &amp;quot; + (string)num_stations);&lt;br /&gt;
                state menu;&lt;br /&gt;
            }&lt;br /&gt;
            else &lt;br /&gt;
            {&lt;br /&gt;
                if (process_line(data))&lt;br /&gt;
                    reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
                else if (config_error)&lt;br /&gt;
                {&lt;br /&gt;
                    llWhisper(0,&amp;quot;errors found in configuration. please correct them.&amp;quot;);&lt;br /&gt;
                    state offline;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state offline&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state offline&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;Reset on owner touch or when notecard updated.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    touch_start(integer t)&lt;br /&gt;
    {&lt;br /&gt;
        if (llDetectedKey(0)==llGetOwner())&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY &amp;amp;&amp;amp; flag)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state menu&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state menu&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        listen_handle=0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        if (param &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
        key toucher=llDetectedKey(0);&lt;br /&gt;
&lt;br /&gt;
        if (has_access(toucher))&lt;br /&gt;
        {&lt;br /&gt;
            make_menu(toucher);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;sorry, no access.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    listen(integer chan, string name,key id,string msg)&lt;br /&gt;
    {&lt;br /&gt;
        integer index;&lt;br /&gt;
&lt;br /&gt;
        if (menu_type == 0)          // main menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_ON)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=1;&lt;br /&gt;
                set_parcel_url(parcel_url);               &lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is ON&amp;quot;);&lt;br /&gt;
                menu_num=0;&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned on.&amp;quot;);&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=0;&lt;br /&gt;
                set_parcel_url(&amp;quot;&amp;quot;);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned off.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
                {&lt;br /&gt;
                    llGiveInventory(id,info_notecard);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                    llWhisper(0,&amp;quot;sorry, help not available.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (radio_status == 1)&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(category_list, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: genre not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    category_index=index;&lt;br /&gt;
                    llWhisper(0,&amp;quot;Genre now set to &amp;quot; + llList2String(category_list,category_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
                    menu_type=1;&lt;br /&gt;
                    menu_num=0;&lt;br /&gt;
                    make_menu(id);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (menu_type == 1 &amp;amp;&amp;amp; radio_status == 1)     // station menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(station_name, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: station not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    station_index=index;&lt;br /&gt;
                    string new_url=llList2String(station_url,station_index);&lt;br /&gt;
&lt;br /&gt;
                    if (new_url != parcel_url)&lt;br /&gt;
                    {&lt;br /&gt;
                        set_parcel_url(new_url);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        retrieve_titelinfo();&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_response(key id, integer status, list meta, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == httpreq_id)&lt;br /&gt;
        {&lt;br /&gt;
            if (status == 200)&lt;br /&gt;
            {&lt;br /&gt;
                string feed = llGetSubString(body,llSubStringIndex(body, &amp;quot;&amp;lt;body&amp;gt;&amp;quot;) + llStringLength(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;), llSubStringIndex(body,&amp;quot;&amp;lt;/body&amp;gt;&amp;quot;) - 1);&lt;br /&gt;
                list feed_list = llParseString2List(feed,[&amp;quot;,&amp;quot;],[]);&lt;br /&gt;
                string current_title_info= llList2String(feed_list,6);&lt;br /&gt;
                integer length = llGetListLength(feed_list);&lt;br /&gt;
        &lt;br /&gt;
                if(llList2String(feed_list,7))&lt;br /&gt;
                {&lt;br /&gt;
                    integer a = 7;&lt;br /&gt;
                    for(; a&amp;lt;length; ++a)&lt;br /&gt;
                    {&lt;br /&gt;
                        current_title_info += &amp;quot;, &amp;quot; + llList2String(feed_list,a);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
         &lt;br /&gt;
                if (current_title_info != last_title_info)&lt;br /&gt;
                {&lt;br /&gt;
                    last_title_info = current_title_info;&lt;br /&gt;
                    display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + current_title_info);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + no_title_info);&lt;br /&gt;
            }&lt;br /&gt;
        }    &lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY &amp;amp;&amp;amp; flag)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
// end of script&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Notecard format===&lt;br /&gt;
Example notecard&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# New format Shoutcast - radio controller config notecard&lt;br /&gt;
# The format is divided in 4 sections:&lt;br /&gt;
# 1 - Access configuration&lt;br /&gt;
# 2 - Ban list (keys)&lt;br /&gt;
# 3 - Categories  (same as genres)&lt;br /&gt;
# 4 - Station info (category, name, desc, url)&lt;br /&gt;
# The &#039;#&#039; character defines the start of a comment and can be anywhere on a line. &lt;br /&gt;
# Everything after the &#039;#&#039; incuding the &#039;#&#039; itself is ignored.&lt;br /&gt;
# Case is not important (but information on display will show as entered)&lt;br /&gt;
# Spaces before and/or after fields are trimmed.&lt;br /&gt;
# Empty lines are ignored.&lt;br /&gt;
&lt;br /&gt;
[ACCESS]&lt;br /&gt;
owner=yes       # yes, true,1      means owner has access. everything else not.&lt;br /&gt;
group=yes       #  ,,  ,,  ,,      means group has acess.    ,,        ,,   ,,&lt;br /&gt;
public=yes      #  ,,  ,,  ,,      means public has access.  ,,        ,,   ,, &lt;br /&gt;
&lt;br /&gt;
[BANNED]&lt;br /&gt;
# keys of banned residents&lt;br /&gt;
&lt;br /&gt;
[GENRE]&lt;br /&gt;
# genre name -- Use short genre names as the the length of menu buttons is short!&lt;br /&gt;
Hard Rock&lt;br /&gt;
Classic Rock&lt;br /&gt;
Oldies&lt;br /&gt;
Rap/Urban&lt;br /&gt;
Comedy&lt;br /&gt;
News&lt;br /&gt;
Dance&lt;br /&gt;
Country&lt;br /&gt;
Gothic&lt;br /&gt;
# etc.&lt;br /&gt;
[STATION]&lt;br /&gt;
# Shoutcast radio stations&lt;br /&gt;
# Use a &#039;|&#039; between each field - don&#039;t mind spaces before and after fields, they will be trimmed&lt;br /&gt;
# field1:genre, field2:station name, field3: station description, field4: station http://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt; or https://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;&lt;br /&gt;
# Note that genre must match case-insensitive a value previously entered in section [GENRE]&lt;br /&gt;
Classic Rock    | Absolute         |    Absolute Radio                  | http://205.188.215.226:8018&lt;br /&gt;
# etc.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===TODO===&lt;br /&gt;
&lt;br /&gt;
Planned for upcoming release 0.4:&lt;br /&gt;
* Add a llRegionSay to broadcast the &amp;lt;station&amp;gt;|&amp;lt;genre&amp;gt;|&amp;lt;current songtitle&amp;gt;|&amp;lt;url&amp;gt; to the region and add a script that displays that info on a remote Xytext board. (for use with a remote controller and/or remote display board anywhere in the region/parcel)&lt;br /&gt;
* llResetScript on owner change&lt;br /&gt;
* Relax on URL format&lt;br /&gt;
* Allow multiple genres per station&lt;/div&gt;</description>
			<pubDate>Thu, 10 Feb 2011 00:58:55 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)</comments>
		</item>
		<item>
			<title>Shoutcast - radio controller v0.3 (remake of similar scripts)</title>
			<link>https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133923</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133923</guid>
			<description>&lt;p&gt;Flennan Roffo: /* Shoutcast - radio controller */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}}&lt;br /&gt;
=Shoutcast - radio controller=&lt;br /&gt;
This script controls a shoutcast radio receiver and lets you select the stations that you configured on a notecard. Menu driven. Output of station description, genre and current song title using Xy text.&lt;br /&gt;
Credits for this script go to previous developers of similar scripts:&lt;br /&gt;
* Scripter Coba who wrote the LandOwnersRadio (V2.0) script. Menu driven / notecard config script to select genre and station to set parcel music url.&lt;br /&gt;
* Jamie Otis who wrote the Raven radio infoboard script. Shows what song is playing by fetching info using the sis.slserver.info/sis.php service (now offline). Display on Xytext.&lt;br /&gt;
* Darkie Minotaur who wrote the currentPlaying script. Shows what song is currently playing by fetching info from the /7.html shoutcast page.&lt;br /&gt;
&lt;br /&gt;
Although this script is based upon similar functionality as provided in these scripts, this script is not simply a merge/copy of those scripts, but a complete make-over. &lt;br /&gt;
I use my own notecard format and processing of notecard info, and own menu system.&lt;br /&gt;
&lt;br /&gt;
==Versions==&lt;br /&gt;
&lt;br /&gt;
Current version: v0.3 released 10-2-2011&lt;br /&gt;
&lt;br /&gt;
==Scripts==&lt;br /&gt;
&lt;br /&gt;
===Shoutcast - radio controller===&lt;br /&gt;
This script should be put into the shoutcast - radio controller device.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// Script:  Shoutcast - radio controller&lt;br /&gt;
// Version: 0.3 - released 10-2-2011&lt;br /&gt;
// Logic Scripts (Flennan Roffo)&lt;br /&gt;
// (c) 2010 - Flennan Roffo (Logic Scripts)&lt;br /&gt;
// &lt;br /&gt;
// This script is a remake of a couple of similar script:&lt;br /&gt;
// + LandOwnersRadio V2.0 by Scripter Coba  (( menu driven / notecard config script to select the radio station and sets parcel music url ))&lt;br /&gt;
// + Raven radio infoboard by Jamie Otis    (( worked at the basis of sis service [sis.slserver.com/sis.php] used Xy text display         ))&lt;br /&gt;
// + currentPlaying by Darkie Minotaur      (( used the /7.html info to fetch current song title info, displayed as float text            ))&lt;br /&gt;
//&lt;br /&gt;
// Purpose:&lt;br /&gt;
// * Sets the parcel audio URL and displays the channel info&lt;br /&gt;
// * Uses Xytext to display the info.&lt;br /&gt;
// * Fetches song title info from the shoutcast url&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.1 release&lt;br /&gt;
// * On/Off option&lt;br /&gt;
// * Allows multiple menus (if options per menu &amp;gt; 12) using a prev/next button&lt;br /&gt;
// * Checks if your url is well-formatted&lt;br /&gt;
// * Will delete genres for which no stations exist&lt;br /&gt;
// * Will skip stations that have same url and same genre (you can however have an identical station url under different genres).&lt;br /&gt;
// * New notecard format&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.2 release&lt;br /&gt;
// * Configurable button text&lt;br /&gt;
// * Gets parcel URL and automatically sets the genre/station and on/off status accordingly (&amp;lt;-- doesn&#039;t work)&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Update -- 0.3 release&lt;br /&gt;
// * Fixed bug (only first station in genre displayed in menu)&lt;br /&gt;
// * Auto reset script when config card updated&lt;br /&gt;
// Notes:&lt;br /&gt;
// * Expects url to be in the format: &amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;, where &amp;lt;ip&amp;gt; has the format: xxx.xxx.xxx.xxx  (0 &amp;lt;= xxx &amp;lt;= 255) &lt;br /&gt;
// * Deletes entries in category (genre) for which no stations are configured with notice.&lt;br /&gt;
// * Skips stations which have identical url AND same category (genre).&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Upcoming release -- 0.4&lt;br /&gt;
// * Will add functions for remote controller(s) and remote display(s) using llRegionSay to communicate over a channel.&lt;br /&gt;
// * Should relax on the constraints about the input format of URL&#039;s (currently requires that URL has format: xxx.xxx.xxx.xxx/yyyy).&lt;br /&gt;
// * Fix button placement. Control buttons should be on the first line.&lt;br /&gt;
// * Implement script reset on change of owner.&lt;br /&gt;
// * Permit station to be put under multiple genres, using a comma-seperated list of genres in the section [STATION]&lt;br /&gt;
//   (currently this is only possible by duplicating the entire line and change the genre.)&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Future plans:&lt;br /&gt;
// * Individual user preferences that can be stored on seperate note cards. A user has access to his own list of genres and stations and the system available genres/stations.&lt;br /&gt;
// * Feature for accessing online playlists (M3U, PLS, other formats) to play a list of songs provided by that playlist.&lt;br /&gt;
// * User provided url.&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// BUGS &amp;amp; FEATURE REQUESTS&lt;br /&gt;
//&lt;br /&gt;
// Please inform the author, Logic Scripts (flennan.roffo) about any bugs or annoyances.&lt;br /&gt;
// Feature requests can also be submitted to the author.&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// LICENCE INFO&lt;br /&gt;
//&lt;br /&gt;
// This program is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string info_notecard=&amp;quot;Radio Control info&amp;quot;;              ///////    EDITABLE  \\\\\\&lt;br /&gt;
string config_notecard=&amp;quot;Radio Control config&amp;quot;;          ///////    EDITABLE  \\\\\\&lt;br /&gt;
string comment_char=&amp;quot;#&amp;quot;;                                ///////    EDITABLE  \\\\\\&lt;br /&gt;
list sep_char_list= [&amp;quot;|&amp;quot;];                              ///////    EDITABLE  \\\\\\&lt;br /&gt;
float update_time=5.0;                                  ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string no_title_info=&amp;quot;(no title info available)&amp;quot;;       ///////    EDITABLE  \\\\\\&lt;br /&gt;
&lt;br /&gt;
// not used currently - for showing info on current song title elsewhere in the region&lt;br /&gt;
integer broadcast_channel=-1234;                        ///////    EDITABLE  \\\\\\ &lt;br /&gt;
&lt;br /&gt;
// Buttons&lt;br /&gt;
&lt;br /&gt;
string button_MAIN = &amp;quot;MAIN&amp;quot;;                            ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string button_HELP = &amp;quot;HELP&amp;quot;;                            ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string button_NEXT = &amp;quot;&amp;gt;&amp;gt;&amp;quot;;                              ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string button_PREV = &amp;quot;&amp;lt;&amp;lt;&amp;quot;;                              ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string button_ON   = &amp;quot;ON&amp;quot;;                              ///////    EDITABLE  \\\\\\  &lt;br /&gt;
string button_OFF  = &amp;quot;OFF&amp;quot;;                             ///////    EDITABLE  \\\\\\ &lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// Don&#039;t touch the variables below &lt;br /&gt;
/////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
// List of categories (=genres)&lt;br /&gt;
&lt;br /&gt;
list category_list=[];&lt;br /&gt;
&lt;br /&gt;
// List of stations. KEEP THESE LISTS IN SYNCH!&lt;br /&gt;
&lt;br /&gt;
list station_category=[];&lt;br /&gt;
list station_name=[];&lt;br /&gt;
list station_desc=[];&lt;br /&gt;
list station_url=[];&lt;br /&gt;
&lt;br /&gt;
// Last song title played&lt;br /&gt;
string last_title_info=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
integer radio_status=0;    // 0 - OFF   1 - ON&lt;br /&gt;
string parcel_url=&amp;quot;&amp;quot;;&lt;br /&gt;
integer lineno=0;&lt;br /&gt;
key reqid=NULL_KEY;&lt;br /&gt;
key httpreq_id=NULL_KEY;&lt;br /&gt;
integer config_error=FALSE;&lt;br /&gt;
integer flag;&lt;br /&gt;
integer section=0;&lt;br /&gt;
&lt;br /&gt;
// Access values. Note that users who are banned can not access the device even when access is public&lt;br /&gt;
integer owner_access=TRUE;&lt;br /&gt;
integer group_access=FALSE;&lt;br /&gt;
integer public_access=TRUE;&lt;br /&gt;
list banned_keys=[];&lt;br /&gt;
&lt;br /&gt;
// Channels for menu and user input&lt;br /&gt;
integer menu_channel;&lt;br /&gt;
integer listen_handle;&lt;br /&gt;
&lt;br /&gt;
// Menu&lt;br /&gt;
integer menu_type=0;         // 0 - Main menu (genres)   1 - Station menu (stations)&lt;br /&gt;
integer menu_num=0;          // When more menu options need to be selectable then can be displayed on a menu (12), this is the menu number - menu number 0 is the first menu.&lt;br /&gt;
&lt;br /&gt;
// Genres and stations&lt;br /&gt;
&lt;br /&gt;
integer category_index=0;    // Current index in category_list  (genre)&lt;br /&gt;
integer station_index=0;     // Current index in station_*      (station)&lt;br /&gt;
&lt;br /&gt;
integer num_categories=0;&lt;br /&gt;
integer num_stations=0;&lt;br /&gt;
&lt;br /&gt;
// Make request for title info using HTTP request&lt;br /&gt;
retrieve_titelinfo()&lt;br /&gt;
{&lt;br /&gt;
    string url=llList2String(station_url,station_index);&lt;br /&gt;
    httpreq_id=llHTTPRequest(url + &amp;quot;/7.html  HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n&amp;quot;,[],&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Display a line on an Xytext device linked in&lt;br /&gt;
display_line(string line, string message)&lt;br /&gt;
{&lt;br /&gt;
    // Setup XYtext Variables&lt;br /&gt;
    integer DISPLAY_STRING      = 204000; &lt;br /&gt;
//    integer DISPLAY_EXTENDED    = 204001;     (not used)&lt;br /&gt;
//    integer REMAP_INDICES       = 204002;     (not used) &lt;br /&gt;
//    integer RESET_INDICES       = 204003;     (not used)&lt;br /&gt;
//    integer SET_CELL_INFO       = 204004;     (not used)&lt;br /&gt;
//    integer SET_FONT_TEXTURE    = 204005;     (not used)&lt;br /&gt;
//    integer SET_THICKNESS       = 204006;     (not used)&lt;br /&gt;
//    integer SET_COLOR           = 204007;     (not used)&lt;br /&gt;
&lt;br /&gt;
    llMessageLinked(LINK_SET,DISPLAY_STRING,message,line);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Clear the Xytext display&lt;br /&gt;
clear_display() &lt;br /&gt;
{&lt;br /&gt;
    // Clears the display&lt;br /&gt;
    display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio Station ID&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;2&amp;quot;,&amp;quot;Music Genre....&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;3&amp;quot;,&amp;quot;Now Playing....&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Make a menu / dialog&lt;br /&gt;
make_menu(key id)&lt;br /&gt;
{&lt;br /&gt;
     menu_channel=random_channel();&lt;br /&gt;
&lt;br /&gt;
    if (radio_status == 0)&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        llDialog(id,&amp;quot;Menu: Status\n\nRadio is OFF&amp;quot;, [ &amp;quot;ON&amp;quot;, &amp;quot;HELP&amp;quot; ],menu_channel);&lt;br /&gt;
    }&lt;br /&gt;
    else &lt;br /&gt;
    {&lt;br /&gt;
        if (menu_type ==0)&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Genres&amp;quot;, category_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Stations\nGenre: &amp;quot; + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (listen_handle != 0)    llListenRemove(listen_handle);&lt;br /&gt;
    listen_handle=llListen(menu_channel,&amp;quot;&amp;quot;,id,&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Make the menu option list for menu: catagories (genres)&lt;br /&gt;
list category_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
&lt;br /&gt;
    if (len &amp;gt; 9)   // If more then 9 items (12 minus the 3 buttons for MAIN/HELP and PREV, NEXT)&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;   // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc. &lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt; last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
&lt;br /&gt;
             while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_HELP;&lt;br /&gt;
             else&lt;br /&gt;
                 menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_OFF;&lt;br /&gt;
             else&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num != last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;       &lt;br /&gt;
        }            &lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
        menu+=(list)button_OFF;&lt;br /&gt;
        menu+=(list)button_HELP;&lt;br /&gt;
    }        &lt;br /&gt;
    &lt;br /&gt;
    return menu;    // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns the number of stations in a certain category&lt;br /&gt;
integer stations_in_category(integer cat)&lt;br /&gt;
{&lt;br /&gt;
    integer count=0;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
    string category=llList2String(category_list,cat);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (category == llList2String(category_list,i))&lt;br /&gt;
            count++;&lt;br /&gt;
&lt;br /&gt;
    return count;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Not used currently -- to fix button placement&lt;br /&gt;
list order_buttons(list buttons)&lt;br /&gt;
{&lt;br /&gt;
    integer offset;&lt;br /&gt;
    list fixt;&lt;br /&gt;
    integer flag=0;&lt;br /&gt;
&lt;br /&gt;
    while((offset = llGetListLength(buttons)))&lt;br /&gt;
    {&lt;br /&gt;
        if (offset &amp;gt; 3)&lt;br /&gt;
            flag=1;&lt;br /&gt;
        else&lt;br /&gt;
            flag=0;&lt;br /&gt;
&lt;br /&gt;
        fixt += llList2List(buttons, offset = -3 * flag, -1);&lt;br /&gt;
        buttons = llDeleteSubList(buttons, offset, -1);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return fixt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns a list of station names in a certain category (genre)&lt;br /&gt;
list station_list(integer category)&lt;br /&gt;
{&lt;br /&gt;
    list s=[];&lt;br /&gt;
    integer i;&lt;br /&gt;
    string cname=llList2String(category_list,category_index);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; llGetListLength(station_name); i++)&lt;br /&gt;
        if (llList2String(station_category,i) == cname)&lt;br /&gt;
            s+=(list)llList2String(station_name,i);&lt;br /&gt;
&lt;br /&gt;
    return s;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns the list of stations for the station menu, depending on the submenu number&lt;br /&gt;
list station_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
    list stations=station_list(category_index);&lt;br /&gt;
    integer len=llGetListLength(stations);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
        &lt;br /&gt;
    if (len &amp;gt; 11)       // 12 - 1 for MAIN menu&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;&lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt;= last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
             integer last=9*num+8;&lt;br /&gt;
&lt;br /&gt;
             menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;gt; 0)&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;lt; last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;                      &lt;br /&gt;
&lt;br /&gt;
            if (len &amp;gt; last)&lt;br /&gt;
                len =last;&lt;br /&gt;
                &lt;br /&gt;
            while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(stations,len);&lt;br /&gt;
        }&lt;br /&gt;
    }            &lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(stations,len);&lt;br /&gt;
    }        &lt;br /&gt;
&lt;br /&gt;
    return menu; // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns whether av with key id has access&lt;br /&gt;
integer has_access(key id)&lt;br /&gt;
{&lt;br /&gt;
    if (llListFindList(banned_keys,(list)id) != -1)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    if (owner_access &amp;amp;&amp;amp; id == llGetOwner())&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (group_access &amp;amp;&amp;amp; llSameGroup(id))&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (public_access)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Gets a random channel -- uses a wide range of big negative channel numbers seldomly used&lt;br /&gt;
integer random_channel()&lt;br /&gt;
{&lt;br /&gt;
    integer min=-2147483647;&lt;br /&gt;
    integer max=-1000;&lt;br /&gt;
&lt;br /&gt;
    return (integer) (min + llFrand(max-min));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Check for the format of the url string  -- is very selective about url format&lt;br /&gt;
// expects:   xxx.xxx.xxx.xxx:xxxx    (ip adress in number notation with port adress)&lt;br /&gt;
// Next release will relax on this constraint.&lt;br /&gt;
integer check_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    integer pos=0;&lt;br /&gt;
&lt;br /&gt;
    if (llGetSubString(url,0,6) == &amp;quot;http://&amp;quot;)&lt;br /&gt;
        pos=7;        &lt;br /&gt;
    if (llGetSubString(url,0,7) == &amp;quot;https://&amp;quot;)&lt;br /&gt;
        pos=8;&lt;br /&gt;
&lt;br /&gt;
    if (pos==0)   return FALSE;&lt;br /&gt;
&lt;br /&gt;
    string str_ip_port=llGetSubString(url,pos,-1);&lt;br /&gt;
    list list_ip_port=llParseString2List(str_ip_port,[&amp;quot;:&amp;quot;],[]);                 // split in ip-adress and port&lt;br /&gt;
    list list_ip=llParseString2List(llList2String(list_ip_port,0),[&amp;quot;.&amp;quot;],[]);    // split ip-adress elements&lt;br /&gt;
&lt;br /&gt;
    if (llGetListLength(list_ip_port) != 2 || llGetListLength(list_ip) != 4)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer test;&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;4;i++)&lt;br /&gt;
    {&lt;br /&gt;
        test=llList2Integer(list_ip,i);&lt;br /&gt;
        if (llList2String(list_ip,i) != (string)test)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        if (test &amp;lt; 0 || test &amp;gt; 255)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    test=llList2Integer(list_ip_port,1);&lt;br /&gt;
    if (llList2String(list_ip_port,1) != (string)test)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns a true value depending on the first character in input - anything else is assumed false.&lt;br /&gt;
integer true_value(string input)&lt;br /&gt;
{&lt;br /&gt;
    string value=llToLower(llGetSubString(input,0,0));&lt;br /&gt;
&lt;br /&gt;
    if (value == &amp;quot;y&amp;quot; || value == &amp;quot;t&amp;quot; || value ==&amp;quot;1&amp;quot;)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Return if more input should be processed (if not at EOF) - sets ConfigError if any config error found. Reading config card stops at the first error.&lt;br /&gt;
integer process_line(string dataline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(dataline,STRING_TRIM);&lt;br /&gt;
    integer index=llSubStringIndex(line,comment_char);&lt;br /&gt;
    &lt;br /&gt;
    if (index==0)       // line starts with comment - ignore line&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (index!=-1)&lt;br /&gt;
        line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL);   // skip everything after comment_char and trim tail&lt;br /&gt;
&lt;br /&gt;
    if (line==&amp;quot;&amp;quot;)       // Ignore blank lines&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (llToLower(line) == &amp;quot;[access]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 1;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[banned]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 2;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[genre]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 3;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[station]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 4;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llGetSubString(line,0,0) == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; llGetSubString(line,-1,-1) == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: malformed section found at line &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
        config_error=TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: no section found on line: &amp;quot; + (string) lineno);&lt;br /&gt;
        config_error = TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    list breakup=llParseString2List(line,[&amp;quot;=&amp;quot;],[]);&lt;br /&gt;
    string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);&lt;br /&gt;
    string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);&lt;br /&gt;
&lt;br /&gt;
    if (section == 1)            // access&lt;br /&gt;
    {&lt;br /&gt;
        field=llToLower(field);&lt;br /&gt;
&lt;br /&gt;
        if (field==&amp;quot;owner&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            owner_access=true_value(values);                       &lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;group&amp;quot;)&lt;br /&gt;
        {    &lt;br /&gt;
            group_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;public&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            public_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: invalid option on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 2)         // ban list&lt;br /&gt;
    {&lt;br /&gt;
        key try=(key) field;&lt;br /&gt;
&lt;br /&gt;
        if (try)&lt;br /&gt;
        {&lt;br /&gt;
            banned_keys+=(list)((key) field);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 3)           // categories&lt;br /&gt;
    {&lt;br /&gt;
        if (llListFindList(category_list,(list)field) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            category_list+=(list)field;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;genre: &#039;&amp;quot; + field + &amp;quot;&#039; already entered; double entry skipped.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 4)            // stations&lt;br /&gt;
    {&lt;br /&gt;
        list parse=llParseString2List(line,sep_char_list, []);&lt;br /&gt;
        string category=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);&lt;br /&gt;
        string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);&lt;br /&gt;
    &lt;br /&gt;
        if (!available_category(category))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: unknown genre on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (check_url(url))&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                num_stations++;&lt;br /&gt;
                station_category+=(list)category;&lt;br /&gt;
                station_name+=(list)name;&lt;br /&gt;
                station_desc+=(list)desc;&lt;br /&gt;
                station_url+=(list)url;&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llWhisper(0,&amp;quot;This station is already entered under the same genre and same url and is skipped.\nStation: &amp;quot; + name + &amp;quot;\nGenre: &#039;&amp;quot; + category + &amp;quot;&#039;\nURL: &amp;quot; + url);&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: malformed url on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
     &lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Sets the parcel URL and updates the display&lt;br /&gt;
set_parcel_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    parcel_url=url;&lt;br /&gt;
    llSetParcelMusicURL(parcel_url);&lt;br /&gt;
&lt;br /&gt;
    if (parcel_url==&amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        clear_display();&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is OFF&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;station now set to &amp;quot; + llList2String(station_desc,station_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Station: &amp;quot; + llList2String(station_desc,station_index));&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;Genre  : &amp;quot; + llList2String(category_list,category_index));&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;Now playing.....&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns if a category (genre) exists.&lt;br /&gt;
integer available_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;len;i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(category_list,i)))&lt;br /&gt;
            return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns if a category (genre) is empty (i.e. there are no stations for this catagory (genre))&lt;br /&gt;
integer empty_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(station_category,i)))&lt;br /&gt;
            return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Removes categories (genres) for which no station is known.&lt;br /&gt;
skip_empty_categories()&lt;br /&gt;
{&lt;br /&gt;
    integer i=0;&lt;br /&gt;
&lt;br /&gt;
    while (i&amp;lt;llGetListLength(category_list))&lt;br /&gt;
    {&lt;br /&gt;
        if (empty_category(llList2String(category_list,i)))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;Warning: Genre &#039;&amp;quot; + llList2String(category_list,i) + &amp;quot;&#039; contains no stations and is deleted.&amp;quot;);&lt;br /&gt;
            category_list=llDeleteSubList(category_list,i,i);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            i++;&lt;br /&gt;
    }&lt;br /&gt;
            &lt;br /&gt;
    num_categories=llGetListLength(category_list);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state default&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        flag=FALSE;&lt;br /&gt;
        lineno=0;&lt;br /&gt;
        config_error=FALSE;&lt;br /&gt;
        num_stations=0;&lt;br /&gt;
        num_categories=0;&lt;br /&gt;
        radio_status=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(config_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
           reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
           llWhisper(0, &amp;quot;Reading config notecard...&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;1&amp;quot;,&amp;quot;Reading configuration.&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;2&amp;quot;,&amp;quot;Wait....&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;No config notecard &#039;&amp;quot; +  config_notecard + &amp;quot;&#039; present.&amp;quot;);&lt;br /&gt;
            state offline;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (reqid==id)&lt;br /&gt;
        {        &lt;br /&gt;
            if (data==EOF)&lt;br /&gt;
            {&lt;br /&gt;
                skip_empty_categories();&lt;br /&gt;
                llWhisper(0,&amp;quot;Configuration ok.\n&amp;quot; + (string)num_categories + &amp;quot; genres and &amp;quot; + (string)num_stations + &amp;quot; stations.&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Configuration OK&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;2&amp;quot;,&amp;quot;Genres  : &amp;quot; + (string)num_categories);&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Stations: &amp;quot; + (string)num_stations);&lt;br /&gt;
                state menu;&lt;br /&gt;
            }&lt;br /&gt;
            else &lt;br /&gt;
            {&lt;br /&gt;
                if (process_line(data))&lt;br /&gt;
                    reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
                else if (config_error)&lt;br /&gt;
                {&lt;br /&gt;
                    llWhisper(0,&amp;quot;errors found in configuration. please correct them.&amp;quot;);&lt;br /&gt;
                    state offline;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state offline&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state offline&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;Reset on owner touch or when notecard updated.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    touch_start(integer t)&lt;br /&gt;
    {&lt;br /&gt;
        if (llDetectedKey(0)==llGetOwner())&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY &amp;amp;&amp;amp; flag)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state menu&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state menu&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        listen_handle=0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        if (param &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
        key toucher=llDetectedKey(0);&lt;br /&gt;
&lt;br /&gt;
        if (has_access(toucher))&lt;br /&gt;
        {&lt;br /&gt;
            make_menu(toucher);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;sorry, no access.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    listen(integer chan, string name,key id,string msg)&lt;br /&gt;
    {&lt;br /&gt;
        integer index;&lt;br /&gt;
&lt;br /&gt;
        if (menu_type == 0)          // main menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_ON)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=1;&lt;br /&gt;
                set_parcel_url(parcel_url);               &lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is ON&amp;quot;);&lt;br /&gt;
                menu_num=0;&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned on.&amp;quot;);&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=0;&lt;br /&gt;
                set_parcel_url(&amp;quot;&amp;quot;);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned off.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
                {&lt;br /&gt;
                    llGiveInventory(id,info_notecard);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                    llWhisper(0,&amp;quot;sorry, help not available.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (radio_status == 1)&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(category_list, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: genre not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    category_index=index;&lt;br /&gt;
                    llWhisper(0,&amp;quot;Genre now set to &amp;quot; + llList2String(category_list,category_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
                    menu_type=1;&lt;br /&gt;
                    menu_num=0;&lt;br /&gt;
                    make_menu(id);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (menu_type == 1 &amp;amp;&amp;amp; radio_status == 1)     // station menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(station_name, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: station not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    station_index=index;&lt;br /&gt;
                    string new_url=llList2String(station_url,station_index);&lt;br /&gt;
&lt;br /&gt;
                    if (new_url != parcel_url)&lt;br /&gt;
                    {&lt;br /&gt;
                        set_parcel_url(new_url);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        retrieve_titelinfo();&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_response(key id, integer status, list meta, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == httpreq_id)&lt;br /&gt;
        {&lt;br /&gt;
            if (status == 200)&lt;br /&gt;
            {&lt;br /&gt;
                string feed = llGetSubString(body,llSubStringIndex(body, &amp;quot;&amp;lt;body&amp;gt;&amp;quot;) + llStringLength(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;), llSubStringIndex(body,&amp;quot;&amp;lt;/body&amp;gt;&amp;quot;) - 1);&lt;br /&gt;
                list feed_list = llParseString2List(feed,[&amp;quot;,&amp;quot;],[]);&lt;br /&gt;
                string current_title_info= llList2String(feed_list,6);&lt;br /&gt;
                integer length = llGetListLength(feed_list);&lt;br /&gt;
        &lt;br /&gt;
                if(llList2String(feed_list,7))&lt;br /&gt;
                {&lt;br /&gt;
                    integer a = 7;&lt;br /&gt;
                    for(; a&amp;lt;length; ++a)&lt;br /&gt;
                    {&lt;br /&gt;
                        current_title_info += &amp;quot;, &amp;quot; + llList2String(feed_list,a);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
         &lt;br /&gt;
                if (current_title_info != last_title_info)&lt;br /&gt;
                {&lt;br /&gt;
                    last_title_info = current_title_info;&lt;br /&gt;
                    display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + current_title_info);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + no_title_info);&lt;br /&gt;
            }&lt;br /&gt;
        }    &lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY &amp;amp;&amp;amp; flag)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
// end of script&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Notecard format===&lt;br /&gt;
Example notecard&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# New format Shoutcast - radio controller config notecard&lt;br /&gt;
# The format is divided in 4 sections:&lt;br /&gt;
# 1 - Access configuration&lt;br /&gt;
# 2 - Ban list (keys)&lt;br /&gt;
# 3 - Categories  (same as genres)&lt;br /&gt;
# 4 - Station info (category, name, desc, url)&lt;br /&gt;
# The &#039;#&#039; character defines the start of a comment and can be anywhere on a line. &lt;br /&gt;
# Everything after the &#039;#&#039; incuding the &#039;#&#039; itself is ignored.&lt;br /&gt;
# Case is not important (but information on display will show as entered)&lt;br /&gt;
# Spaces before and/or after fields are trimmed.&lt;br /&gt;
# Empty lines are ignored.&lt;br /&gt;
&lt;br /&gt;
[ACCESS]&lt;br /&gt;
owner=yes       # yes, true,1      means owner has access. everything else not.&lt;br /&gt;
group=yes       #  ,,  ,,  ,,      means group has acess.    ,,        ,,   ,,&lt;br /&gt;
public=yes      #  ,,  ,,  ,,      means public has access.  ,,        ,,   ,, &lt;br /&gt;
&lt;br /&gt;
[BANNED]&lt;br /&gt;
# keys of banned residents&lt;br /&gt;
&lt;br /&gt;
[GENRE]&lt;br /&gt;
# genre name -- Use short genre names as the the length of menu buttons is short!&lt;br /&gt;
Hard Rock&lt;br /&gt;
Classic Rock&lt;br /&gt;
Oldies&lt;br /&gt;
Rap/Urban&lt;br /&gt;
Comedy&lt;br /&gt;
News&lt;br /&gt;
Dance&lt;br /&gt;
Country&lt;br /&gt;
Gothic&lt;br /&gt;
# etc.&lt;br /&gt;
[STATION]&lt;br /&gt;
# Shoutcast radio stations&lt;br /&gt;
# Use a &#039;|&#039; between each field - don&#039;t mind spaces before and after fields, they will be trimmed&lt;br /&gt;
# field1:genre, field2:station name, field3: station description, field4: station http://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt; or https://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;&lt;br /&gt;
# Note that genre must match case-insensitive a value previously entered in section [GENRE]&lt;br /&gt;
Classic Rock    | Absolute         |    Absolute Radio                  | http://205.188.215.226:8018&lt;br /&gt;
# etc.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===TODO===&lt;br /&gt;
&lt;br /&gt;
Planned for upcoming release 0.4:&lt;br /&gt;
* Add a llRegionSay to broadcast the &amp;lt;station&amp;gt;|&amp;lt;genre&amp;gt;|&amp;lt;current songtitle&amp;gt;|&amp;lt;url&amp;gt; to the region and add a script that displays that info on a remote Xytext board. (for use with a remote controller and/or remote display board anywhere in the region/parcel)&lt;br /&gt;
* llResetScript on owner change&lt;br /&gt;
* Relax on URL format&lt;br /&gt;
* Allow multiple genres per station&lt;/div&gt;</description>
			<pubDate>Thu, 10 Feb 2011 00:58:12 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)</comments>
		</item>
		<item>
			<title>Shoutcast - radio controller v0.3 (remake of similar scripts)</title>
			<link>https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133922</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133922</guid>
			<description>&lt;p&gt;Flennan Roffo: /* Main script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}}&lt;br /&gt;
=Shoutcast - radio controller=&lt;br /&gt;
This script controls a shoutcast radio receiver and lets you select the stations that you configured on a notecard. Menu driven. Output of station description, genre and current song title using Xy text.&lt;br /&gt;
Credits for this script go to previous developers of similar scripts:&lt;br /&gt;
* Scripter Coba who wrote the LandOwnersRadio (V2.0) script. Menu driven / notecard config script to select genre and station to set parcel music url.&lt;br /&gt;
* Jamie Otis who wrote the Raven radio infoboard script. Shows what song is playing by fetching info using the sis.slserver.info/sis.php service (now offline). Display on Xytext.&lt;br /&gt;
* Darkie Minotaur who wrote the currentPlaying script. Shows what song is currently playing by fetching info from the /7.html shoutcast page.&lt;br /&gt;
&lt;br /&gt;
Although this script is based upon similar functionality as provided in these scripts, this script is not simply a merge/copy of those scripts, but a complete make-over. &lt;br /&gt;
I use my own notecard format and processing of notecard info, and own menu system.&lt;br /&gt;
&lt;br /&gt;
==Versions==&lt;br /&gt;
&lt;br /&gt;
Current version: v0.3 released 10-2-2011&lt;br /&gt;
&lt;br /&gt;
==Scripts==&lt;br /&gt;
&lt;br /&gt;
===Shoutcast - radio controller===&lt;br /&gt;
This script should be put into the shoutcast - radio controller device.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// Script:  Shoutcast - radio controller&lt;br /&gt;
// Version: 0.3 - released 10-2-2011&lt;br /&gt;
// Logic Scripts (Flennan Roffo)&lt;br /&gt;
// (c) 2010 - Flennan Roffo (Logic Scripts)&lt;br /&gt;
// &lt;br /&gt;
// This script is a remake of a couple of similar script:&lt;br /&gt;
// + LandOwnersRadio V2.0 by Scripter Coba  (( menu driven / notecard config script to select the radio station and sets parcel music url ))&lt;br /&gt;
// + Raven radio infoboard by Jamie Otis    (( worked at the basis of sis service [sis.slserver.com/sis.php] used Xy text display         ))&lt;br /&gt;
// + currentPlaying by Darkie Minotaur      (( used the /7.html info to fetch current song title info, displayed as float text            ))&lt;br /&gt;
//&lt;br /&gt;
// Purpose:&lt;br /&gt;
// * Sets the parcel audio URL and displays the channel info&lt;br /&gt;
// * Uses Xytext to display the info.&lt;br /&gt;
// * Fetches song title info from the shoutcast url&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.1 release&lt;br /&gt;
// * On/Off option&lt;br /&gt;
// * Allows multiple menus (if options per menu &amp;gt; 12) using a prev/next button&lt;br /&gt;
// * Checks if your url is well-formatted&lt;br /&gt;
// * Will delete genres for which no stations exist&lt;br /&gt;
// * Will skip stations that have same url and same genre (you can however have an identical station url under different genres).&lt;br /&gt;
// * New notecard format&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.2 release&lt;br /&gt;
// * Configurable button text&lt;br /&gt;
// * Gets parcel URL and automatically sets the genre/station and on/off status accordingly (&amp;lt;-- doesn&#039;t work)&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Update -- 0.3 release&lt;br /&gt;
// * Fixed bug (only first station in genre displayed in menu)&lt;br /&gt;
// * Auto reset script when config card updated&lt;br /&gt;
// Notes:&lt;br /&gt;
// * Expects url to be in the format: &amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;, where &amp;lt;ip&amp;gt; has the format: xxx.xxx.xxx.xxx  (0 &amp;lt;= xxx &amp;lt;= 255) &lt;br /&gt;
// * Deletes entries in category (genre) for which no stations are configured with notice.&lt;br /&gt;
// * Skips stations which have identical url AND same category (genre).&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Upcoming release -- 0.4&lt;br /&gt;
// * Will add functions for remote controller(s) and remote display(s) using llRegionSay to communicate over a channel.&lt;br /&gt;
// * Should relax on the constraints about the input format of URL&#039;s (currently requires that URL has format: xxx.xxx.xxx.xxx/yyyy).&lt;br /&gt;
// * Fix button placement. Control buttons should be on the first line.&lt;br /&gt;
// * Implement script reset on change of owner.&lt;br /&gt;
// * Permit station to be put under multiple genres, using a comma-seperated list of genres in the section [STATION]&lt;br /&gt;
//   (currently this is only possible by duplicating the entire line and change the genre.)&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Future plans:&lt;br /&gt;
// * Individual user preferences that can be stored on seperate note cards. A user has access to his own list of genres and stations and the system available genres/stations.&lt;br /&gt;
// * Feature for accessing online playlists (M3U, PLS, other formats) to play a list of songs provided by that playlist.&lt;br /&gt;
// * User provided url.&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// BUGS &amp;amp; FEATURE REQUESTS&lt;br /&gt;
//&lt;br /&gt;
// Please inform the author, Logic Scripts (flennan.roffo) about any bugs or annoyances.&lt;br /&gt;
// Feature requests can also be submitted to the author.&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// LICENCE INFO&lt;br /&gt;
//&lt;br /&gt;
// This program is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string info_notecard=&amp;quot;Radio Control info&amp;quot;;              ///////    EDITABLE  \\\\\\&lt;br /&gt;
string config_notecard=&amp;quot;Radio Control config&amp;quot;;          ///////    EDITABLE  \\\\\\&lt;br /&gt;
string comment_char=&amp;quot;#&amp;quot;;                                ///////    EDITABLE  \\\\\\&lt;br /&gt;
list sep_char_list= [&amp;quot;|&amp;quot;];                              ///////    EDITABLE  \\\\\\&lt;br /&gt;
float update_time=5.0;                                  ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string no_title_info=&amp;quot;(no title info available)&amp;quot;;       ///////    EDITABLE  \\\\\\&lt;br /&gt;
&lt;br /&gt;
// not used currently - for showing info on current song title elsewhere in the region&lt;br /&gt;
integer broadcast_channel=-1234;                        ///////    EDITABLE  \\\\\\ &lt;br /&gt;
&lt;br /&gt;
// Buttons&lt;br /&gt;
&lt;br /&gt;
string button_MAIN = &amp;quot;MAIN&amp;quot;;&lt;br /&gt;
string button_HELP = &amp;quot;HELP&amp;quot;;&lt;br /&gt;
string button_NEXT = &amp;quot;&amp;gt;&amp;gt;&amp;quot;;&lt;br /&gt;
string button_PREV = &amp;quot;&amp;lt;&amp;lt;&amp;quot;;&lt;br /&gt;
string button_ON   = &amp;quot;ON&amp;quot;;&lt;br /&gt;
string button_OFF  = &amp;quot;OFF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// List of categories (=genres)&lt;br /&gt;
&lt;br /&gt;
list category_list=[];&lt;br /&gt;
&lt;br /&gt;
// List of stations. KEEP THESE LISTS IN SYNCH!&lt;br /&gt;
&lt;br /&gt;
list station_category=[];&lt;br /&gt;
list station_name=[];&lt;br /&gt;
list station_desc=[];&lt;br /&gt;
list station_url=[];&lt;br /&gt;
&lt;br /&gt;
// Last song title played&lt;br /&gt;
string last_title_info=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
integer radio_status=0;    // 0 - OFF   1 - ON&lt;br /&gt;
string parcel_url=&amp;quot;&amp;quot;;&lt;br /&gt;
integer lineno=0;&lt;br /&gt;
key reqid=NULL_KEY;&lt;br /&gt;
key httpreq_id=NULL_KEY;&lt;br /&gt;
integer config_error=FALSE;&lt;br /&gt;
integer flag;&lt;br /&gt;
integer section=0;&lt;br /&gt;
&lt;br /&gt;
// Access values. Note that users who are banned can not access the device even when access is public&lt;br /&gt;
integer owner_access=TRUE;&lt;br /&gt;
integer group_access=FALSE;&lt;br /&gt;
integer public_access=TRUE;&lt;br /&gt;
list banned_keys=[];&lt;br /&gt;
&lt;br /&gt;
// Channels for menu and user input&lt;br /&gt;
integer menu_channel;&lt;br /&gt;
integer listen_handle;&lt;br /&gt;
&lt;br /&gt;
// Menu&lt;br /&gt;
integer menu_type=0;         // 0 - Main menu (genres)   1 - Station menu (stations)&lt;br /&gt;
integer menu_num=0;          // When more menu options need to be selectable then can be displayed on a menu (12), this is the menu number - menu number 0 is the first menu.&lt;br /&gt;
&lt;br /&gt;
// Genres and stations&lt;br /&gt;
&lt;br /&gt;
integer category_index=0;    // Current index in category_list  (genre)&lt;br /&gt;
integer station_index=0;     // Current index in station_*      (station)&lt;br /&gt;
&lt;br /&gt;
integer num_categories=0;&lt;br /&gt;
integer num_stations=0;&lt;br /&gt;
&lt;br /&gt;
// Make request for title info using HTTP request&lt;br /&gt;
retrieve_titelinfo()&lt;br /&gt;
{&lt;br /&gt;
    string url=llList2String(station_url,station_index);&lt;br /&gt;
    httpreq_id=llHTTPRequest(url + &amp;quot;/7.html  HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n&amp;quot;,[],&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Display a line on an Xytext device linked in&lt;br /&gt;
display_line(string line, string message)&lt;br /&gt;
{&lt;br /&gt;
    // Setup XYtext Variables&lt;br /&gt;
    integer DISPLAY_STRING      = 204000; &lt;br /&gt;
//    integer DISPLAY_EXTENDED    = 204001;     (not used)&lt;br /&gt;
//    integer REMAP_INDICES       = 204002;     (not used) &lt;br /&gt;
//    integer RESET_INDICES       = 204003;     (not used)&lt;br /&gt;
//    integer SET_CELL_INFO       = 204004;     (not used)&lt;br /&gt;
//    integer SET_FONT_TEXTURE    = 204005;     (not used)&lt;br /&gt;
//    integer SET_THICKNESS       = 204006;     (not used)&lt;br /&gt;
//    integer SET_COLOR           = 204007;     (not used)&lt;br /&gt;
&lt;br /&gt;
    llMessageLinked(LINK_SET,DISPLAY_STRING,message,line);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Clear the Xytext display&lt;br /&gt;
clear_display() &lt;br /&gt;
{&lt;br /&gt;
    // Clears the display&lt;br /&gt;
    display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio Station ID&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;2&amp;quot;,&amp;quot;Music Genre....&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;3&amp;quot;,&amp;quot;Now Playing....&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Make a menu / dialog&lt;br /&gt;
make_menu(key id)&lt;br /&gt;
{&lt;br /&gt;
     menu_channel=random_channel();&lt;br /&gt;
&lt;br /&gt;
    if (radio_status == 0)&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        llDialog(id,&amp;quot;Menu: Status\n\nRadio is OFF&amp;quot;, [ &amp;quot;ON&amp;quot;, &amp;quot;HELP&amp;quot; ],menu_channel);&lt;br /&gt;
    }&lt;br /&gt;
    else &lt;br /&gt;
    {&lt;br /&gt;
        if (menu_type ==0)&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Genres&amp;quot;, category_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Stations\nGenre: &amp;quot; + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (listen_handle != 0)    llListenRemove(listen_handle);&lt;br /&gt;
    listen_handle=llListen(menu_channel,&amp;quot;&amp;quot;,id,&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Make the menu option list for menu: catagories (genres)&lt;br /&gt;
list category_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
&lt;br /&gt;
    if (len &amp;gt; 9)   // If more then 9 items (12 minus the 3 buttons for MAIN/HELP and PREV, NEXT)&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;   // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc. &lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt; last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
&lt;br /&gt;
             while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_HELP;&lt;br /&gt;
             else&lt;br /&gt;
                 menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_OFF;&lt;br /&gt;
             else&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num != last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;       &lt;br /&gt;
        }            &lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
        menu+=(list)button_OFF;&lt;br /&gt;
        menu+=(list)button_HELP;&lt;br /&gt;
    }        &lt;br /&gt;
    &lt;br /&gt;
    return menu;    // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns the number of stations in a certain category&lt;br /&gt;
integer stations_in_category(integer cat)&lt;br /&gt;
{&lt;br /&gt;
    integer count=0;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
    string category=llList2String(category_list,cat);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (category == llList2String(category_list,i))&lt;br /&gt;
            count++;&lt;br /&gt;
&lt;br /&gt;
    return count;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Not used currently -- to fix button placement&lt;br /&gt;
list order_buttons(list buttons)&lt;br /&gt;
{&lt;br /&gt;
    integer offset;&lt;br /&gt;
    list fixt;&lt;br /&gt;
    integer flag=0;&lt;br /&gt;
&lt;br /&gt;
    while((offset = llGetListLength(buttons)))&lt;br /&gt;
    {&lt;br /&gt;
        if (offset &amp;gt; 3)&lt;br /&gt;
            flag=1;&lt;br /&gt;
        else&lt;br /&gt;
            flag=0;&lt;br /&gt;
&lt;br /&gt;
        fixt += llList2List(buttons, offset = -3 * flag, -1);&lt;br /&gt;
        buttons = llDeleteSubList(buttons, offset, -1);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return fixt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns a list of station names in a certain category (genre)&lt;br /&gt;
list station_list(integer category)&lt;br /&gt;
{&lt;br /&gt;
    list s=[];&lt;br /&gt;
    integer i;&lt;br /&gt;
    string cname=llList2String(category_list,category_index);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; llGetListLength(station_name); i++)&lt;br /&gt;
        if (llList2String(station_category,i) == cname)&lt;br /&gt;
            s+=(list)llList2String(station_name,i);&lt;br /&gt;
&lt;br /&gt;
    return s;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns the list of stations for the station menu, depending on the submenu number&lt;br /&gt;
list station_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
    list stations=station_list(category_index);&lt;br /&gt;
    integer len=llGetListLength(stations);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
        &lt;br /&gt;
    if (len &amp;gt; 11)       // 12 - 1 for MAIN menu&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;&lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt;= last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
             integer last=9*num+8;&lt;br /&gt;
&lt;br /&gt;
             menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;gt; 0)&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;lt; last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;                      &lt;br /&gt;
&lt;br /&gt;
            if (len &amp;gt; last)&lt;br /&gt;
                len =last;&lt;br /&gt;
                &lt;br /&gt;
            while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(stations,len);&lt;br /&gt;
        }&lt;br /&gt;
    }            &lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(stations,len);&lt;br /&gt;
    }        &lt;br /&gt;
&lt;br /&gt;
    return menu; // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns whether av with key id has access&lt;br /&gt;
integer has_access(key id)&lt;br /&gt;
{&lt;br /&gt;
    if (llListFindList(banned_keys,(list)id) != -1)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    if (owner_access &amp;amp;&amp;amp; id == llGetOwner())&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (group_access &amp;amp;&amp;amp; llSameGroup(id))&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (public_access)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Gets a random channel -- uses a wide range of big negative channel numbers seldomly used&lt;br /&gt;
integer random_channel()&lt;br /&gt;
{&lt;br /&gt;
    integer min=-2147483647;&lt;br /&gt;
    integer max=-1000;&lt;br /&gt;
&lt;br /&gt;
    return (integer) (min + llFrand(max-min));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Check for the format of the url string  -- is very selective about url format&lt;br /&gt;
// expects:   xxx.xxx.xxx.xxx:xxxx    (ip adress in number notation with port adress)&lt;br /&gt;
// Next release will relax on this constraint.&lt;br /&gt;
integer check_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    integer pos=0;&lt;br /&gt;
&lt;br /&gt;
    if (llGetSubString(url,0,6) == &amp;quot;http://&amp;quot;)&lt;br /&gt;
        pos=7;        &lt;br /&gt;
    if (llGetSubString(url,0,7) == &amp;quot;https://&amp;quot;)&lt;br /&gt;
        pos=8;&lt;br /&gt;
&lt;br /&gt;
    if (pos==0)   return FALSE;&lt;br /&gt;
&lt;br /&gt;
    string str_ip_port=llGetSubString(url,pos,-1);&lt;br /&gt;
    list list_ip_port=llParseString2List(str_ip_port,[&amp;quot;:&amp;quot;],[]);                 // split in ip-adress and port&lt;br /&gt;
    list list_ip=llParseString2List(llList2String(list_ip_port,0),[&amp;quot;.&amp;quot;],[]);    // split ip-adress elements&lt;br /&gt;
&lt;br /&gt;
    if (llGetListLength(list_ip_port) != 2 || llGetListLength(list_ip) != 4)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer test;&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;4;i++)&lt;br /&gt;
    {&lt;br /&gt;
        test=llList2Integer(list_ip,i);&lt;br /&gt;
        if (llList2String(list_ip,i) != (string)test)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        if (test &amp;lt; 0 || test &amp;gt; 255)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    test=llList2Integer(list_ip_port,1);&lt;br /&gt;
    if (llList2String(list_ip_port,1) != (string)test)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns a true value depending on the first character in input - anything else is assumed false.&lt;br /&gt;
integer true_value(string input)&lt;br /&gt;
{&lt;br /&gt;
    string value=llToLower(llGetSubString(input,0,0));&lt;br /&gt;
&lt;br /&gt;
    if (value == &amp;quot;y&amp;quot; || value == &amp;quot;t&amp;quot; || value ==&amp;quot;1&amp;quot;)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Return if more input should be processed (if not at EOF) - sets ConfigError if any config error found. Reading config card stops at the first error.&lt;br /&gt;
integer process_line(string dataline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(dataline,STRING_TRIM);&lt;br /&gt;
    integer index=llSubStringIndex(line,comment_char);&lt;br /&gt;
    &lt;br /&gt;
    if (index==0)       // line starts with comment - ignore line&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (index!=-1)&lt;br /&gt;
        line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL);   // skip everything after comment_char and trim tail&lt;br /&gt;
&lt;br /&gt;
    if (line==&amp;quot;&amp;quot;)       // Ignore blank lines&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (llToLower(line) == &amp;quot;[access]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 1;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[banned]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 2;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[genre]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 3;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[station]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 4;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llGetSubString(line,0,0) == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; llGetSubString(line,-1,-1) == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: malformed section found at line &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
        config_error=TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: no section found on line: &amp;quot; + (string) lineno);&lt;br /&gt;
        config_error = TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    list breakup=llParseString2List(line,[&amp;quot;=&amp;quot;],[]);&lt;br /&gt;
    string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);&lt;br /&gt;
    string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);&lt;br /&gt;
&lt;br /&gt;
    if (section == 1)            // access&lt;br /&gt;
    {&lt;br /&gt;
        field=llToLower(field);&lt;br /&gt;
&lt;br /&gt;
        if (field==&amp;quot;owner&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            owner_access=true_value(values);                       &lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;group&amp;quot;)&lt;br /&gt;
        {    &lt;br /&gt;
            group_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;public&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            public_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: invalid option on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 2)         // ban list&lt;br /&gt;
    {&lt;br /&gt;
        key try=(key) field;&lt;br /&gt;
&lt;br /&gt;
        if (try)&lt;br /&gt;
        {&lt;br /&gt;
            banned_keys+=(list)((key) field);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 3)           // categories&lt;br /&gt;
    {&lt;br /&gt;
        if (llListFindList(category_list,(list)field) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            category_list+=(list)field;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;genre: &#039;&amp;quot; + field + &amp;quot;&#039; already entered; double entry skipped.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 4)            // stations&lt;br /&gt;
    {&lt;br /&gt;
        list parse=llParseString2List(line,sep_char_list, []);&lt;br /&gt;
        string category=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);&lt;br /&gt;
        string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);&lt;br /&gt;
    &lt;br /&gt;
        if (!available_category(category))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: unknown genre on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (check_url(url))&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                num_stations++;&lt;br /&gt;
                station_category+=(list)category;&lt;br /&gt;
                station_name+=(list)name;&lt;br /&gt;
                station_desc+=(list)desc;&lt;br /&gt;
                station_url+=(list)url;&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llWhisper(0,&amp;quot;This station is already entered under the same genre and same url and is skipped.\nStation: &amp;quot; + name + &amp;quot;\nGenre: &#039;&amp;quot; + category + &amp;quot;&#039;\nURL: &amp;quot; + url);&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: malformed url on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
     &lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Sets the parcel URL and updates the display&lt;br /&gt;
set_parcel_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    parcel_url=url;&lt;br /&gt;
    llSetParcelMusicURL(parcel_url);&lt;br /&gt;
&lt;br /&gt;
    if (parcel_url==&amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        clear_display();&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is OFF&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;station now set to &amp;quot; + llList2String(station_desc,station_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Station: &amp;quot; + llList2String(station_desc,station_index));&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;Genre  : &amp;quot; + llList2String(category_list,category_index));&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;Now playing.....&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns if a category (genre) exists.&lt;br /&gt;
integer available_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;len;i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(category_list,i)))&lt;br /&gt;
            return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns if a category (genre) is empty (i.e. there are no stations for this catagory (genre))&lt;br /&gt;
integer empty_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(station_category,i)))&lt;br /&gt;
            return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Removes categories (genres) for which no station is known.&lt;br /&gt;
skip_empty_categories()&lt;br /&gt;
{&lt;br /&gt;
    integer i=0;&lt;br /&gt;
&lt;br /&gt;
    while (i&amp;lt;llGetListLength(category_list))&lt;br /&gt;
    {&lt;br /&gt;
        if (empty_category(llList2String(category_list,i)))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;Warning: Genre &#039;&amp;quot; + llList2String(category_list,i) + &amp;quot;&#039; contains no stations and is deleted.&amp;quot;);&lt;br /&gt;
            category_list=llDeleteSubList(category_list,i,i);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            i++;&lt;br /&gt;
    }&lt;br /&gt;
            &lt;br /&gt;
    num_categories=llGetListLength(category_list);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state default&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        flag=FALSE;&lt;br /&gt;
        lineno=0;&lt;br /&gt;
        config_error=FALSE;&lt;br /&gt;
        num_stations=0;&lt;br /&gt;
        num_categories=0;&lt;br /&gt;
        radio_status=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(config_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
           reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
           llWhisper(0, &amp;quot;Reading config notecard...&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;1&amp;quot;,&amp;quot;Reading configuration.&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;2&amp;quot;,&amp;quot;Wait....&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;No config notecard &#039;&amp;quot; +  config_notecard + &amp;quot;&#039; present.&amp;quot;);&lt;br /&gt;
            state offline;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (reqid==id)&lt;br /&gt;
        {        &lt;br /&gt;
            if (data==EOF)&lt;br /&gt;
            {&lt;br /&gt;
                skip_empty_categories();&lt;br /&gt;
                llWhisper(0,&amp;quot;Configuration ok.\n&amp;quot; + (string)num_categories + &amp;quot; genres and &amp;quot; + (string)num_stations + &amp;quot; stations.&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Configuration OK&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;2&amp;quot;,&amp;quot;Genres  : &amp;quot; + (string)num_categories);&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Stations: &amp;quot; + (string)num_stations);&lt;br /&gt;
                state menu;&lt;br /&gt;
            }&lt;br /&gt;
            else &lt;br /&gt;
            {&lt;br /&gt;
                if (process_line(data))&lt;br /&gt;
                    reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
                else if (config_error)&lt;br /&gt;
                {&lt;br /&gt;
                    llWhisper(0,&amp;quot;errors found in configuration. please correct them.&amp;quot;);&lt;br /&gt;
                    state offline;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state offline&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state offline&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;Reset on owner touch or when notecard updated.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    touch_start(integer t)&lt;br /&gt;
    {&lt;br /&gt;
        if (llDetectedKey(0)==llGetOwner())&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY &amp;amp;&amp;amp; flag)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state menu&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state menu&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        listen_handle=0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        if (param &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
        key toucher=llDetectedKey(0);&lt;br /&gt;
&lt;br /&gt;
        if (has_access(toucher))&lt;br /&gt;
        {&lt;br /&gt;
            make_menu(toucher);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;sorry, no access.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    listen(integer chan, string name,key id,string msg)&lt;br /&gt;
    {&lt;br /&gt;
        integer index;&lt;br /&gt;
&lt;br /&gt;
        if (menu_type == 0)          // main menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_ON)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=1;&lt;br /&gt;
                set_parcel_url(parcel_url);               &lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is ON&amp;quot;);&lt;br /&gt;
                menu_num=0;&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned on.&amp;quot;);&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=0;&lt;br /&gt;
                set_parcel_url(&amp;quot;&amp;quot;);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned off.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
                {&lt;br /&gt;
                    llGiveInventory(id,info_notecard);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                    llWhisper(0,&amp;quot;sorry, help not available.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (radio_status == 1)&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(category_list, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: genre not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    category_index=index;&lt;br /&gt;
                    llWhisper(0,&amp;quot;Genre now set to &amp;quot; + llList2String(category_list,category_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
                    menu_type=1;&lt;br /&gt;
                    menu_num=0;&lt;br /&gt;
                    make_menu(id);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (menu_type == 1 &amp;amp;&amp;amp; radio_status == 1)     // station menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(station_name, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: station not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    station_index=index;&lt;br /&gt;
                    string new_url=llList2String(station_url,station_index);&lt;br /&gt;
&lt;br /&gt;
                    if (new_url != parcel_url)&lt;br /&gt;
                    {&lt;br /&gt;
                        set_parcel_url(new_url);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        retrieve_titelinfo();&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_response(key id, integer status, list meta, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == httpreq_id)&lt;br /&gt;
        {&lt;br /&gt;
            if (status == 200)&lt;br /&gt;
            {&lt;br /&gt;
                string feed = llGetSubString(body,llSubStringIndex(body, &amp;quot;&amp;lt;body&amp;gt;&amp;quot;) + llStringLength(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;), llSubStringIndex(body,&amp;quot;&amp;lt;/body&amp;gt;&amp;quot;) - 1);&lt;br /&gt;
                list feed_list = llParseString2List(feed,[&amp;quot;,&amp;quot;],[]);&lt;br /&gt;
                string current_title_info= llList2String(feed_list,6);&lt;br /&gt;
                integer length = llGetListLength(feed_list);&lt;br /&gt;
        &lt;br /&gt;
                if(llList2String(feed_list,7))&lt;br /&gt;
                {&lt;br /&gt;
                    integer a = 7;&lt;br /&gt;
                    for(; a&amp;lt;length; ++a)&lt;br /&gt;
                    {&lt;br /&gt;
                        current_title_info += &amp;quot;, &amp;quot; + llList2String(feed_list,a);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
         &lt;br /&gt;
                if (current_title_info != last_title_info)&lt;br /&gt;
                {&lt;br /&gt;
                    last_title_info = current_title_info;&lt;br /&gt;
                    display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + current_title_info);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + no_title_info);&lt;br /&gt;
            }&lt;br /&gt;
        }    &lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY &amp;amp;&amp;amp; flag)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
// end of script&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
===Notecard format===&lt;br /&gt;
Example notecard&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# New format Shoutcast - radio controller config notecard&lt;br /&gt;
# The format is divided in 4 sections:&lt;br /&gt;
# 1 - Access configuration&lt;br /&gt;
# 2 - Ban list (keys)&lt;br /&gt;
# 3 - Categories  (same as genres)&lt;br /&gt;
# 4 - Station info (category, name, desc, url)&lt;br /&gt;
# The &#039;#&#039; character defines the start of a comment and can be anywhere on a line. &lt;br /&gt;
# Everything after the &#039;#&#039; incuding the &#039;#&#039; itself is ignored.&lt;br /&gt;
# Case is not important (but information on display will show as entered)&lt;br /&gt;
# Spaces before and/or after fields are trimmed.&lt;br /&gt;
# Empty lines are ignored.&lt;br /&gt;
&lt;br /&gt;
[ACCESS]&lt;br /&gt;
owner=yes       # yes, true,1      means owner has access. everything else not.&lt;br /&gt;
group=yes       #  ,,  ,,  ,,      means group has acess.    ,,        ,,   ,,&lt;br /&gt;
public=yes      #  ,,  ,,  ,,      means public has access.  ,,        ,,   ,, &lt;br /&gt;
&lt;br /&gt;
[BANNED]&lt;br /&gt;
# keys of banned residents&lt;br /&gt;
&lt;br /&gt;
[GENRE]&lt;br /&gt;
# genre name -- Use short genre names as the the length of menu buttons is short!&lt;br /&gt;
Hard Rock&lt;br /&gt;
Classic Rock&lt;br /&gt;
Oldies&lt;br /&gt;
Rap/Urban&lt;br /&gt;
Comedy&lt;br /&gt;
News&lt;br /&gt;
Dance&lt;br /&gt;
Country&lt;br /&gt;
Gothic&lt;br /&gt;
# etc.&lt;br /&gt;
[STATION]&lt;br /&gt;
# Shoutcast radio stations&lt;br /&gt;
# Use a &#039;|&#039; between each field - don&#039;t mind spaces before and after fields, they will be trimmed&lt;br /&gt;
# field1:genre, field2:station name, field3: station description, field4: station http://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt; or https://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;&lt;br /&gt;
# Note that genre must match case-insensitive a value previously entered in section [GENRE]&lt;br /&gt;
Classic Rock    | Absolute         |    Absolute Radio                  | http://205.188.215.226:8018&lt;br /&gt;
# etc.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===TODO===&lt;br /&gt;
&lt;br /&gt;
Planned for upcoming release 0.4:&lt;br /&gt;
* Add a llRegionSay to broadcast the &amp;lt;station&amp;gt;|&amp;lt;genre&amp;gt;|&amp;lt;current songtitle&amp;gt;|&amp;lt;url&amp;gt; to the region and add a script that displays that info on a remote Xytext board. (for use with a remote controller and/or remote display board anywhere in the region/parcel)&lt;br /&gt;
* llResetScript on owner change&lt;br /&gt;
* Relax on URL format&lt;br /&gt;
* Allow multiple genres per station&lt;/div&gt;</description>
			<pubDate>Thu, 10 Feb 2011 00:54:55 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)</comments>
		</item>
		<item>
			<title>Shoutcast - radio controller v0.3 (remake of similar scripts)</title>
			<link>https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133921</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133921</guid>
			<description>&lt;p&gt;Flennan Roffo: /* Shoutcast - radio controller */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}}&lt;br /&gt;
=Shoutcast - radio controller=&lt;br /&gt;
This script controls a shoutcast radio receiver and lets you select the stations that you configured on a notecard. Menu driven. Output of station description, genre and current song title using Xy text.&lt;br /&gt;
Credits for this script go to previous developers of similar scripts:&lt;br /&gt;
* Scripter Coba who wrote the LandOwnersRadio (V2.0) script. Menu driven / notecard config script to select genre and station to set parcel music url.&lt;br /&gt;
* Jamie Otis who wrote the Raven radio infoboard script. Shows what song is playing by fetching info using the sis.slserver.info/sis.php service (now offline). Display on Xytext.&lt;br /&gt;
* Darkie Minotaur who wrote the currentPlaying script. Shows what song is currently playing by fetching info from the /7.html shoutcast page.&lt;br /&gt;
&lt;br /&gt;
Although this script is based upon similar functionality as provided in these scripts, this script is not simply a merge/copy of those scripts, but a complete make-over. &lt;br /&gt;
I use my own notecard format and processing of notecard info, and own menu system.&lt;br /&gt;
&lt;br /&gt;
==Versions==&lt;br /&gt;
&lt;br /&gt;
Current version: v0.3 released 10-2-2011&lt;br /&gt;
&lt;br /&gt;
==Main script==&lt;br /&gt;
&lt;br /&gt;
This script should be put into the shoutcast - radio controller device.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// Script:  Shoutcast - radio controller&lt;br /&gt;
// Version: 0.3 - released 10-2-2011&lt;br /&gt;
// Logic Scripts (Flennan Roffo)&lt;br /&gt;
// (c) 2010 - Flennan Roffo (Logic Scripts)&lt;br /&gt;
// &lt;br /&gt;
// This script is a remake of a couple of similar script:&lt;br /&gt;
// + LandOwnersRadio V2.0 by Scripter Coba  (( menu driven / notecard config script to select the radio station and sets parcel music url ))&lt;br /&gt;
// + Raven radio infoboard by Jamie Otis    (( worked at the basis of sis service [sis.slserver.com/sis.php] used Xy text display         ))&lt;br /&gt;
// + currentPlaying by Darkie Minotaur      (( used the /7.html info to fetch current song title info, displayed as float text            ))&lt;br /&gt;
//&lt;br /&gt;
// Purpose:&lt;br /&gt;
// * Sets the parcel audio URL and displays the channel info&lt;br /&gt;
// * Uses Xytext to display the info.&lt;br /&gt;
// * Fetches song title info from the shoutcast url&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.1 release&lt;br /&gt;
// * On/Off option&lt;br /&gt;
// * Allows multiple menus (if options per menu &amp;gt; 12) using a prev/next button&lt;br /&gt;
// * Checks if your url is well-formatted&lt;br /&gt;
// * Will delete genres for which no stations exist&lt;br /&gt;
// * Will skip stations that have same url and same genre (you can however have an identical station url under different genres).&lt;br /&gt;
// * New notecard format&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.2 release&lt;br /&gt;
// * Configurable button text&lt;br /&gt;
// * Gets parcel URL and automatically sets the genre/station and on/off status accordingly (&amp;lt;-- doesn&#039;t work)&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Update -- 0.3 release&lt;br /&gt;
// * Fixed bug (only first station in genre displayed in menu)&lt;br /&gt;
// * Auto reset script when config card updated&lt;br /&gt;
// Notes:&lt;br /&gt;
// * Expects url to be in the format: &amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;, where &amp;lt;ip&amp;gt; has the format: xxx.xxx.xxx.xxx&lt;br /&gt;
// * Deletes entries in category (genre) for which no stations are configured with notice.&lt;br /&gt;
// * Skips stations which have identical URL AND same category (genre).&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Upcoming release -- 0.4&lt;br /&gt;
// * Will add functions for remote controller(s) and remote display(s) using llRegionSay to communicate over a channel.&lt;br /&gt;
// * Should relax on the constraints about the input format of URL&#039;s (currently requires that URL has format: xxx.xxx.xxx.xxx/yyyy)&lt;br /&gt;
// * Fix button placement&lt;br /&gt;
// * Implement script reset on change of owner&lt;br /&gt;
// * Permit station to be put under multiple genres, using a comma-seperated list of genres in the section [STATION]&lt;br /&gt;
//   (currently this is only possible by duplicating the entire line and change the genre.)&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// BUGS &amp;amp; FEATURE REQUESTS&lt;br /&gt;
//&lt;br /&gt;
// Please inform the author, Logic Scripts (flennan.roffo) about any bugs or annoyances.&lt;br /&gt;
// Feature requests can also be submitted to the author.&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// LICENCE INFO&lt;br /&gt;
//&lt;br /&gt;
// This program is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string info_notecard=&amp;quot;Radio Control info&amp;quot;;              ///////    EDITABLE  \\\\\\&lt;br /&gt;
string config_notecard=&amp;quot;Radio Control config&amp;quot;;          ///////    EDITABLE  \\\\\\&lt;br /&gt;
string comment_char=&amp;quot;#&amp;quot;;                                ///////    EDITABLE  \\\\\\&lt;br /&gt;
list sep_char_list= [&amp;quot;|&amp;quot;];                              ///////    EDITABLE  \\\\\\&lt;br /&gt;
float update_time=5.0;                                  ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string no_title_info=&amp;quot;(no title info available)&amp;quot;;       ///////    EDITABLE  \\\\\\&lt;br /&gt;
&lt;br /&gt;
// not used currently - for showing info on current song title elsewhere in the region&lt;br /&gt;
integer broadcast_channel=-1234;                        ///////    EDITABLE  \\\\\\ &lt;br /&gt;
&lt;br /&gt;
// Buttons&lt;br /&gt;
&lt;br /&gt;
string button_MAIN = &amp;quot;MAIN&amp;quot;;&lt;br /&gt;
string button_HELP = &amp;quot;HELP&amp;quot;;&lt;br /&gt;
string button_NEXT = &amp;quot;&amp;gt;&amp;gt;&amp;quot;;&lt;br /&gt;
string button_PREV = &amp;quot;&amp;lt;&amp;lt;&amp;quot;;&lt;br /&gt;
string button_ON   = &amp;quot;ON&amp;quot;;&lt;br /&gt;
string button_OFF  = &amp;quot;OFF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// List of categories (=genres)&lt;br /&gt;
&lt;br /&gt;
list category_list=[];&lt;br /&gt;
&lt;br /&gt;
// List of stations. KEEP THESE LISTS IN SYNCH!&lt;br /&gt;
&lt;br /&gt;
list station_category=[];&lt;br /&gt;
list station_name=[];&lt;br /&gt;
list station_desc=[];&lt;br /&gt;
list station_url=[];&lt;br /&gt;
&lt;br /&gt;
// Last song title played&lt;br /&gt;
string last_title_info=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
integer radio_status=0;    // 0 - OFF   1 - ON&lt;br /&gt;
string parcel_url=&amp;quot;&amp;quot;;&lt;br /&gt;
integer lineno=0;&lt;br /&gt;
key reqid=NULL_KEY;&lt;br /&gt;
key httpreq_id=NULL_KEY;&lt;br /&gt;
integer config_error=FALSE;&lt;br /&gt;
integer flag;&lt;br /&gt;
integer section=0;&lt;br /&gt;
&lt;br /&gt;
// Access values. Note that users who are banned can not access the device even when access is public&lt;br /&gt;
integer owner_access=TRUE;&lt;br /&gt;
integer group_access=FALSE;&lt;br /&gt;
integer public_access=TRUE;&lt;br /&gt;
list banned_keys=[];&lt;br /&gt;
&lt;br /&gt;
// Channels for menu and user input&lt;br /&gt;
integer menu_channel;&lt;br /&gt;
integer listen_handle;&lt;br /&gt;
&lt;br /&gt;
// Menu&lt;br /&gt;
integer menu_type=0;         // 0 - Main menu (genres)   1 - Station menu (stations)&lt;br /&gt;
integer menu_num=0;          // When more menu options need to be selectable then can be displayed on a menu (12), this is the menu number - menu number 0 is the first menu.&lt;br /&gt;
&lt;br /&gt;
// Genres and stations&lt;br /&gt;
&lt;br /&gt;
integer category_index=0;    // Current index in category_list  (genre)&lt;br /&gt;
integer station_index=0;     // Current index in station_*      (station)&lt;br /&gt;
&lt;br /&gt;
integer num_categories=0;&lt;br /&gt;
integer num_stations=0;&lt;br /&gt;
&lt;br /&gt;
// Make request for title info using HTTP request&lt;br /&gt;
retrieve_titelinfo()&lt;br /&gt;
{&lt;br /&gt;
    string url=llList2String(station_url,station_index);&lt;br /&gt;
    httpreq_id=llHTTPRequest(url + &amp;quot;/7.html  HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n&amp;quot;,[],&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Display a line on an Xytext device linked in&lt;br /&gt;
display_line(string line, string message)&lt;br /&gt;
{&lt;br /&gt;
    // Setup XYtext Variables&lt;br /&gt;
    integer DISPLAY_STRING      = 204000; &lt;br /&gt;
//    integer DISPLAY_EXTENDED    = 204001;     (not used)&lt;br /&gt;
//    integer REMAP_INDICES       = 204002;     (not used) &lt;br /&gt;
//    integer RESET_INDICES       = 204003;     (not used)&lt;br /&gt;
//    integer SET_CELL_INFO       = 204004;     (not used)&lt;br /&gt;
//    integer SET_FONT_TEXTURE    = 204005;     (not used)&lt;br /&gt;
//    integer SET_THICKNESS       = 204006;     (not used)&lt;br /&gt;
//    integer SET_COLOR           = 204007;     (not used)&lt;br /&gt;
&lt;br /&gt;
    llMessageLinked(LINK_SET,DISPLAY_STRING,message,line);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Clear the Xytext display&lt;br /&gt;
clear_display() &lt;br /&gt;
{&lt;br /&gt;
    // Clears the display&lt;br /&gt;
    display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio Station ID&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;2&amp;quot;,&amp;quot;Music Genre....&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;3&amp;quot;,&amp;quot;Now Playing....&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Make a menu / dialog&lt;br /&gt;
make_menu(key id)&lt;br /&gt;
{&lt;br /&gt;
     menu_channel=random_channel();&lt;br /&gt;
&lt;br /&gt;
    if (radio_status == 0)&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        llDialog(id,&amp;quot;Menu: Status\n\nRadio is OFF&amp;quot;, [ &amp;quot;ON&amp;quot;, &amp;quot;HELP&amp;quot; ],menu_channel);&lt;br /&gt;
    }&lt;br /&gt;
    else &lt;br /&gt;
    {&lt;br /&gt;
        if (menu_type ==0)&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Genres&amp;quot;, category_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Stations\nGenre: &amp;quot; + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (listen_handle != 0)    llListenRemove(listen_handle);&lt;br /&gt;
    listen_handle=llListen(menu_channel,&amp;quot;&amp;quot;,id,&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Make the menu option list for menu: catagories (genres)&lt;br /&gt;
list category_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
&lt;br /&gt;
    if (len &amp;gt; 9)   // If more then 9 items (12 minus the 3 buttons for MAIN/HELP and PREV, NEXT)&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;   // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc. &lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt; last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
&lt;br /&gt;
             while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_HELP;&lt;br /&gt;
             else&lt;br /&gt;
                 menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_OFF;&lt;br /&gt;
             else&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num != last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;       &lt;br /&gt;
        }            &lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
        menu+=(list)button_OFF;&lt;br /&gt;
        menu+=(list)button_HELP;&lt;br /&gt;
    }        &lt;br /&gt;
    &lt;br /&gt;
    return menu;    // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns the number of stations in a certain category&lt;br /&gt;
integer stations_in_category(integer cat)&lt;br /&gt;
{&lt;br /&gt;
    integer count=0;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
    string category=llList2String(category_list,cat);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (category == llList2String(category_list,i))&lt;br /&gt;
            count++;&lt;br /&gt;
&lt;br /&gt;
    return count;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Not used currently -- to fix button placement&lt;br /&gt;
list order_buttons(list buttons)&lt;br /&gt;
{&lt;br /&gt;
    integer offset;&lt;br /&gt;
    list fixt;&lt;br /&gt;
    integer flag=0;&lt;br /&gt;
&lt;br /&gt;
    while((offset = llGetListLength(buttons)))&lt;br /&gt;
    {&lt;br /&gt;
        if (offset &amp;gt; 3)&lt;br /&gt;
            flag=1;&lt;br /&gt;
        else&lt;br /&gt;
            flag=0;&lt;br /&gt;
&lt;br /&gt;
        fixt += llList2List(buttons, offset = -3 * flag, -1);&lt;br /&gt;
        buttons = llDeleteSubList(buttons, offset, -1);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return fixt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns a list of station names in a certain category (genre)&lt;br /&gt;
list station_list(integer category)&lt;br /&gt;
{&lt;br /&gt;
    list s=[];&lt;br /&gt;
    integer i;&lt;br /&gt;
    string cname=llList2String(category_list,category_index);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; llGetListLength(station_name); i++)&lt;br /&gt;
        if (llList2String(station_category,i) == cname)&lt;br /&gt;
            s+=(list)llList2String(station_name,i);&lt;br /&gt;
&lt;br /&gt;
    return s;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns the list of stations for the station menu, depending on the submenu number&lt;br /&gt;
list station_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
    list stations=station_list(category_index);&lt;br /&gt;
    integer len=llGetListLength(stations);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
        &lt;br /&gt;
    if (len &amp;gt; 11)       // 12 - 1 for MAIN menu&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;&lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt;= last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
             integer last=9*num+8;&lt;br /&gt;
&lt;br /&gt;
             menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;gt; 0)&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;lt; last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;                      &lt;br /&gt;
&lt;br /&gt;
            if (len &amp;gt; last)&lt;br /&gt;
                len =last;&lt;br /&gt;
                &lt;br /&gt;
            while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(stations,len);&lt;br /&gt;
        }&lt;br /&gt;
    }            &lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(stations,len);&lt;br /&gt;
    }        &lt;br /&gt;
&lt;br /&gt;
    return menu; // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns whether av with key id has access&lt;br /&gt;
integer has_access(key id)&lt;br /&gt;
{&lt;br /&gt;
    if (llListFindList(banned_keys,(list)id) != -1)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    if (owner_access &amp;amp;&amp;amp; id == llGetOwner())&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (group_access &amp;amp;&amp;amp; llSameGroup(id))&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (public_access)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Gets a random channel -- uses a wide range of big negative channel numbers seldomly used&lt;br /&gt;
integer random_channel()&lt;br /&gt;
{&lt;br /&gt;
    integer min=-2147483647;&lt;br /&gt;
    integer max=-1000;&lt;br /&gt;
&lt;br /&gt;
    return (integer) (min + llFrand(max-min));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Check for the format of the url string  -- is very selective about url format&lt;br /&gt;
// expects:   xxx.xxx.xxx.xxx:xxxx    (ip adress in number notation with port adress)&lt;br /&gt;
// Next release will relax on this constraint.&lt;br /&gt;
integer check_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    integer pos=0;&lt;br /&gt;
&lt;br /&gt;
    if (llGetSubString(url,0,6) == &amp;quot;http://&amp;quot;)&lt;br /&gt;
        pos=7;        &lt;br /&gt;
    if (llGetSubString(url,0,7) == &amp;quot;https://&amp;quot;)&lt;br /&gt;
        pos=8;&lt;br /&gt;
&lt;br /&gt;
    if (pos==0)   return FALSE;&lt;br /&gt;
&lt;br /&gt;
    string str_ip_port=llGetSubString(url,pos,-1);&lt;br /&gt;
    list list_ip_port=llParseString2List(str_ip_port,[&amp;quot;:&amp;quot;],[]);                 // split in ip-adress and port&lt;br /&gt;
    list list_ip=llParseString2List(llList2String(list_ip_port,0),[&amp;quot;.&amp;quot;],[]);    // split ip-adress elements&lt;br /&gt;
&lt;br /&gt;
    if (llGetListLength(list_ip_port) != 2 || llGetListLength(list_ip) != 4)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer test;&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;4;i++)&lt;br /&gt;
    {&lt;br /&gt;
        test=llList2Integer(list_ip,i);&lt;br /&gt;
        if (llList2String(list_ip,i) != (string)test)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        if (test &amp;lt; 0 || test &amp;gt; 255)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    test=llList2Integer(list_ip_port,1);&lt;br /&gt;
    if (llList2String(list_ip_port,1) != (string)test)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns a true value depending on the first character in input - anything else is assumed false.&lt;br /&gt;
integer true_value(string input)&lt;br /&gt;
{&lt;br /&gt;
    string value=llToLower(llGetSubString(input,0,0));&lt;br /&gt;
&lt;br /&gt;
    if (value == &amp;quot;y&amp;quot; || value == &amp;quot;t&amp;quot; || value ==&amp;quot;1&amp;quot;)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Return if more input should be processed (if not at EOF) - sets ConfigError if any config error found. Reading config card stops at the first error.&lt;br /&gt;
integer process_line(string dataline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(dataline,STRING_TRIM);&lt;br /&gt;
    integer index=llSubStringIndex(line,comment_char);&lt;br /&gt;
    &lt;br /&gt;
    if (index==0)       // line starts with comment - ignore line&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (index!=-1)&lt;br /&gt;
        line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL);   // skip everything after comment_char and trim tail&lt;br /&gt;
&lt;br /&gt;
    if (line==&amp;quot;&amp;quot;)       // Ignore blank lines&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (llToLower(line) == &amp;quot;[access]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 1;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[banned]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 2;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[genre]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 3;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[station]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 4;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llGetSubString(line,0,0) == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; llGetSubString(line,-1,-1) == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: malformed section found at line &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
        config_error=TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: no section found on line: &amp;quot; + (string) lineno);&lt;br /&gt;
        config_error = TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    list breakup=llParseString2List(line,[&amp;quot;=&amp;quot;],[]);&lt;br /&gt;
    string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);&lt;br /&gt;
    string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);&lt;br /&gt;
&lt;br /&gt;
    if (section == 1)            // access&lt;br /&gt;
    {&lt;br /&gt;
        field=llToLower(field);&lt;br /&gt;
&lt;br /&gt;
        if (field==&amp;quot;owner&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            owner_access=true_value(values);                       &lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;group&amp;quot;)&lt;br /&gt;
        {    &lt;br /&gt;
            group_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;public&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            public_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: invalid option on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 2)         // ban list&lt;br /&gt;
    {&lt;br /&gt;
        key try=(key) field;&lt;br /&gt;
&lt;br /&gt;
        if (try)&lt;br /&gt;
        {&lt;br /&gt;
            banned_keys+=(list)((key) field);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 3)           // categories&lt;br /&gt;
    {&lt;br /&gt;
        if (llListFindList(category_list,(list)field) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            category_list+=(list)field;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;genre: &#039;&amp;quot; + field + &amp;quot;&#039; already entered; double entry skipped.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 4)            // stations&lt;br /&gt;
    {&lt;br /&gt;
        list parse=llParseString2List(line,sep_char_list, []);&lt;br /&gt;
        string category=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);&lt;br /&gt;
        string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);&lt;br /&gt;
    &lt;br /&gt;
        if (!available_category(category))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: unknown genre on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (check_url(url))&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                num_stations++;&lt;br /&gt;
                station_category+=(list)category;&lt;br /&gt;
                station_name+=(list)name;&lt;br /&gt;
                station_desc+=(list)desc;&lt;br /&gt;
                station_url+=(list)url;&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llWhisper(0,&amp;quot;This station is already entered under the same genre and same url and is skipped.\nStation: &amp;quot; + name + &amp;quot;\nGenre: &#039;&amp;quot; + category + &amp;quot;&#039;\nURL: &amp;quot; + url);&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: malformed url on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
     &lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Sets the parcel URL and updates the display&lt;br /&gt;
set_parcel_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    parcel_url=url;&lt;br /&gt;
    llSetParcelMusicURL(parcel_url);&lt;br /&gt;
&lt;br /&gt;
    if (parcel_url==&amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        clear_display();&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is OFF&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;station now set to &amp;quot; + llList2String(station_desc,station_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Station: &amp;quot; + llList2String(station_desc,station_index));&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;Genre  : &amp;quot; + llList2String(category_list,category_index));&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;Now playing.....&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns if a category (genre) exists.&lt;br /&gt;
integer available_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;len;i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(category_list,i)))&lt;br /&gt;
            return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns if a category (genre) is empty (i.e. there are no stations for this catagory (genre))&lt;br /&gt;
integer empty_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(station_category,i)))&lt;br /&gt;
            return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Removes categories (genres) for which no station is known.&lt;br /&gt;
skip_empty_categories()&lt;br /&gt;
{&lt;br /&gt;
    integer i=0;&lt;br /&gt;
&lt;br /&gt;
    while (i&amp;lt;llGetListLength(category_list))&lt;br /&gt;
    {&lt;br /&gt;
        if (empty_category(llList2String(category_list,i)))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;Warning: Genre &#039;&amp;quot; + llList2String(category_list,i) + &amp;quot;&#039; contains no stations and is deleted.&amp;quot;);&lt;br /&gt;
            category_list=llDeleteSubList(category_list,i,i);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            i++;&lt;br /&gt;
    }&lt;br /&gt;
            &lt;br /&gt;
    num_categories=llGetListLength(category_list);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state default&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        flag=FALSE;&lt;br /&gt;
        lineno=0;&lt;br /&gt;
        config_error=FALSE;&lt;br /&gt;
        num_stations=0;&lt;br /&gt;
        num_categories=0;&lt;br /&gt;
        radio_status=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(config_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
           reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
           llWhisper(0, &amp;quot;Reading config notecard...&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;1&amp;quot;,&amp;quot;Reading configuration.&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;2&amp;quot;,&amp;quot;Wait....&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;No config notecard &#039;&amp;quot; +  config_notecard + &amp;quot;&#039; present.&amp;quot;);&lt;br /&gt;
            state offline;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (reqid==id)&lt;br /&gt;
        {        &lt;br /&gt;
            if (data==EOF)&lt;br /&gt;
            {&lt;br /&gt;
                skip_empty_categories();&lt;br /&gt;
                llWhisper(0,&amp;quot;Configuration ok.\n&amp;quot; + (string)num_categories + &amp;quot; genres and &amp;quot; + (string)num_stations + &amp;quot; stations.&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Configuration OK&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;2&amp;quot;,&amp;quot;Genres  : &amp;quot; + (string)num_categories);&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Stations: &amp;quot; + (string)num_stations);&lt;br /&gt;
                state menu;&lt;br /&gt;
            }&lt;br /&gt;
            else &lt;br /&gt;
            {&lt;br /&gt;
                if (process_line(data))&lt;br /&gt;
                    reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
                else if (config_error)&lt;br /&gt;
                {&lt;br /&gt;
                    llWhisper(0,&amp;quot;errors found in configuration. please correct them.&amp;quot;);&lt;br /&gt;
                    state offline;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state offline&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state offline&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;Reset on owner touch or when notecard updated.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    touch_start(integer t)&lt;br /&gt;
    {&lt;br /&gt;
        if (llDetectedKey(0)==llGetOwner())&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY &amp;amp;&amp;amp; flag)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state menu&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state menu&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        listen_handle=0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        if (param &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
        key toucher=llDetectedKey(0);&lt;br /&gt;
&lt;br /&gt;
        if (has_access(toucher))&lt;br /&gt;
        {&lt;br /&gt;
            make_menu(toucher);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;sorry, no access.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    listen(integer chan, string name,key id,string msg)&lt;br /&gt;
    {&lt;br /&gt;
        integer index;&lt;br /&gt;
&lt;br /&gt;
        if (menu_type == 0)          // main menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_ON)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=1;&lt;br /&gt;
                set_parcel_url(parcel_url);               &lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is ON&amp;quot;);&lt;br /&gt;
                menu_num=0;&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned on.&amp;quot;);&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=0;&lt;br /&gt;
                set_parcel_url(&amp;quot;&amp;quot;);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned off.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
                {&lt;br /&gt;
                    llGiveInventory(id,info_notecard);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                    llWhisper(0,&amp;quot;sorry, help not available.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (radio_status == 1)&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(category_list, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: genre not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    category_index=index;&lt;br /&gt;
                    llWhisper(0,&amp;quot;Genre now set to &amp;quot; + llList2String(category_list,category_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
                    menu_type=1;&lt;br /&gt;
                    menu_num=0;&lt;br /&gt;
                    make_menu(id);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (menu_type == 1 &amp;amp;&amp;amp; radio_status == 1)     // station menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(station_name, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: station not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    station_index=index;&lt;br /&gt;
                    string new_url=llList2String(station_url,station_index);&lt;br /&gt;
&lt;br /&gt;
                    if (new_url != parcel_url)&lt;br /&gt;
                    {&lt;br /&gt;
                        set_parcel_url(new_url);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        retrieve_titelinfo();&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_response(key id, integer status, list meta, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == httpreq_id)&lt;br /&gt;
        {&lt;br /&gt;
            if (status == 200)&lt;br /&gt;
            {&lt;br /&gt;
                string feed = llGetSubString(body,llSubStringIndex(body, &amp;quot;&amp;lt;body&amp;gt;&amp;quot;) + llStringLength(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;), llSubStringIndex(body,&amp;quot;&amp;lt;/body&amp;gt;&amp;quot;) - 1);&lt;br /&gt;
                list feed_list = llParseString2List(feed,[&amp;quot;,&amp;quot;],[]);&lt;br /&gt;
                string current_title_info= llList2String(feed_list,6);&lt;br /&gt;
                integer length = llGetListLength(feed_list);&lt;br /&gt;
        &lt;br /&gt;
                if(llList2String(feed_list,7))&lt;br /&gt;
                {&lt;br /&gt;
                    integer a = 7;&lt;br /&gt;
                    for(; a&amp;lt;length; ++a)&lt;br /&gt;
                    {&lt;br /&gt;
                        current_title_info += &amp;quot;, &amp;quot; + llList2String(feed_list,a);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
         &lt;br /&gt;
                if (current_title_info != last_title_info)&lt;br /&gt;
                {&lt;br /&gt;
                    last_title_info = current_title_info;&lt;br /&gt;
                    display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + current_title_info);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + no_title_info);&lt;br /&gt;
            }&lt;br /&gt;
        }    &lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY &amp;amp;&amp;amp; flag)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
// end of script&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
===Notecard format===&lt;br /&gt;
Example notecard&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# New format Shoutcast - radio controller config notecard&lt;br /&gt;
# The format is divided in 4 sections:&lt;br /&gt;
# 1 - Access configuration&lt;br /&gt;
# 2 - Ban list (keys)&lt;br /&gt;
# 3 - Categories  (same as genres)&lt;br /&gt;
# 4 - Station info (category, name, desc, url)&lt;br /&gt;
# The &#039;#&#039; character defines the start of a comment and can be anywhere on a line. &lt;br /&gt;
# Everything after the &#039;#&#039; incuding the &#039;#&#039; itself is ignored.&lt;br /&gt;
# Case is not important (but information on display will show as entered)&lt;br /&gt;
# Spaces before and/or after fields are trimmed.&lt;br /&gt;
# Empty lines are ignored.&lt;br /&gt;
&lt;br /&gt;
[ACCESS]&lt;br /&gt;
owner=yes       # yes, true,1      means owner has access. everything else not.&lt;br /&gt;
group=yes       #  ,,  ,,  ,,      means group has acess.    ,,        ,,   ,,&lt;br /&gt;
public=yes      #  ,,  ,,  ,,      means public has access.  ,,        ,,   ,, &lt;br /&gt;
&lt;br /&gt;
[BANNED]&lt;br /&gt;
# keys of banned residents&lt;br /&gt;
&lt;br /&gt;
[GENRE]&lt;br /&gt;
# genre name -- Use short genre names as the the length of menu buttons is short!&lt;br /&gt;
Hard Rock&lt;br /&gt;
Classic Rock&lt;br /&gt;
Oldies&lt;br /&gt;
Rap/Urban&lt;br /&gt;
Comedy&lt;br /&gt;
News&lt;br /&gt;
Dance&lt;br /&gt;
Country&lt;br /&gt;
Gothic&lt;br /&gt;
# etc.&lt;br /&gt;
[STATION]&lt;br /&gt;
# Shoutcast radio stations&lt;br /&gt;
# Use a &#039;|&#039; between each field - don&#039;t mind spaces before and after fields, they will be trimmed&lt;br /&gt;
# field1:genre, field2:station name, field3: station description, field4: station http://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt; or https://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;&lt;br /&gt;
# Note that genre must match case-insensitive a value previously entered in section [GENRE]&lt;br /&gt;
Classic Rock    | Absolute         |    Absolute Radio                  | http://205.188.215.226:8018&lt;br /&gt;
# etc.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===TODO===&lt;br /&gt;
&lt;br /&gt;
Planned for upcoming release 0.4:&lt;br /&gt;
* Add a llRegionSay to broadcast the &amp;lt;station&amp;gt;|&amp;lt;genre&amp;gt;|&amp;lt;current songtitle&amp;gt;|&amp;lt;url&amp;gt; to the region and add a script that displays that info on a remote Xytext board. (for use with a remote controller and/or remote display board anywhere in the region/parcel)&lt;br /&gt;
* llResetScript on owner change&lt;br /&gt;
* Relax on URL format&lt;br /&gt;
* Allow multiple genres per station&lt;/div&gt;</description>
			<pubDate>Thu, 10 Feb 2011 00:43:37 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)</comments>
		</item>
		<item>
			<title>Shoutcast - radio controller v0.3 (remake of similar scripts)</title>
			<link>https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133920</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133920</guid>
			<description>&lt;p&gt;Flennan Roffo: /* Main script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}}&lt;br /&gt;
=Shoutcast - radio controller=&lt;br /&gt;
This script controls a shoutcast radio receiver and lets you select the stations that you configured on a notecard. Menu driven. Output of station description, genre and current song title using Xy text.&lt;br /&gt;
&lt;br /&gt;
==Versions==&lt;br /&gt;
&lt;br /&gt;
Current version: v0.3 released 10-2-2011&lt;br /&gt;
&lt;br /&gt;
==Main script==&lt;br /&gt;
&lt;br /&gt;
This script should be put into the shoutcast - radio controller device.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// Script:  Shoutcast - radio controller&lt;br /&gt;
// Version: 0.3 - released 10-2-2011&lt;br /&gt;
// Logic Scripts (Flennan Roffo)&lt;br /&gt;
// (c) 2010 - Flennan Roffo (Logic Scripts)&lt;br /&gt;
// &lt;br /&gt;
// This script is a remake of a couple of similar script:&lt;br /&gt;
// + LandOwnersRadio V2.0 by Scripter Coba  (( menu driven / notecard config script to select the radio station and sets parcel music url ))&lt;br /&gt;
// + Raven radio infoboard by Jamie Otis    (( worked at the basis of sis service [sis.slserver.com/sis.php] used Xy text display         ))&lt;br /&gt;
// + currentPlaying by Darkie Minotaur      (( used the /7.html info to fetch current song title info, displayed as float text            ))&lt;br /&gt;
//&lt;br /&gt;
// Purpose:&lt;br /&gt;
// * Sets the parcel audio URL and displays the channel info&lt;br /&gt;
// * Uses Xytext to display the info.&lt;br /&gt;
// * Fetches song title info from the shoutcast url&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.1 release&lt;br /&gt;
// * On/Off option&lt;br /&gt;
// * Allows multiple menus (if options per menu &amp;gt; 12) using a prev/next button&lt;br /&gt;
// * Checks if your url is well-formatted&lt;br /&gt;
// * Will delete genres for which no stations exist&lt;br /&gt;
// * Will skip stations that have same url and same genre (you can however have an identical station url under different genres).&lt;br /&gt;
// * New notecard format&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.2 release&lt;br /&gt;
// * Configurable button text&lt;br /&gt;
// * Gets parcel URL and automatically sets the genre/station and on/off status accordingly (&amp;lt;-- doesn&#039;t work)&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Update -- 0.3 release&lt;br /&gt;
// * Fixed bug (only first station in genre displayed in menu)&lt;br /&gt;
// * Auto reset script when config card updated&lt;br /&gt;
// Notes:&lt;br /&gt;
// * Expects url to be in the format: &amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;, where &amp;lt;ip&amp;gt; has the format: xxx.xxx.xxx.xxx&lt;br /&gt;
// * Deletes entries in category (genre) for which no stations are configured with notice.&lt;br /&gt;
// * Skips stations which have identical URL AND same category (genre).&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Upcoming release -- 0.4&lt;br /&gt;
// * Will add functions for remote controller(s) and remote display(s) using llRegionSay to communicate over a channel.&lt;br /&gt;
// * Should relax on the constraints about the input format of URL&#039;s (currently requires that URL has format: xxx.xxx.xxx.xxx/yyyy)&lt;br /&gt;
// * Fix button placement&lt;br /&gt;
// * Implement script reset on change of owner&lt;br /&gt;
// * Permit station to be put under multiple genres, using a comma-seperated list of genres in the section [STATION]&lt;br /&gt;
//   (currently this is only possible by duplicating the entire line and change the genre.)&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// BUGS &amp;amp; FEATURE REQUESTS&lt;br /&gt;
//&lt;br /&gt;
// Please inform the author, Logic Scripts (flennan.roffo) about any bugs or annoyances.&lt;br /&gt;
// Feature requests can also be submitted to the author.&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// LICENCE INFO&lt;br /&gt;
//&lt;br /&gt;
// This program is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string info_notecard=&amp;quot;Radio Control info&amp;quot;;              ///////    EDITABLE  \\\\\\&lt;br /&gt;
string config_notecard=&amp;quot;Radio Control config&amp;quot;;          ///////    EDITABLE  \\\\\\&lt;br /&gt;
string comment_char=&amp;quot;#&amp;quot;;                                ///////    EDITABLE  \\\\\\&lt;br /&gt;
list sep_char_list= [&amp;quot;|&amp;quot;];                              ///////    EDITABLE  \\\\\\&lt;br /&gt;
float update_time=5.0;                                  ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string no_title_info=&amp;quot;(no title info available)&amp;quot;;       ///////    EDITABLE  \\\\\\&lt;br /&gt;
&lt;br /&gt;
// not used currently - for showing info on current song title elsewhere in the region&lt;br /&gt;
integer broadcast_channel=-1234;                        ///////    EDITABLE  \\\\\\ &lt;br /&gt;
&lt;br /&gt;
// Buttons&lt;br /&gt;
&lt;br /&gt;
string button_MAIN = &amp;quot;MAIN&amp;quot;;&lt;br /&gt;
string button_HELP = &amp;quot;HELP&amp;quot;;&lt;br /&gt;
string button_NEXT = &amp;quot;&amp;gt;&amp;gt;&amp;quot;;&lt;br /&gt;
string button_PREV = &amp;quot;&amp;lt;&amp;lt;&amp;quot;;&lt;br /&gt;
string button_ON   = &amp;quot;ON&amp;quot;;&lt;br /&gt;
string button_OFF  = &amp;quot;OFF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// List of categories (=genres)&lt;br /&gt;
&lt;br /&gt;
list category_list=[];&lt;br /&gt;
&lt;br /&gt;
// List of stations. KEEP THESE LISTS IN SYNCH!&lt;br /&gt;
&lt;br /&gt;
list station_category=[];&lt;br /&gt;
list station_name=[];&lt;br /&gt;
list station_desc=[];&lt;br /&gt;
list station_url=[];&lt;br /&gt;
&lt;br /&gt;
// Last song title played&lt;br /&gt;
string last_title_info=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
integer radio_status=0;    // 0 - OFF   1 - ON&lt;br /&gt;
string parcel_url=&amp;quot;&amp;quot;;&lt;br /&gt;
integer lineno=0;&lt;br /&gt;
key reqid=NULL_KEY;&lt;br /&gt;
key httpreq_id=NULL_KEY;&lt;br /&gt;
integer config_error=FALSE;&lt;br /&gt;
integer flag;&lt;br /&gt;
integer section=0;&lt;br /&gt;
&lt;br /&gt;
// Access values. Note that users who are banned can not access the device even when access is public&lt;br /&gt;
integer owner_access=TRUE;&lt;br /&gt;
integer group_access=FALSE;&lt;br /&gt;
integer public_access=TRUE;&lt;br /&gt;
list banned_keys=[];&lt;br /&gt;
&lt;br /&gt;
// Channels for menu and user input&lt;br /&gt;
integer menu_channel;&lt;br /&gt;
integer listen_handle;&lt;br /&gt;
&lt;br /&gt;
// Menu&lt;br /&gt;
integer menu_type=0;         // 0 - Main menu (genres)   1 - Station menu (stations)&lt;br /&gt;
integer menu_num=0;          // When more menu options need to be selectable then can be displayed on a menu (12), this is the menu number - menu number 0 is the first menu.&lt;br /&gt;
&lt;br /&gt;
// Genres and stations&lt;br /&gt;
&lt;br /&gt;
integer category_index=0;    // Current index in category_list  (genre)&lt;br /&gt;
integer station_index=0;     // Current index in station_*      (station)&lt;br /&gt;
&lt;br /&gt;
integer num_categories=0;&lt;br /&gt;
integer num_stations=0;&lt;br /&gt;
&lt;br /&gt;
// Make request for title info using HTTP request&lt;br /&gt;
retrieve_titelinfo()&lt;br /&gt;
{&lt;br /&gt;
    string url=llList2String(station_url,station_index);&lt;br /&gt;
    httpreq_id=llHTTPRequest(url + &amp;quot;/7.html  HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n&amp;quot;,[],&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Display a line on an Xytext device linked in&lt;br /&gt;
display_line(string line, string message)&lt;br /&gt;
{&lt;br /&gt;
    // Setup XYtext Variables&lt;br /&gt;
    integer DISPLAY_STRING      = 204000; &lt;br /&gt;
//    integer DISPLAY_EXTENDED    = 204001;     (not used)&lt;br /&gt;
//    integer REMAP_INDICES       = 204002;     (not used) &lt;br /&gt;
//    integer RESET_INDICES       = 204003;     (not used)&lt;br /&gt;
//    integer SET_CELL_INFO       = 204004;     (not used)&lt;br /&gt;
//    integer SET_FONT_TEXTURE    = 204005;     (not used)&lt;br /&gt;
//    integer SET_THICKNESS       = 204006;     (not used)&lt;br /&gt;
//    integer SET_COLOR           = 204007;     (not used)&lt;br /&gt;
&lt;br /&gt;
    llMessageLinked(LINK_SET,DISPLAY_STRING,message,line);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Clear the Xytext display&lt;br /&gt;
clear_display() &lt;br /&gt;
{&lt;br /&gt;
    // Clears the display&lt;br /&gt;
    display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio Station ID&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;2&amp;quot;,&amp;quot;Music Genre....&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;3&amp;quot;,&amp;quot;Now Playing....&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Make a menu / dialog&lt;br /&gt;
make_menu(key id)&lt;br /&gt;
{&lt;br /&gt;
     menu_channel=random_channel();&lt;br /&gt;
&lt;br /&gt;
    if (radio_status == 0)&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        llDialog(id,&amp;quot;Menu: Status\n\nRadio is OFF&amp;quot;, [ &amp;quot;ON&amp;quot;, &amp;quot;HELP&amp;quot; ],menu_channel);&lt;br /&gt;
    }&lt;br /&gt;
    else &lt;br /&gt;
    {&lt;br /&gt;
        if (menu_type ==0)&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Genres&amp;quot;, category_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Stations\nGenre: &amp;quot; + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (listen_handle != 0)    llListenRemove(listen_handle);&lt;br /&gt;
    listen_handle=llListen(menu_channel,&amp;quot;&amp;quot;,id,&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Make the menu option list for menu: catagories (genres)&lt;br /&gt;
list category_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
&lt;br /&gt;
    if (len &amp;gt; 9)   // If more then 9 items (12 minus the 3 buttons for MAIN/HELP and PREV, NEXT)&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;   // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc. &lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt; last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
&lt;br /&gt;
             while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_HELP;&lt;br /&gt;
             else&lt;br /&gt;
                 menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_OFF;&lt;br /&gt;
             else&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num != last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;       &lt;br /&gt;
        }            &lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
        menu+=(list)button_OFF;&lt;br /&gt;
        menu+=(list)button_HELP;&lt;br /&gt;
    }        &lt;br /&gt;
    &lt;br /&gt;
    return menu;    // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns the number of stations in a certain category&lt;br /&gt;
integer stations_in_category(integer cat)&lt;br /&gt;
{&lt;br /&gt;
    integer count=0;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
    string category=llList2String(category_list,cat);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (category == llList2String(category_list,i))&lt;br /&gt;
            count++;&lt;br /&gt;
&lt;br /&gt;
    return count;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Not used currently -- to fix button placement&lt;br /&gt;
list order_buttons(list buttons)&lt;br /&gt;
{&lt;br /&gt;
    integer offset;&lt;br /&gt;
    list fixt;&lt;br /&gt;
    integer flag=0;&lt;br /&gt;
&lt;br /&gt;
    while((offset = llGetListLength(buttons)))&lt;br /&gt;
    {&lt;br /&gt;
        if (offset &amp;gt; 3)&lt;br /&gt;
            flag=1;&lt;br /&gt;
        else&lt;br /&gt;
            flag=0;&lt;br /&gt;
&lt;br /&gt;
        fixt += llList2List(buttons, offset = -3 * flag, -1);&lt;br /&gt;
        buttons = llDeleteSubList(buttons, offset, -1);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return fixt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns a list of station names in a certain category (genre)&lt;br /&gt;
list station_list(integer category)&lt;br /&gt;
{&lt;br /&gt;
    list s=[];&lt;br /&gt;
    integer i;&lt;br /&gt;
    string cname=llList2String(category_list,category_index);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; llGetListLength(station_name); i++)&lt;br /&gt;
        if (llList2String(station_category,i) == cname)&lt;br /&gt;
            s+=(list)llList2String(station_name,i);&lt;br /&gt;
&lt;br /&gt;
    return s;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns the list of stations for the station menu, depending on the submenu number&lt;br /&gt;
list station_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
    list stations=station_list(category_index);&lt;br /&gt;
    integer len=llGetListLength(stations);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
        &lt;br /&gt;
    if (len &amp;gt; 11)       // 12 - 1 for MAIN menu&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;&lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt;= last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
             integer last=9*num+8;&lt;br /&gt;
&lt;br /&gt;
             menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;gt; 0)&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;lt; last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;                      &lt;br /&gt;
&lt;br /&gt;
            if (len &amp;gt; last)&lt;br /&gt;
                len =last;&lt;br /&gt;
                &lt;br /&gt;
            while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(stations,len);&lt;br /&gt;
        }&lt;br /&gt;
    }            &lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(stations,len);&lt;br /&gt;
    }        &lt;br /&gt;
&lt;br /&gt;
    return menu; // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns whether av with key id has access&lt;br /&gt;
integer has_access(key id)&lt;br /&gt;
{&lt;br /&gt;
    if (llListFindList(banned_keys,(list)id) != -1)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    if (owner_access &amp;amp;&amp;amp; id == llGetOwner())&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (group_access &amp;amp;&amp;amp; llSameGroup(id))&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (public_access)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Gets a random channel -- uses a wide range of big negative channel numbers seldomly used&lt;br /&gt;
integer random_channel()&lt;br /&gt;
{&lt;br /&gt;
    integer min=-2147483647;&lt;br /&gt;
    integer max=-1000;&lt;br /&gt;
&lt;br /&gt;
    return (integer) (min + llFrand(max-min));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Check for the format of the url string  -- is very selective about url format&lt;br /&gt;
// expects:   xxx.xxx.xxx.xxx:xxxx    (ip adress in number notation with port adress)&lt;br /&gt;
// Next release will relax on this constraint.&lt;br /&gt;
integer check_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    integer pos=0;&lt;br /&gt;
&lt;br /&gt;
    if (llGetSubString(url,0,6) == &amp;quot;http://&amp;quot;)&lt;br /&gt;
        pos=7;        &lt;br /&gt;
    if (llGetSubString(url,0,7) == &amp;quot;https://&amp;quot;)&lt;br /&gt;
        pos=8;&lt;br /&gt;
&lt;br /&gt;
    if (pos==0)   return FALSE;&lt;br /&gt;
&lt;br /&gt;
    string str_ip_port=llGetSubString(url,pos,-1);&lt;br /&gt;
    list list_ip_port=llParseString2List(str_ip_port,[&amp;quot;:&amp;quot;],[]);                 // split in ip-adress and port&lt;br /&gt;
    list list_ip=llParseString2List(llList2String(list_ip_port,0),[&amp;quot;.&amp;quot;],[]);    // split ip-adress elements&lt;br /&gt;
&lt;br /&gt;
    if (llGetListLength(list_ip_port) != 2 || llGetListLength(list_ip) != 4)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer test;&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;4;i++)&lt;br /&gt;
    {&lt;br /&gt;
        test=llList2Integer(list_ip,i);&lt;br /&gt;
        if (llList2String(list_ip,i) != (string)test)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        if (test &amp;lt; 0 || test &amp;gt; 255)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    test=llList2Integer(list_ip_port,1);&lt;br /&gt;
    if (llList2String(list_ip_port,1) != (string)test)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns a true value depending on the first character in input - anything else is assumed false.&lt;br /&gt;
integer true_value(string input)&lt;br /&gt;
{&lt;br /&gt;
    string value=llToLower(llGetSubString(input,0,0));&lt;br /&gt;
&lt;br /&gt;
    if (value == &amp;quot;y&amp;quot; || value == &amp;quot;t&amp;quot; || value ==&amp;quot;1&amp;quot;)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Return if more input should be processed (if not at EOF) - sets ConfigError if any config error found. Reading config card stops at the first error.&lt;br /&gt;
integer process_line(string dataline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(dataline,STRING_TRIM);&lt;br /&gt;
    integer index=llSubStringIndex(line,comment_char);&lt;br /&gt;
    &lt;br /&gt;
    if (index==0)       // line starts with comment - ignore line&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (index!=-1)&lt;br /&gt;
        line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL);   // skip everything after comment_char and trim tail&lt;br /&gt;
&lt;br /&gt;
    if (line==&amp;quot;&amp;quot;)       // Ignore blank lines&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (llToLower(line) == &amp;quot;[access]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 1;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[banned]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 2;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[genre]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 3;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[station]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 4;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llGetSubString(line,0,0) == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; llGetSubString(line,-1,-1) == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: malformed section found at line &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
        config_error=TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: no section found on line: &amp;quot; + (string) lineno);&lt;br /&gt;
        config_error = TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    list breakup=llParseString2List(line,[&amp;quot;=&amp;quot;],[]);&lt;br /&gt;
    string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);&lt;br /&gt;
    string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);&lt;br /&gt;
&lt;br /&gt;
    if (section == 1)            // access&lt;br /&gt;
    {&lt;br /&gt;
        field=llToLower(field);&lt;br /&gt;
&lt;br /&gt;
        if (field==&amp;quot;owner&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            owner_access=true_value(values);                       &lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;group&amp;quot;)&lt;br /&gt;
        {    &lt;br /&gt;
            group_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;public&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            public_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: invalid option on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 2)         // ban list&lt;br /&gt;
    {&lt;br /&gt;
        key try=(key) field;&lt;br /&gt;
&lt;br /&gt;
        if (try)&lt;br /&gt;
        {&lt;br /&gt;
            banned_keys+=(list)((key) field);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 3)           // categories&lt;br /&gt;
    {&lt;br /&gt;
        if (llListFindList(category_list,(list)field) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            category_list+=(list)field;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;genre: &#039;&amp;quot; + field + &amp;quot;&#039; already entered; double entry skipped.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 4)            // stations&lt;br /&gt;
    {&lt;br /&gt;
        list parse=llParseString2List(line,sep_char_list, []);&lt;br /&gt;
        string category=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);&lt;br /&gt;
        string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);&lt;br /&gt;
    &lt;br /&gt;
        if (!available_category(category))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: unknown genre on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (check_url(url))&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                num_stations++;&lt;br /&gt;
                station_category+=(list)category;&lt;br /&gt;
                station_name+=(list)name;&lt;br /&gt;
                station_desc+=(list)desc;&lt;br /&gt;
                station_url+=(list)url;&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llWhisper(0,&amp;quot;This station is already entered under the same genre and same url and is skipped.\nStation: &amp;quot; + name + &amp;quot;\nGenre: &#039;&amp;quot; + category + &amp;quot;&#039;\nURL: &amp;quot; + url);&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: malformed url on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
     &lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Sets the parcel URL and updates the display&lt;br /&gt;
set_parcel_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    parcel_url=url;&lt;br /&gt;
    llSetParcelMusicURL(parcel_url);&lt;br /&gt;
&lt;br /&gt;
    if (parcel_url==&amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        clear_display();&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is OFF&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;station now set to &amp;quot; + llList2String(station_desc,station_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Station: &amp;quot; + llList2String(station_desc,station_index));&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;Genre  : &amp;quot; + llList2String(category_list,category_index));&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;Now playing.....&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns if a category (genre) exists.&lt;br /&gt;
integer available_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;len;i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(category_list,i)))&lt;br /&gt;
            return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns if a category (genre) is empty (i.e. there are no stations for this catagory (genre))&lt;br /&gt;
integer empty_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(station_category,i)))&lt;br /&gt;
            return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Removes categories (genres) for which no station is known.&lt;br /&gt;
skip_empty_categories()&lt;br /&gt;
{&lt;br /&gt;
    integer i=0;&lt;br /&gt;
&lt;br /&gt;
    while (i&amp;lt;llGetListLength(category_list))&lt;br /&gt;
    {&lt;br /&gt;
        if (empty_category(llList2String(category_list,i)))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;Warning: Genre &#039;&amp;quot; + llList2String(category_list,i) + &amp;quot;&#039; contains no stations and is deleted.&amp;quot;);&lt;br /&gt;
            category_list=llDeleteSubList(category_list,i,i);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            i++;&lt;br /&gt;
    }&lt;br /&gt;
            &lt;br /&gt;
    num_categories=llGetListLength(category_list);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state default&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        flag=FALSE;&lt;br /&gt;
        lineno=0;&lt;br /&gt;
        config_error=FALSE;&lt;br /&gt;
        num_stations=0;&lt;br /&gt;
        num_categories=0;&lt;br /&gt;
        radio_status=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(config_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
           reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
           llWhisper(0, &amp;quot;Reading config notecard...&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;1&amp;quot;,&amp;quot;Reading configuration.&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;2&amp;quot;,&amp;quot;Wait....&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;No config notecard &#039;&amp;quot; +  config_notecard + &amp;quot;&#039; present.&amp;quot;);&lt;br /&gt;
            state offline;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (reqid==id)&lt;br /&gt;
        {        &lt;br /&gt;
            if (data==EOF)&lt;br /&gt;
            {&lt;br /&gt;
                skip_empty_categories();&lt;br /&gt;
                llWhisper(0,&amp;quot;Configuration ok.\n&amp;quot; + (string)num_categories + &amp;quot; genres and &amp;quot; + (string)num_stations + &amp;quot; stations.&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Configuration OK&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;2&amp;quot;,&amp;quot;Genres  : &amp;quot; + (string)num_categories);&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Stations: &amp;quot; + (string)num_stations);&lt;br /&gt;
                state menu;&lt;br /&gt;
            }&lt;br /&gt;
            else &lt;br /&gt;
            {&lt;br /&gt;
                if (process_line(data))&lt;br /&gt;
                    reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
                else if (config_error)&lt;br /&gt;
                {&lt;br /&gt;
                    llWhisper(0,&amp;quot;errors found in configuration. please correct them.&amp;quot;);&lt;br /&gt;
                    state offline;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state offline&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state offline&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;Reset on owner touch or when notecard updated.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    touch_start(integer t)&lt;br /&gt;
    {&lt;br /&gt;
        if (llDetectedKey(0)==llGetOwner())&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY &amp;amp;&amp;amp; flag)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state menu&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state menu&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        listen_handle=0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        if (param &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
        key toucher=llDetectedKey(0);&lt;br /&gt;
&lt;br /&gt;
        if (has_access(toucher))&lt;br /&gt;
        {&lt;br /&gt;
            make_menu(toucher);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;sorry, no access.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    listen(integer chan, string name,key id,string msg)&lt;br /&gt;
    {&lt;br /&gt;
        integer index;&lt;br /&gt;
&lt;br /&gt;
        if (menu_type == 0)          // main menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_ON)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=1;&lt;br /&gt;
                set_parcel_url(parcel_url);               &lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is ON&amp;quot;);&lt;br /&gt;
                menu_num=0;&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned on.&amp;quot;);&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=0;&lt;br /&gt;
                set_parcel_url(&amp;quot;&amp;quot;);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned off.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
                {&lt;br /&gt;
                    llGiveInventory(id,info_notecard);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                    llWhisper(0,&amp;quot;sorry, help not available.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (radio_status == 1)&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(category_list, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: genre not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    category_index=index;&lt;br /&gt;
                    llWhisper(0,&amp;quot;Genre now set to &amp;quot; + llList2String(category_list,category_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
                    menu_type=1;&lt;br /&gt;
                    menu_num=0;&lt;br /&gt;
                    make_menu(id);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (menu_type == 1 &amp;amp;&amp;amp; radio_status == 1)     // station menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(station_name, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: station not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    station_index=index;&lt;br /&gt;
                    string new_url=llList2String(station_url,station_index);&lt;br /&gt;
&lt;br /&gt;
                    if (new_url != parcel_url)&lt;br /&gt;
                    {&lt;br /&gt;
                        set_parcel_url(new_url);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        retrieve_titelinfo();&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_response(key id, integer status, list meta, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == httpreq_id)&lt;br /&gt;
        {&lt;br /&gt;
            if (status == 200)&lt;br /&gt;
            {&lt;br /&gt;
                string feed = llGetSubString(body,llSubStringIndex(body, &amp;quot;&amp;lt;body&amp;gt;&amp;quot;) + llStringLength(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;), llSubStringIndex(body,&amp;quot;&amp;lt;/body&amp;gt;&amp;quot;) - 1);&lt;br /&gt;
                list feed_list = llParseString2List(feed,[&amp;quot;,&amp;quot;],[]);&lt;br /&gt;
                string current_title_info= llList2String(feed_list,6);&lt;br /&gt;
                integer length = llGetListLength(feed_list);&lt;br /&gt;
        &lt;br /&gt;
                if(llList2String(feed_list,7))&lt;br /&gt;
                {&lt;br /&gt;
                    integer a = 7;&lt;br /&gt;
                    for(; a&amp;lt;length; ++a)&lt;br /&gt;
                    {&lt;br /&gt;
                        current_title_info += &amp;quot;, &amp;quot; + llList2String(feed_list,a);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
         &lt;br /&gt;
                if (current_title_info != last_title_info)&lt;br /&gt;
                {&lt;br /&gt;
                    last_title_info = current_title_info;&lt;br /&gt;
                    display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + current_title_info);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + no_title_info);&lt;br /&gt;
            }&lt;br /&gt;
        }    &lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY &amp;amp;&amp;amp; flag)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
// end of script&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
===Notecard format===&lt;br /&gt;
Example notecard&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# New format Shoutcast - radio controller config notecard&lt;br /&gt;
# The format is divided in 4 sections:&lt;br /&gt;
# 1 - Access configuration&lt;br /&gt;
# 2 - Ban list (keys)&lt;br /&gt;
# 3 - Categories  (same as genres)&lt;br /&gt;
# 4 - Station info (category, name, desc, url)&lt;br /&gt;
# The &#039;#&#039; character defines the start of a comment and can be anywhere on a line. &lt;br /&gt;
# Everything after the &#039;#&#039; incuding the &#039;#&#039; itself is ignored.&lt;br /&gt;
# Case is not important (but information on display will show as entered)&lt;br /&gt;
# Spaces before and/or after fields are trimmed.&lt;br /&gt;
# Empty lines are ignored.&lt;br /&gt;
&lt;br /&gt;
[ACCESS]&lt;br /&gt;
owner=yes       # yes, true,1      means owner has access. everything else not.&lt;br /&gt;
group=yes       #  ,,  ,,  ,,      means group has acess.    ,,        ,,   ,,&lt;br /&gt;
public=yes      #  ,,  ,,  ,,      means public has access.  ,,        ,,   ,, &lt;br /&gt;
&lt;br /&gt;
[BANNED]&lt;br /&gt;
# keys of banned residents&lt;br /&gt;
&lt;br /&gt;
[GENRE]&lt;br /&gt;
# genre name -- Use short genre names as the the length of menu buttons is short!&lt;br /&gt;
Hard Rock&lt;br /&gt;
Classic Rock&lt;br /&gt;
Oldies&lt;br /&gt;
Rap/Urban&lt;br /&gt;
Comedy&lt;br /&gt;
News&lt;br /&gt;
Dance&lt;br /&gt;
Country&lt;br /&gt;
Gothic&lt;br /&gt;
# etc.&lt;br /&gt;
[STATION]&lt;br /&gt;
# Shoutcast radio stations&lt;br /&gt;
# Use a &#039;|&#039; between each field - don&#039;t mind spaces before and after fields, they will be trimmed&lt;br /&gt;
# field1:genre, field2:station name, field3: station description, field4: station http://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt; or https://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;&lt;br /&gt;
# Note that genre must match case-insensitive a value previously entered in section [GENRE]&lt;br /&gt;
Classic Rock    | Absolute         |    Absolute Radio                  | http://205.188.215.226:8018&lt;br /&gt;
# etc.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===TODO===&lt;br /&gt;
&lt;br /&gt;
Planned for upcoming release 0.4:&lt;br /&gt;
* Add a llRegionSay to broadcast the &amp;lt;station&amp;gt;|&amp;lt;genre&amp;gt;|&amp;lt;current songtitle&amp;gt;|&amp;lt;url&amp;gt; to the region and add a script that displays that info on a remote Xytext board. (for use with a remote controller and/or remote display board anywhere in the region/parcel)&lt;br /&gt;
* llResetScript on owner change&lt;br /&gt;
* Relax on URL format&lt;br /&gt;
* Allow multiple genres per station&lt;/div&gt;</description>
			<pubDate>Thu, 10 Feb 2011 00:36:14 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)</comments>
		</item>
		<item>
			<title>Shoutcast - radio controller v0.3 (remake of similar scripts)</title>
			<link>https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133919</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133919</guid>
			<description>&lt;p&gt;Flennan Roffo: /* Main script */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}}&lt;br /&gt;
=Shoutcast - radio controller=&lt;br /&gt;
This script controls a shoutcast radio receiver and lets you select the stations that you configured on a notecard. Menu driven. Output of station description, genre and current song title using Xy text.&lt;br /&gt;
&lt;br /&gt;
==Versions==&lt;br /&gt;
&lt;br /&gt;
Current version: v0.3 released 10-2-2011&lt;br /&gt;
&lt;br /&gt;
==Main script==&lt;br /&gt;
&lt;br /&gt;
This script should be put into the shoutcast - radio controller device.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// Script:  Shoutcast - radio controller&lt;br /&gt;
// Version: 0.3 - released 10-2-2011&lt;br /&gt;
// Logic Scripts (Flennan Roffo)&lt;br /&gt;
// (c) 2010 - Flennan Roffo (Logic Scripts)&lt;br /&gt;
// &lt;br /&gt;
// This script is a remake of a couple of similar script:&lt;br /&gt;
// + LandOwnersRadio V2.0 by Scripter Coba  (( menu driven / notecard config script to select the radio station and sets parcel music url ))&lt;br /&gt;
// + Raven radio infoboard by Jamie Otis    (( worked at the basis of sis service [sis.slserver.com/sis.php] used Xy text display         ))&lt;br /&gt;
// + currentPlaying by Darkie Minotaur      (( used the /7.html info to fetch current song title info, displayed as float text            ))&lt;br /&gt;
//&lt;br /&gt;
// Purpose:&lt;br /&gt;
// * Sets the parcel audio URL and displays the channel info&lt;br /&gt;
// * Uses Xytext to display the info.&lt;br /&gt;
// * Fetches song title info from the shoutcast url&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.1 release&lt;br /&gt;
// * On/Off option&lt;br /&gt;
// * Allows multiple menus (if options per menu &amp;gt; 12) using a prev/next button&lt;br /&gt;
// * Checks if your url is well-formatted&lt;br /&gt;
// * Will delete genres for which no stations exist&lt;br /&gt;
// * Will skip stations that have same url and same genre (you can however have an identical station url under different genres).&lt;br /&gt;
// * New notecard format&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.2 release&lt;br /&gt;
// * Configurable button text&lt;br /&gt;
// * Gets parcel URL and automatically sets the genre/station and on/off status accordingly (&amp;lt;-- doesn&#039;t work)&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Update -- 0.3 release&lt;br /&gt;
// * Fixed bug (only first station in genre displayed in menu)&lt;br /&gt;
// * Auto reset script when config card updated&lt;br /&gt;
// Notes:&lt;br /&gt;
// * Expects url to be in the format: &amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;, where &amp;lt;ip&amp;gt; has the format: xxx.xxx.xxx.xxx&lt;br /&gt;
// * Deletes entries in category (genre) for which no stations are configured with notice.&lt;br /&gt;
// * Skips stations which have identical URL AND same category (genre).&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Upcoming release -- 0.4&lt;br /&gt;
// * Will add functions for remote controller(s) and remote display(s) using llRegionSay to communicate over a channel.&lt;br /&gt;
// * Should relax on the constraints about the input format of URL&#039;s (currently requires that URL has format: xxx.xxx.xxx.xxx/yyyy)&lt;br /&gt;
// * Fix button placement&lt;br /&gt;
// * Implement script reset on change of owner&lt;br /&gt;
// * Permit station to be put under multiple genres, using a comma-seperated list of genres in the section [STATION]&lt;br /&gt;
//   (currently this is only possible by duplicating the entire line and change the genre.)&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// BUGS &amp;amp; FEATURE REQUESTS&lt;br /&gt;
//&lt;br /&gt;
// Please inform the author, Logic Scripts (flennan.roffo) about any bugs or annoyances.&lt;br /&gt;
// Feature requests can also be submitted to the author.&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// LICENCE INFO&lt;br /&gt;
//&lt;br /&gt;
// This program is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string info_notecard=&amp;quot;Radio Control info&amp;quot;;              ///////    EDITABLE  \\\\\\&lt;br /&gt;
string config_notecard=&amp;quot;Radio Control config&amp;quot;;          ///////    EDITABLE  \\\\\\&lt;br /&gt;
string comment_char=&amp;quot;#&amp;quot;;                                ///////    EDITABLE  \\\\\\&lt;br /&gt;
list sep_char_list= [&amp;quot;|&amp;quot;];                              ///////    EDITABLE  \\\\\\&lt;br /&gt;
float update_time=5.0;                                  ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string no_title_info=&amp;quot;(no title info available)&amp;quot;;       ///////    EDITABLE  \\\\\\&lt;br /&gt;
&lt;br /&gt;
// not used currently - for showing info on current song title elsewhere in the region&lt;br /&gt;
integer broadcast_channel=-1234;                        ///////    EDITABLE  \\\\\\ &lt;br /&gt;
&lt;br /&gt;
// Buttons&lt;br /&gt;
&lt;br /&gt;
string button_MAIN = &amp;quot;MAIN&amp;quot;;&lt;br /&gt;
string button_HELP = &amp;quot;HELP&amp;quot;;&lt;br /&gt;
string button_NEXT = &amp;quot;&amp;gt;&amp;gt;&amp;quot;;&lt;br /&gt;
string button_PREV = &amp;quot;&amp;lt;&amp;lt;&amp;quot;;&lt;br /&gt;
string button_ON   = &amp;quot;ON&amp;quot;;&lt;br /&gt;
string button_OFF  = &amp;quot;OFF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// List of categories (=genres)&lt;br /&gt;
&lt;br /&gt;
list category_list=[];&lt;br /&gt;
&lt;br /&gt;
// List of stations. KEEP THESE LISTS IN SYNCH!&lt;br /&gt;
&lt;br /&gt;
list station_category=[];&lt;br /&gt;
list station_name=[];&lt;br /&gt;
list station_desc=[];&lt;br /&gt;
list station_url=[];&lt;br /&gt;
&lt;br /&gt;
// Last song title played&lt;br /&gt;
string last_title_info=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
integer radio_status=0;    // 0 - OFF   1 - ON&lt;br /&gt;
string parcel_url=&amp;quot;&amp;quot;;&lt;br /&gt;
integer lineno=0;&lt;br /&gt;
key reqid=NULL_KEY;&lt;br /&gt;
key httpreq_id=NULL_KEY;&lt;br /&gt;
integer config_error=FALSE;&lt;br /&gt;
integer flag;&lt;br /&gt;
integer section=0;&lt;br /&gt;
&lt;br /&gt;
// Access values. Note that users who are banned can not access the device even when access is public&lt;br /&gt;
integer owner_access=TRUE;&lt;br /&gt;
integer group_access=FALSE;&lt;br /&gt;
integer public_access=TRUE;&lt;br /&gt;
list banned_keys=[];&lt;br /&gt;
&lt;br /&gt;
// Channels for menu and user input&lt;br /&gt;
integer menu_channel;&lt;br /&gt;
integer listen_handle;&lt;br /&gt;
&lt;br /&gt;
// Menu&lt;br /&gt;
integer menu_type=0;         // 0 - Main menu (genres)   1 - Station menu (stations)&lt;br /&gt;
integer menu_num=0;          // When more menu options need to be selectable then can be displayed on a menu (12), this is the menu number - menu number 0 is the first menu.&lt;br /&gt;
&lt;br /&gt;
// Genres and stations&lt;br /&gt;
&lt;br /&gt;
integer category_index=0;    // Current index in category_list  (genre)&lt;br /&gt;
integer station_index=0;     // Current index in station_*      (station)&lt;br /&gt;
&lt;br /&gt;
integer num_categories=0;&lt;br /&gt;
integer num_stations=0;&lt;br /&gt;
&lt;br /&gt;
// Make request for title info using HTTP request&lt;br /&gt;
retrieve_titelinfo()&lt;br /&gt;
{&lt;br /&gt;
    string url=llList2String(station_url,station_index);&lt;br /&gt;
    httpreq_id=llHTTPRequest(url + &amp;quot;/7.html  HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n&amp;quot;,[],&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Display a line on an Xytext device linked in&lt;br /&gt;
display_line(string line, string message)&lt;br /&gt;
{&lt;br /&gt;
    // Setup XYtext Variables&lt;br /&gt;
    integer DISPLAY_STRING      = 204000; &lt;br /&gt;
//    integer DISPLAY_EXTENDED    = 204001;     (not used)&lt;br /&gt;
//    integer REMAP_INDICES       = 204002;     (not used) &lt;br /&gt;
//    integer RESET_INDICES       = 204003;     (not used)&lt;br /&gt;
//    integer SET_CELL_INFO       = 204004;     (not used)&lt;br /&gt;
//    integer SET_FONT_TEXTURE    = 204005;     (not used)&lt;br /&gt;
//    integer SET_THICKNESS       = 204006;     (not used)&lt;br /&gt;
//    integer SET_COLOR           = 204007;     (not used)&lt;br /&gt;
&lt;br /&gt;
    llMessageLinked(LINK_SET,DISPLAY_STRING,message,line);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Clear the Xytext display&lt;br /&gt;
clear_display() &lt;br /&gt;
{&lt;br /&gt;
    // Clears the display&lt;br /&gt;
    display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio Station ID&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;2&amp;quot;,&amp;quot;Music Genre....&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;3&amp;quot;,&amp;quot;Now Playing....&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Make a menu / dialog&lt;br /&gt;
make_menu(key id)&lt;br /&gt;
{&lt;br /&gt;
     menu_channel=random_channel();&lt;br /&gt;
&lt;br /&gt;
    if (radio_status == 0)&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        llDialog(id,&amp;quot;Menu: Status\n\nRadio is OFF&amp;quot;, [ &amp;quot;ON&amp;quot;, &amp;quot;HELP&amp;quot; ],menu_channel);&lt;br /&gt;
    }&lt;br /&gt;
    else &lt;br /&gt;
    {&lt;br /&gt;
        if (menu_type ==0)&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Genres&amp;quot;, category_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Stations\nGenre: &amp;quot; + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (listen_handle != 0)    llListenRemove(listen_handle);&lt;br /&gt;
    listen_handle=llListen(menu_channel,&amp;quot;&amp;quot;,id,&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Make the menu option list for menu: catagories (genres)&lt;br /&gt;
list category_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
&lt;br /&gt;
    if (len &amp;gt; 9)   // If more then 9 items (12 minus the 3 buttons for MAIN/HELP and PREV, NEXT)&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;   // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc. &lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt; last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
&lt;br /&gt;
             while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_HELP;&lt;br /&gt;
             else&lt;br /&gt;
                 menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_OFF;&lt;br /&gt;
             else&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num != last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;       &lt;br /&gt;
        }            &lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
        menu+=(list)button_OFF;&lt;br /&gt;
        menu+=(list)button_HELP;&lt;br /&gt;
    }        &lt;br /&gt;
    &lt;br /&gt;
    return menu;    // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns the number of stations in a certain category&lt;br /&gt;
integer stations_in_category(integer cat)&lt;br /&gt;
{&lt;br /&gt;
    integer count=0;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
    string category=llList2String(category_list,cat);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (category == llList2String(category_list,i))&lt;br /&gt;
            count++;&lt;br /&gt;
&lt;br /&gt;
    return count;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Not used currently -- to fix button placement&lt;br /&gt;
list order_buttons(list buttons)&lt;br /&gt;
{&lt;br /&gt;
    integer offset;&lt;br /&gt;
    list fixt;&lt;br /&gt;
    integer flag=0;&lt;br /&gt;
&lt;br /&gt;
    while((offset = llGetListLength(buttons)))&lt;br /&gt;
    {&lt;br /&gt;
        if (offset &amp;gt; 3)&lt;br /&gt;
            flag=1;&lt;br /&gt;
        else&lt;br /&gt;
            flag=0;&lt;br /&gt;
&lt;br /&gt;
        fixt += llList2List(buttons, offset = -3 * flag, -1);&lt;br /&gt;
        buttons = llDeleteSubList(buttons, offset, -1);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return fixt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns a list of station names in a certain category (genre)&lt;br /&gt;
list station_list(integer category)&lt;br /&gt;
{&lt;br /&gt;
    list s=[];&lt;br /&gt;
    integer i;&lt;br /&gt;
    string cname=llList2String(category_list,category_index);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; llGetListLength(station_name); i++)&lt;br /&gt;
        if (llList2String(station_category,i) == cname)&lt;br /&gt;
            s+=(list)llList2String(station_name,i);&lt;br /&gt;
&lt;br /&gt;
    return s;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns the list of stations for the station menu, depending on the submenu number&lt;br /&gt;
list station_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
    list stations=station_list(category_index);&lt;br /&gt;
    integer len=llGetListLength(stations);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
        &lt;br /&gt;
    if (len &amp;gt; 11)       // 12 - 1 for MAIN menu&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;&lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt;= last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
             integer last=9*num+8;&lt;br /&gt;
&lt;br /&gt;
             menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;gt; 0)&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;lt; last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;                      &lt;br /&gt;
&lt;br /&gt;
            if (len &amp;gt; last)&lt;br /&gt;
                len =last;&lt;br /&gt;
                &lt;br /&gt;
            while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(stations,len);&lt;br /&gt;
        }&lt;br /&gt;
    }            &lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(stations,len);&lt;br /&gt;
    }        &lt;br /&gt;
&lt;br /&gt;
    return menu; // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns whether av with key id has access&lt;br /&gt;
integer has_access(key id)&lt;br /&gt;
{&lt;br /&gt;
    if (llListFindList(banned_keys,(list)id) != -1)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    if (owner_access &amp;amp;&amp;amp; id == llGetOwner())&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (group_access &amp;amp;&amp;amp; llSameGroup(id))&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (public_access)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Gets a random channel -- uses a wide range of big negative channel numbers seldomly used&lt;br /&gt;
integer random_channel()&lt;br /&gt;
{&lt;br /&gt;
    integer min=-2147483647;&lt;br /&gt;
    integer max=-1000;&lt;br /&gt;
&lt;br /&gt;
    return (integer) (min + llFrand(max-min));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Check for the format of the url string  -- is very selective about url format&lt;br /&gt;
// expects:   xxx.xxx.xxx.xxx:xxxx    (ip adress in number notation with port adress)&lt;br /&gt;
// Next release will relax on this constraint.&lt;br /&gt;
integer check_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    integer pos=0;&lt;br /&gt;
&lt;br /&gt;
    if (llGetSubString(url,0,6) == &amp;quot;http://&amp;quot;)&lt;br /&gt;
        pos=7;        &lt;br /&gt;
    if (llGetSubString(url,0,7) == &amp;quot;https://&amp;quot;)&lt;br /&gt;
        pos=8;&lt;br /&gt;
&lt;br /&gt;
    if (pos==0)   return FALSE;&lt;br /&gt;
&lt;br /&gt;
    string str_ip_port=llGetSubString(url,pos,-1);&lt;br /&gt;
    list list_ip_port=llParseString2List(str_ip_port,[&amp;quot;:&amp;quot;],[]);                 // split in ip-adress and port&lt;br /&gt;
    list list_ip=llParseString2List(llList2String(list_ip_port,0),[&amp;quot;.&amp;quot;],[]);    // split ip-adress elements&lt;br /&gt;
&lt;br /&gt;
    if (llGetListLength(list_ip_port) != 2 || llGetListLength(list_ip) != 4)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer test;&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;4;i++)&lt;br /&gt;
    {&lt;br /&gt;
        test=llList2Integer(list_ip,i);&lt;br /&gt;
        if (llList2String(list_ip,i) != (string)test)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        if (test &amp;lt; 0 || test &amp;gt; 255)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    test=llList2Integer(list_ip_port,1);&lt;br /&gt;
    if (llList2String(list_ip_port,1) != (string)test)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns a true value depending on the first character in input - anything else is assumed false.&lt;br /&gt;
integer true_value(string input)&lt;br /&gt;
{&lt;br /&gt;
    string value=llToLower(llGetSubString(input,0,0));&lt;br /&gt;
&lt;br /&gt;
    if (value == &amp;quot;y&amp;quot; || value == &amp;quot;t&amp;quot; || value ==&amp;quot;1&amp;quot;)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Return if more input should be processed (if not at EOF) - sets ConfigError if any config error found.&lt;br /&gt;
integer process_line(string dataline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(dataline,STRING_TRIM);&lt;br /&gt;
    integer index=llSubStringIndex(line,comment_char);&lt;br /&gt;
    &lt;br /&gt;
    if (index==0)       // line starts with comment - ignore line&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (index!=-1)&lt;br /&gt;
        line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL);   // skip everything after comment_char and trim tail&lt;br /&gt;
&lt;br /&gt;
    if (line==&amp;quot;&amp;quot;)       // Ignore blank lines&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (llToLower(line) == &amp;quot;[access]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 1;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[banned]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 2;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[genre]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 3;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[station]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 4;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llGetSubString(line,0,0) == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; llGetSubString(line,-1,-1) == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: malformed section found at line &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
        config_error=TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: no section found on line: &amp;quot; + (string) lineno);&lt;br /&gt;
        config_error = TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    list breakup=llParseString2List(line,[&amp;quot;=&amp;quot;],[]);&lt;br /&gt;
    string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);&lt;br /&gt;
    string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);&lt;br /&gt;
&lt;br /&gt;
    if (section == 1)            // access&lt;br /&gt;
    {&lt;br /&gt;
        field=llToLower(field);&lt;br /&gt;
&lt;br /&gt;
        if (field==&amp;quot;owner&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            owner_access=true_value(values);                       &lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;group&amp;quot;)&lt;br /&gt;
        {    &lt;br /&gt;
            group_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;public&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            public_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: invalid option on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 2)         // ban list&lt;br /&gt;
    {&lt;br /&gt;
        key try=(key) field;&lt;br /&gt;
&lt;br /&gt;
        if (try)&lt;br /&gt;
        {&lt;br /&gt;
            banned_keys+=(list)((key) field);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 3)           // categories&lt;br /&gt;
    {&lt;br /&gt;
        if (llListFindList(category_list,(list)field) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            category_list+=(list)field;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;genre: &#039;&amp;quot; + field + &amp;quot;&#039; already entered; double entry skipped.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 4)            // stations&lt;br /&gt;
    {&lt;br /&gt;
        list parse=llParseString2List(line,sep_char_list, []);&lt;br /&gt;
        string category=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);&lt;br /&gt;
        string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);&lt;br /&gt;
    &lt;br /&gt;
        if (!available_category(category))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: unknown genre on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (check_url(url))&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                num_stations++;&lt;br /&gt;
                station_category+=(list)category;&lt;br /&gt;
                station_name+=(list)name;&lt;br /&gt;
                station_desc+=(list)desc;&lt;br /&gt;
                station_url+=(list)url;&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llWhisper(0,&amp;quot;This station is already entered under the same genre and same url and is skipped.\nStation: &amp;quot; + name + &amp;quot;\nGenre: &#039;&amp;quot; + category + &amp;quot;&#039;\nURL: &amp;quot; + url);&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: malformed url on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
     &lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Sets the parcel URL and updates the display&lt;br /&gt;
set_parcel_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    parcel_url=url;&lt;br /&gt;
    llSetParcelMusicURL(parcel_url);&lt;br /&gt;
&lt;br /&gt;
    if (parcel_url==&amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        clear_display();&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is OFF&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;station now set to &amp;quot; + llList2String(station_desc,station_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Station: &amp;quot; + llList2String(station_desc,station_index));&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;Genre  : &amp;quot; + llList2String(category_list,category_index));&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;Now playing.....&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns if a category (genre) exists.&lt;br /&gt;
integer available_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;len;i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(category_list,i)))&lt;br /&gt;
            return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns if a category (genre) is empty   (NOTE: same function as available_category(), but logical negate of it. One of these can be removed.)&lt;br /&gt;
integer empty_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(station_category,i)))&lt;br /&gt;
            return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Removes categories (genres) for which no station is known.&lt;br /&gt;
skip_empty_categories()&lt;br /&gt;
{&lt;br /&gt;
    integer i=0;&lt;br /&gt;
&lt;br /&gt;
    while (i&amp;lt;llGetListLength(category_list))&lt;br /&gt;
    {&lt;br /&gt;
        if (empty_category(llList2String(category_list,i)))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;Warning: Genre &#039;&amp;quot; + llList2String(category_list,i) + &amp;quot;&#039; contains no stations and is deleted.&amp;quot;);&lt;br /&gt;
            category_list=llDeleteSubList(category_list,i,i);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            i++;&lt;br /&gt;
    }&lt;br /&gt;
            &lt;br /&gt;
    num_categories=llGetListLength(category_list);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state default&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        flag=FALSE;&lt;br /&gt;
        lineno=0;&lt;br /&gt;
        config_error=FALSE;&lt;br /&gt;
        num_stations=0;&lt;br /&gt;
        num_categories=0;&lt;br /&gt;
        radio_status=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(config_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
           reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
           llWhisper(0, &amp;quot;Reading config notecard...&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;1&amp;quot;,&amp;quot;Reading configuration.&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;2&amp;quot;,&amp;quot;Wait....&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;No config notecard &#039;&amp;quot; +  config_notecard + &amp;quot;&#039; present.&amp;quot;);&lt;br /&gt;
            state offline;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (reqid==id)&lt;br /&gt;
        {        &lt;br /&gt;
            if (data==EOF)&lt;br /&gt;
            {&lt;br /&gt;
                skip_empty_categories();&lt;br /&gt;
                llWhisper(0,&amp;quot;Configuration ok.\n&amp;quot; + (string)num_categories + &amp;quot; genres and &amp;quot; + (string)num_stations + &amp;quot; stations.&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Configuration OK&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;2&amp;quot;,&amp;quot;Genres  : &amp;quot; + (string)num_categories);&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Stations: &amp;quot; + (string)num_stations);&lt;br /&gt;
                state menu;&lt;br /&gt;
            }&lt;br /&gt;
            else &lt;br /&gt;
            {&lt;br /&gt;
                if (process_line(data))&lt;br /&gt;
                    reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
                else if (config_error)&lt;br /&gt;
                {&lt;br /&gt;
                    llWhisper(0,&amp;quot;errors found in configuration. please correct them.&amp;quot;);&lt;br /&gt;
                    state offline;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state offline&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state offline&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;Reset on owner touch or when notecard updated.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    touch_start(integer t)&lt;br /&gt;
    {&lt;br /&gt;
        if (llDetectedKey(0)==llGetOwner())&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY &amp;amp;&amp;amp; flag)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state menu&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state menu&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        listen_handle=0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        if (param &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
        key toucher=llDetectedKey(0);&lt;br /&gt;
&lt;br /&gt;
        if (has_access(toucher))&lt;br /&gt;
        {&lt;br /&gt;
            make_menu(toucher);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;sorry, no access.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    listen(integer chan, string name,key id,string msg)&lt;br /&gt;
    {&lt;br /&gt;
        integer index;&lt;br /&gt;
&lt;br /&gt;
        if (menu_type == 0)          // main menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_ON)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=1;&lt;br /&gt;
                set_parcel_url(parcel_url);               &lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is ON&amp;quot;);&lt;br /&gt;
                menu_num=0;&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned on.&amp;quot;);&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=0;&lt;br /&gt;
                set_parcel_url(&amp;quot;&amp;quot;);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned off.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
                {&lt;br /&gt;
                    llGiveInventory(id,info_notecard);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                    llWhisper(0,&amp;quot;sorry, help not available.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (radio_status == 1)&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(category_list, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: genre not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    category_index=index;&lt;br /&gt;
                    llWhisper(0,&amp;quot;Genre now set to &amp;quot; + llList2String(category_list,category_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
                    menu_type=1;&lt;br /&gt;
                    menu_num=0;&lt;br /&gt;
                    make_menu(id);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (menu_type == 1 &amp;amp;&amp;amp; radio_status == 1)     // station menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(station_name, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: station not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    station_index=index;&lt;br /&gt;
                    string new_url=llList2String(station_url,station_index);&lt;br /&gt;
&lt;br /&gt;
                    if (new_url != parcel_url)&lt;br /&gt;
                    {&lt;br /&gt;
                        set_parcel_url(new_url);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        retrieve_titelinfo();&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_response(key id, integer status, list meta, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == httpreq_id)&lt;br /&gt;
        {&lt;br /&gt;
            if (status == 200)&lt;br /&gt;
            {&lt;br /&gt;
                string feed = llGetSubString(body,llSubStringIndex(body, &amp;quot;&amp;lt;body&amp;gt;&amp;quot;) + llStringLength(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;), llSubStringIndex(body,&amp;quot;&amp;lt;/body&amp;gt;&amp;quot;) - 1);&lt;br /&gt;
                list feed_list = llParseString2List(feed,[&amp;quot;,&amp;quot;],[]);&lt;br /&gt;
                string current_title_info= llList2String(feed_list,6);&lt;br /&gt;
                integer length = llGetListLength(feed_list);&lt;br /&gt;
        &lt;br /&gt;
                if(llList2String(feed_list,7))&lt;br /&gt;
                {&lt;br /&gt;
                    integer a = 7;&lt;br /&gt;
                    for(; a&amp;lt;length; ++a)&lt;br /&gt;
                    {&lt;br /&gt;
                        current_title_info += &amp;quot;, &amp;quot; + llList2String(feed_list,a);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
         &lt;br /&gt;
                if (current_title_info != last_title_info)&lt;br /&gt;
                {&lt;br /&gt;
                    last_title_info = current_title_info;&lt;br /&gt;
                    display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + current_title_info);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + no_title_info);&lt;br /&gt;
            }&lt;br /&gt;
        }    &lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY &amp;amp;&amp;amp; flag)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
// end of script&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
===Notecard format===&lt;br /&gt;
Example notecard&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# New format Shoutcast - radio controller config notecard&lt;br /&gt;
# The format is divided in 4 sections:&lt;br /&gt;
# 1 - Access configuration&lt;br /&gt;
# 2 - Ban list (keys)&lt;br /&gt;
# 3 - Categories  (same as genres)&lt;br /&gt;
# 4 - Station info (category, name, desc, url)&lt;br /&gt;
# The &#039;#&#039; character defines the start of a comment and can be anywhere on a line. &lt;br /&gt;
# Everything after the &#039;#&#039; incuding the &#039;#&#039; itself is ignored.&lt;br /&gt;
# Case is not important (but information on display will show as entered)&lt;br /&gt;
# Spaces before and/or after fields are trimmed.&lt;br /&gt;
# Empty lines are ignored.&lt;br /&gt;
&lt;br /&gt;
[ACCESS]&lt;br /&gt;
owner=yes       # yes, true,1      means owner has access. everything else not.&lt;br /&gt;
group=yes       #  ,,  ,,  ,,      means group has acess.    ,,        ,,   ,,&lt;br /&gt;
public=yes      #  ,,  ,,  ,,      means public has access.  ,,        ,,   ,, &lt;br /&gt;
&lt;br /&gt;
[BANNED]&lt;br /&gt;
# keys of banned residents&lt;br /&gt;
&lt;br /&gt;
[GENRE]&lt;br /&gt;
# genre name -- Use short genre names as the the length of menu buttons is short!&lt;br /&gt;
Hard Rock&lt;br /&gt;
Classic Rock&lt;br /&gt;
Oldies&lt;br /&gt;
Rap/Urban&lt;br /&gt;
Comedy&lt;br /&gt;
News&lt;br /&gt;
Dance&lt;br /&gt;
Country&lt;br /&gt;
Gothic&lt;br /&gt;
# etc.&lt;br /&gt;
[STATION]&lt;br /&gt;
# Shoutcast radio stations&lt;br /&gt;
# Use a &#039;|&#039; between each field - don&#039;t mind spaces before and after fields, they will be trimmed&lt;br /&gt;
# field1:genre, field2:station name, field3: station description, field4: station http://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt; or https://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;&lt;br /&gt;
# Note that genre must match case-insensitive a value previously entered in section [GENRE]&lt;br /&gt;
Classic Rock    | Absolute         |    Absolute Radio                  | http://205.188.215.226:8018&lt;br /&gt;
# etc.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===TODO===&lt;br /&gt;
&lt;br /&gt;
Planned for upcoming release 0.4:&lt;br /&gt;
* Add a llRegionSay to broadcast the &amp;lt;station&amp;gt;|&amp;lt;genre&amp;gt;|&amp;lt;current songtitle&amp;gt;|&amp;lt;url&amp;gt; to the region and add a script that displays that info on a remote Xytext board. (for use with a remote controller and/or remote display board anywhere in the region/parcel)&lt;br /&gt;
* llResetScript on owner change&lt;br /&gt;
* Relax on URL format&lt;br /&gt;
* Allow multiple genres per station&lt;/div&gt;</description>
			<pubDate>Thu, 10 Feb 2011 00:29:17 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)</comments>
		</item>
		<item>
			<title>Shoutcast - radio controller v0.3 (remake of similar scripts)</title>
			<link>https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133918</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133918</guid>
			<description>&lt;p&gt;Flennan Roffo: /* Notecard format */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}}&lt;br /&gt;
=Shoutcast - radio controller=&lt;br /&gt;
This script controls a shoutcast radio receiver and lets you select the stations that you configured on a notecard. Menu driven. Output of station description, genre and current song title using Xy text.&lt;br /&gt;
&lt;br /&gt;
==Versions==&lt;br /&gt;
&lt;br /&gt;
Current version: v0.3 released 10-2-2011&lt;br /&gt;
&lt;br /&gt;
==Main script==&lt;br /&gt;
&lt;br /&gt;
This script should be put into the &lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// Script:  Shoutcast - radio controller&lt;br /&gt;
// Version: 0.3 - released 10-2-2011&lt;br /&gt;
// Logic Scripts (Flennan Roffo)&lt;br /&gt;
// (c) 2010 - Flennan Roffo (Logic Scripts)&lt;br /&gt;
// &lt;br /&gt;
// This script is a remake of a couple of similar script:&lt;br /&gt;
// + LandOwnersRadio V2.0 by Scripter Coba  (( menu driven / notecard config script to select the radio station and sets parcel music url ))&lt;br /&gt;
// + Raven radio infoboard by Jamie Otis    (( worked at the basis of sis service [sis.slserver.com/sis.php] used Xy text display         ))&lt;br /&gt;
// + currentPlaying by Darkie Minotaur      (( used the /7.html info to fetch current song title info, displayed as float text            ))&lt;br /&gt;
//&lt;br /&gt;
// Purpose:&lt;br /&gt;
// * Sets the parcel audio URL and displays the channel info&lt;br /&gt;
// * Uses Xytext to display the info.&lt;br /&gt;
// * Fetches song title info from the shoutcast url&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.1 release&lt;br /&gt;
// * On/Off option&lt;br /&gt;
// * Allows multiple menus (if options per menu &amp;gt; 12) using a prev/next button&lt;br /&gt;
// * Checks if your url is well-formatted&lt;br /&gt;
// * Will delete genres for which no stations exist&lt;br /&gt;
// * Will skip stations that have same url and same genre (you can however have an identical station url under different genres).&lt;br /&gt;
// * New notecard format&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.2 release&lt;br /&gt;
// * Configurable button text&lt;br /&gt;
// * Gets parcel URL and automatically sets the genre/station and on/off status accordingly (&amp;lt;-- doesn&#039;t work)&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Update -- 0.3 release&lt;br /&gt;
// * Fixed bug (only first station in genre displayed in menu)&lt;br /&gt;
// * Auto reset script when config card updated&lt;br /&gt;
// Notes:&lt;br /&gt;
// * Expects url to be in the format: &amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;, where &amp;lt;ip&amp;gt; has the format: xxx.xxx.xxx.xxx&lt;br /&gt;
// * Deletes entries in category (genre) for which no stations are configured with notice.&lt;br /&gt;
// * Skips stations which have identical URL AND same category (genre).&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Upcoming release -- 0.4&lt;br /&gt;
// * Will add functions for remote controller(s) and remote display(s) using llRegionSay to communicate over a channel.&lt;br /&gt;
// * Should relax on the constraints about the input format of URL&#039;s (currently requires that URL has format: xxx.xxx.xxx.xxx/yyyy)&lt;br /&gt;
// * Fix button placement&lt;br /&gt;
// * Implement script reset on change of owner&lt;br /&gt;
// * Permit station to be put under multiple genres, using a comma-seperated list of genres in the section [STATION]&lt;br /&gt;
//   (currently this is only possible by duplicating the entire line and change the genre.)&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// BUGS &amp;amp; FEATURE REQUESTS&lt;br /&gt;
//&lt;br /&gt;
// Please inform the author, Logic Scripts (flennan.roffo) about any bugs or annoyances.&lt;br /&gt;
// Feature requests can also be submitted to the author.&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// LICENCE INFO&lt;br /&gt;
//&lt;br /&gt;
// This program is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string info_notecard=&amp;quot;Radio Control info&amp;quot;;              ///////    EDITABLE  \\\\\\&lt;br /&gt;
string config_notecard=&amp;quot;Radio Control config&amp;quot;;          ///////    EDITABLE  \\\\\\&lt;br /&gt;
string comment_char=&amp;quot;#&amp;quot;;                                ///////    EDITABLE  \\\\\\&lt;br /&gt;
list sep_char_list= [&amp;quot;|&amp;quot;];                              ///////    EDITABLE  \\\\\\&lt;br /&gt;
float update_time=5.0;                                  ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string no_title_info=&amp;quot;(no title info available)&amp;quot;;       ///////    EDITABLE  \\\\\\&lt;br /&gt;
&lt;br /&gt;
// not used currently - for showing info on current song title elsewhere in the region&lt;br /&gt;
integer broadcast_channel=-1234;                        ///////    EDITABLE  \\\\\\ &lt;br /&gt;
&lt;br /&gt;
// Buttons&lt;br /&gt;
&lt;br /&gt;
string button_MAIN = &amp;quot;MAIN&amp;quot;;&lt;br /&gt;
string button_HELP = &amp;quot;HELP&amp;quot;;&lt;br /&gt;
string button_NEXT = &amp;quot;&amp;gt;&amp;gt;&amp;quot;;&lt;br /&gt;
string button_PREV = &amp;quot;&amp;lt;&amp;lt;&amp;quot;;&lt;br /&gt;
string button_ON   = &amp;quot;ON&amp;quot;;&lt;br /&gt;
string button_OFF  = &amp;quot;OFF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// List of categories (=genres)&lt;br /&gt;
&lt;br /&gt;
list category_list=[];&lt;br /&gt;
&lt;br /&gt;
// List of stations. KEEP THESE LISTS IN SYNCH!&lt;br /&gt;
&lt;br /&gt;
list station_category=[];&lt;br /&gt;
list station_name=[];&lt;br /&gt;
list station_desc=[];&lt;br /&gt;
list station_url=[];&lt;br /&gt;
&lt;br /&gt;
// Last song title played&lt;br /&gt;
string last_title_info=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
integer radio_status=0;    // 0 - OFF   1 - ON&lt;br /&gt;
string parcel_url=&amp;quot;&amp;quot;;&lt;br /&gt;
integer lineno=0;&lt;br /&gt;
key reqid=NULL_KEY;&lt;br /&gt;
key httpreq_id=NULL_KEY;&lt;br /&gt;
integer config_error=FALSE;&lt;br /&gt;
integer flag;&lt;br /&gt;
integer section=0;&lt;br /&gt;
&lt;br /&gt;
// Access values. Note that users who are banned can not access the device even when access is public&lt;br /&gt;
integer owner_access=TRUE;&lt;br /&gt;
integer group_access=FALSE;&lt;br /&gt;
integer public_access=TRUE;&lt;br /&gt;
list banned_keys=[];&lt;br /&gt;
&lt;br /&gt;
// Channels for menu and user input&lt;br /&gt;
integer menu_channel;&lt;br /&gt;
integer listen_handle;&lt;br /&gt;
&lt;br /&gt;
// Menu&lt;br /&gt;
integer menu_type=0;         // 0 - Main menu (genres)   1 - Station menu (stations)&lt;br /&gt;
integer menu_num=0;          // When more menu options need to be selectable then can be displayed on a menu (12), this is the menu number - menu number 0 is the first menu.&lt;br /&gt;
&lt;br /&gt;
// Genres and stations&lt;br /&gt;
&lt;br /&gt;
integer category_index=0;    // Current index in category_list  (genre)&lt;br /&gt;
integer station_index=0;     // Current index in station_*      (station)&lt;br /&gt;
&lt;br /&gt;
integer num_categories=0;&lt;br /&gt;
integer num_stations=0;&lt;br /&gt;
&lt;br /&gt;
// Make request for title info using HTTP request&lt;br /&gt;
retrieve_titelinfo()&lt;br /&gt;
{&lt;br /&gt;
    string url=llList2String(station_url,station_index);&lt;br /&gt;
    httpreq_id=llHTTPRequest(url + &amp;quot;/7.html  HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n&amp;quot;,[],&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Display a line on an Xytext device linked in&lt;br /&gt;
display_line(string line, string message)&lt;br /&gt;
{&lt;br /&gt;
    // Setup XYtext Variables&lt;br /&gt;
    integer DISPLAY_STRING      = 204000; &lt;br /&gt;
//    integer DISPLAY_EXTENDED    = 204001;     (not used)&lt;br /&gt;
//    integer REMAP_INDICES       = 204002;     (not used) &lt;br /&gt;
//    integer RESET_INDICES       = 204003;     (not used)&lt;br /&gt;
//    integer SET_CELL_INFO       = 204004;     (not used)&lt;br /&gt;
//    integer SET_FONT_TEXTURE    = 204005;     (not used)&lt;br /&gt;
//    integer SET_THICKNESS       = 204006;     (not used)&lt;br /&gt;
//    integer SET_COLOR           = 204007;     (not used)&lt;br /&gt;
&lt;br /&gt;
    llMessageLinked(LINK_SET,DISPLAY_STRING,message,line);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Clear the Xytext display&lt;br /&gt;
clear_display() &lt;br /&gt;
{&lt;br /&gt;
    // Clears the display&lt;br /&gt;
    display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio Station ID&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;2&amp;quot;,&amp;quot;Music Genre....&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;3&amp;quot;,&amp;quot;Now Playing....&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Make a menu / dialog&lt;br /&gt;
make_menu(key id)&lt;br /&gt;
{&lt;br /&gt;
     menu_channel=random_channel();&lt;br /&gt;
&lt;br /&gt;
    if (radio_status == 0)&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        llDialog(id,&amp;quot;Menu: Status\n\nRadio is OFF&amp;quot;, [ &amp;quot;ON&amp;quot;, &amp;quot;HELP&amp;quot; ],menu_channel);&lt;br /&gt;
    }&lt;br /&gt;
    else &lt;br /&gt;
    {&lt;br /&gt;
        if (menu_type ==0)&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Genres&amp;quot;, category_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Stations\nGenre: &amp;quot; + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (listen_handle != 0)    llListenRemove(listen_handle);&lt;br /&gt;
    listen_handle=llListen(menu_channel,&amp;quot;&amp;quot;,id,&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Make the menu option list for menu: catagories (genres)&lt;br /&gt;
list category_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
&lt;br /&gt;
    if (len &amp;gt; 9)   // If more then 9 items (12 minus the 3 buttons for MAIN/HELP and PREV, NEXT)&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;   // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc. &lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt; last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
&lt;br /&gt;
             while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_HELP;&lt;br /&gt;
             else&lt;br /&gt;
                 menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_OFF;&lt;br /&gt;
             else&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num != last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;       &lt;br /&gt;
        }            &lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
        menu+=(list)button_OFF;&lt;br /&gt;
        menu+=(list)button_HELP;&lt;br /&gt;
    }        &lt;br /&gt;
    &lt;br /&gt;
    return menu;    // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns the number of stations in a certain category&lt;br /&gt;
integer stations_in_category(integer cat)&lt;br /&gt;
{&lt;br /&gt;
    integer count=0;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
    string category=llList2String(category_list,cat);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (category == llList2String(category_list,i))&lt;br /&gt;
            count++;&lt;br /&gt;
&lt;br /&gt;
    return count;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Not used currently -- to fix button placement&lt;br /&gt;
list order_buttons(list buttons)&lt;br /&gt;
{&lt;br /&gt;
    integer offset;&lt;br /&gt;
    list fixt;&lt;br /&gt;
    integer flag=0;&lt;br /&gt;
&lt;br /&gt;
    while((offset = llGetListLength(buttons)))&lt;br /&gt;
    {&lt;br /&gt;
        if (offset &amp;gt; 3)&lt;br /&gt;
            flag=1;&lt;br /&gt;
        else&lt;br /&gt;
            flag=0;&lt;br /&gt;
&lt;br /&gt;
        fixt += llList2List(buttons, offset = -3 * flag, -1);&lt;br /&gt;
        buttons = llDeleteSubList(buttons, offset, -1);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return fixt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns a list of station names in a certain category (genre)&lt;br /&gt;
list station_list(integer category)&lt;br /&gt;
{&lt;br /&gt;
    list s=[];&lt;br /&gt;
    integer i;&lt;br /&gt;
    string cname=llList2String(category_list,category_index);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; llGetListLength(station_name); i++)&lt;br /&gt;
        if (llList2String(station_category,i) == cname)&lt;br /&gt;
            s+=(list)llList2String(station_name,i);&lt;br /&gt;
&lt;br /&gt;
    return s;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns the list of stations for the station menu, depending on the submenu number&lt;br /&gt;
list station_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
    list stations=station_list(category_index);&lt;br /&gt;
    integer len=llGetListLength(stations);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
        &lt;br /&gt;
    if (len &amp;gt; 11)       // 12 - 1 for MAIN menu&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;&lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt;= last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
             integer last=9*num+8;&lt;br /&gt;
&lt;br /&gt;
             menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;gt; 0)&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;lt; last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;                      &lt;br /&gt;
&lt;br /&gt;
            if (len &amp;gt; last)&lt;br /&gt;
                len =last;&lt;br /&gt;
                &lt;br /&gt;
            while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(stations,len);&lt;br /&gt;
        }&lt;br /&gt;
    }            &lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(stations,len);&lt;br /&gt;
    }        &lt;br /&gt;
&lt;br /&gt;
    return menu; // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns whether av with key id has access&lt;br /&gt;
integer has_access(key id)&lt;br /&gt;
{&lt;br /&gt;
    if (llListFindList(banned_keys,(list)id) != -1)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    if (owner_access &amp;amp;&amp;amp; id == llGetOwner())&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (group_access &amp;amp;&amp;amp; llSameGroup(id))&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (public_access)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Gets a random channel -- uses a wide range of big negative channel numbers seldomly used&lt;br /&gt;
integer random_channel()&lt;br /&gt;
{&lt;br /&gt;
    integer min=-2147483647;&lt;br /&gt;
    integer max=-1000;&lt;br /&gt;
&lt;br /&gt;
    return (integer) (min + llFrand(max-min));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Check for the format of the url string  -- is very selective about url format&lt;br /&gt;
// expects:   xxx.xxx.xxx.xxx:xxxx    (ip adress in number notation with port adress)&lt;br /&gt;
// Next release will relax on this constraint.&lt;br /&gt;
integer check_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    integer pos=0;&lt;br /&gt;
&lt;br /&gt;
    if (llGetSubString(url,0,6) == &amp;quot;http://&amp;quot;)&lt;br /&gt;
        pos=7;        &lt;br /&gt;
    if (llGetSubString(url,0,7) == &amp;quot;https://&amp;quot;)&lt;br /&gt;
        pos=8;&lt;br /&gt;
&lt;br /&gt;
    if (pos==0)   return FALSE;&lt;br /&gt;
&lt;br /&gt;
    string str_ip_port=llGetSubString(url,pos,-1);&lt;br /&gt;
    list list_ip_port=llParseString2List(str_ip_port,[&amp;quot;:&amp;quot;],[]);                 // split in ip-adress and port&lt;br /&gt;
    list list_ip=llParseString2List(llList2String(list_ip_port,0),[&amp;quot;.&amp;quot;],[]);    // split ip-adress elements&lt;br /&gt;
&lt;br /&gt;
    if (llGetListLength(list_ip_port) != 2 || llGetListLength(list_ip) != 4)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer test;&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;4;i++)&lt;br /&gt;
    {&lt;br /&gt;
        test=llList2Integer(list_ip,i);&lt;br /&gt;
        if (llList2String(list_ip,i) != (string)test)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        if (test &amp;lt; 0 || test &amp;gt; 255)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    test=llList2Integer(list_ip_port,1);&lt;br /&gt;
    if (llList2String(list_ip_port,1) != (string)test)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns a true value depending on the first character in input - anything else is assumed false.&lt;br /&gt;
integer true_value(string input)&lt;br /&gt;
{&lt;br /&gt;
    string value=llToLower(llGetSubString(input,0,0));&lt;br /&gt;
&lt;br /&gt;
    if (value == &amp;quot;y&amp;quot; || value == &amp;quot;t&amp;quot; || value ==&amp;quot;1&amp;quot;)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Return if more input should be processed (if not at EOF) - sets ConfigError if any config error found.&lt;br /&gt;
integer process_line(string dataline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(dataline,STRING_TRIM);&lt;br /&gt;
    integer index=llSubStringIndex(line,comment_char);&lt;br /&gt;
    &lt;br /&gt;
    if (index==0)       // line starts with comment - ignore line&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (index!=-1)&lt;br /&gt;
        line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL);   // skip everything after comment_char and trim tail&lt;br /&gt;
&lt;br /&gt;
    if (line==&amp;quot;&amp;quot;)       // Ignore blank lines&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (llToLower(line) == &amp;quot;[access]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 1;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[banned]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 2;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[genre]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 3;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[station]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 4;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llGetSubString(line,0,0) == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; llGetSubString(line,-1,-1) == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: malformed section found at line &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
        config_error=TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: no section found on line: &amp;quot; + (string) lineno);&lt;br /&gt;
        config_error = TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    list breakup=llParseString2List(line,[&amp;quot;=&amp;quot;],[]);&lt;br /&gt;
    string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);&lt;br /&gt;
    string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);&lt;br /&gt;
&lt;br /&gt;
    if (section == 1)            // access&lt;br /&gt;
    {&lt;br /&gt;
        field=llToLower(field);&lt;br /&gt;
&lt;br /&gt;
        if (field==&amp;quot;owner&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            owner_access=true_value(values);                       &lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;group&amp;quot;)&lt;br /&gt;
        {    &lt;br /&gt;
            group_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;public&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            public_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: invalid option on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 2)         // ban list&lt;br /&gt;
    {&lt;br /&gt;
        key try=(key) field;&lt;br /&gt;
&lt;br /&gt;
        if (try)&lt;br /&gt;
        {&lt;br /&gt;
            banned_keys+=(list)((key) field);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 3)           // categories&lt;br /&gt;
    {&lt;br /&gt;
        if (llListFindList(category_list,(list)field) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            category_list+=(list)field;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;genre: &#039;&amp;quot; + field + &amp;quot;&#039; already entered; double entry skipped.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 4)            // stations&lt;br /&gt;
    {&lt;br /&gt;
        list parse=llParseString2List(line,sep_char_list, []);&lt;br /&gt;
        string category=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);&lt;br /&gt;
        string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);&lt;br /&gt;
    &lt;br /&gt;
        if (!available_category(category))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: unknown genre on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (check_url(url))&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                num_stations++;&lt;br /&gt;
                station_category+=(list)category;&lt;br /&gt;
                station_name+=(list)name;&lt;br /&gt;
                station_desc+=(list)desc;&lt;br /&gt;
                station_url+=(list)url;&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llWhisper(0,&amp;quot;This station is already entered under the same genre and same url and is skipped.\nStation: &amp;quot; + name + &amp;quot;\nGenre: &#039;&amp;quot; + category + &amp;quot;&#039;\nURL: &amp;quot; + url);&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: malformed url on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
     &lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Sets the parcel URL and updates the display&lt;br /&gt;
set_parcel_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    parcel_url=url;&lt;br /&gt;
    llSetParcelMusicURL(parcel_url);&lt;br /&gt;
&lt;br /&gt;
    if (parcel_url==&amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        clear_display();&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is OFF&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;station now set to &amp;quot; + llList2String(station_desc,station_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Station: &amp;quot; + llList2String(station_desc,station_index));&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;Genre  : &amp;quot; + llList2String(category_list,category_index));&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;Now playing.....&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns if a category (genre) exists.&lt;br /&gt;
integer available_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;len;i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(category_list,i)))&lt;br /&gt;
            return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns if a category (genre) is empty   (NOTE: same function as available_category(), but logical negate of it. One of these can be removed.)&lt;br /&gt;
integer empty_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(station_category,i)))&lt;br /&gt;
            return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Removes categories (genres) for which no station is known.&lt;br /&gt;
skip_empty_categories()&lt;br /&gt;
{&lt;br /&gt;
    integer i=0;&lt;br /&gt;
&lt;br /&gt;
    while (i&amp;lt;llGetListLength(category_list))&lt;br /&gt;
    {&lt;br /&gt;
        if (empty_category(llList2String(category_list,i)))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;Warning: Genre &#039;&amp;quot; + llList2String(category_list,i) + &amp;quot;&#039; contains no stations and is deleted.&amp;quot;);&lt;br /&gt;
            category_list=llDeleteSubList(category_list,i,i);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            i++;&lt;br /&gt;
    }&lt;br /&gt;
            &lt;br /&gt;
    num_categories=llGetListLength(category_list);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state default&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        flag=FALSE;&lt;br /&gt;
        lineno=0;&lt;br /&gt;
        config_error=FALSE;&lt;br /&gt;
        num_stations=0;&lt;br /&gt;
        num_categories=0;&lt;br /&gt;
        radio_status=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(config_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
           reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
           llWhisper(0, &amp;quot;Reading config notecard...&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;1&amp;quot;,&amp;quot;Reading configuration.&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;2&amp;quot;,&amp;quot;Wait....&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;No config notecard &#039;&amp;quot; +  config_notecard + &amp;quot;&#039; present.&amp;quot;);&lt;br /&gt;
            state offline;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (reqid==id)&lt;br /&gt;
        {        &lt;br /&gt;
            if (data==EOF)&lt;br /&gt;
            {&lt;br /&gt;
                skip_empty_categories();&lt;br /&gt;
                llWhisper(0,&amp;quot;Configuration ok.\n&amp;quot; + (string)num_categories + &amp;quot; genres and &amp;quot; + (string)num_stations + &amp;quot; stations.&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Configuration OK&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;2&amp;quot;,&amp;quot;Genres  : &amp;quot; + (string)num_categories);&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Stations: &amp;quot; + (string)num_stations);&lt;br /&gt;
                state menu;&lt;br /&gt;
            }&lt;br /&gt;
            else &lt;br /&gt;
            {&lt;br /&gt;
                if (process_line(data))&lt;br /&gt;
                    reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
                else if (config_error)&lt;br /&gt;
                {&lt;br /&gt;
                    llWhisper(0,&amp;quot;errors found in configuration. please correct them.&amp;quot;);&lt;br /&gt;
                    state offline;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state offline&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state offline&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;Reset on owner touch or when notecard updated.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    touch_start(integer t)&lt;br /&gt;
    {&lt;br /&gt;
        if (llDetectedKey(0)==llGetOwner())&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY &amp;amp;&amp;amp; flag)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state menu&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state menu&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        listen_handle=0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        if (param &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
        key toucher=llDetectedKey(0);&lt;br /&gt;
&lt;br /&gt;
        if (has_access(toucher))&lt;br /&gt;
        {&lt;br /&gt;
            make_menu(toucher);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;sorry, no access.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    listen(integer chan, string name,key id,string msg)&lt;br /&gt;
    {&lt;br /&gt;
        integer index;&lt;br /&gt;
&lt;br /&gt;
        if (menu_type == 0)          // main menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_ON)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=1;&lt;br /&gt;
                set_parcel_url(parcel_url);               &lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is ON&amp;quot;);&lt;br /&gt;
                menu_num=0;&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned on.&amp;quot;);&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=0;&lt;br /&gt;
                set_parcel_url(&amp;quot;&amp;quot;);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned off.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
                {&lt;br /&gt;
                    llGiveInventory(id,info_notecard);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                    llWhisper(0,&amp;quot;sorry, help not available.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (radio_status == 1)&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(category_list, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: genre not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    category_index=index;&lt;br /&gt;
                    llWhisper(0,&amp;quot;Genre now set to &amp;quot; + llList2String(category_list,category_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
                    menu_type=1;&lt;br /&gt;
                    menu_num=0;&lt;br /&gt;
                    make_menu(id);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (menu_type == 1 &amp;amp;&amp;amp; radio_status == 1)     // station menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(station_name, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: station not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    station_index=index;&lt;br /&gt;
                    string new_url=llList2String(station_url,station_index);&lt;br /&gt;
&lt;br /&gt;
                    if (new_url != parcel_url)&lt;br /&gt;
                    {&lt;br /&gt;
                        set_parcel_url(new_url);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        retrieve_titelinfo();&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_response(key id, integer status, list meta, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == httpreq_id)&lt;br /&gt;
        {&lt;br /&gt;
            if (status == 200)&lt;br /&gt;
            {&lt;br /&gt;
                string feed = llGetSubString(body,llSubStringIndex(body, &amp;quot;&amp;lt;body&amp;gt;&amp;quot;) + llStringLength(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;), llSubStringIndex(body,&amp;quot;&amp;lt;/body&amp;gt;&amp;quot;) - 1);&lt;br /&gt;
                list feed_list = llParseString2List(feed,[&amp;quot;,&amp;quot;],[]);&lt;br /&gt;
                string current_title_info= llList2String(feed_list,6);&lt;br /&gt;
                integer length = llGetListLength(feed_list);&lt;br /&gt;
        &lt;br /&gt;
                if(llList2String(feed_list,7))&lt;br /&gt;
                {&lt;br /&gt;
                    integer a = 7;&lt;br /&gt;
                    for(; a&amp;lt;length; ++a)&lt;br /&gt;
                    {&lt;br /&gt;
                        current_title_info += &amp;quot;, &amp;quot; + llList2String(feed_list,a);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
         &lt;br /&gt;
                if (current_title_info != last_title_info)&lt;br /&gt;
                {&lt;br /&gt;
                    last_title_info = current_title_info;&lt;br /&gt;
                    display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + current_title_info);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + no_title_info);&lt;br /&gt;
            }&lt;br /&gt;
        }    &lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY &amp;amp;&amp;amp; flag)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
// end of script&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
===Notecard format===&lt;br /&gt;
Example notecard&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# New format Shoutcast - radio controller config notecard&lt;br /&gt;
# The format is divided in 4 sections:&lt;br /&gt;
# 1 - Access configuration&lt;br /&gt;
# 2 - Ban list (keys)&lt;br /&gt;
# 3 - Categories  (same as genres)&lt;br /&gt;
# 4 - Station info (category, name, desc, url)&lt;br /&gt;
# The &#039;#&#039; character defines the start of a comment and can be anywhere on a line. &lt;br /&gt;
# Everything after the &#039;#&#039; incuding the &#039;#&#039; itself is ignored.&lt;br /&gt;
# Case is not important (but information on display will show as entered)&lt;br /&gt;
# Spaces before and/or after fields are trimmed.&lt;br /&gt;
# Empty lines are ignored.&lt;br /&gt;
&lt;br /&gt;
[ACCESS]&lt;br /&gt;
owner=yes       # yes, true,1      means owner has access. everything else not.&lt;br /&gt;
group=yes       #  ,,  ,,  ,,      means group has acess.    ,,        ,,   ,,&lt;br /&gt;
public=yes      #  ,,  ,,  ,,      means public has access.  ,,        ,,   ,, &lt;br /&gt;
&lt;br /&gt;
[BANNED]&lt;br /&gt;
# keys of banned residents&lt;br /&gt;
&lt;br /&gt;
[GENRE]&lt;br /&gt;
# genre name -- Use short genre names as the the length of menu buttons is short!&lt;br /&gt;
Hard Rock&lt;br /&gt;
Classic Rock&lt;br /&gt;
Oldies&lt;br /&gt;
Rap/Urban&lt;br /&gt;
Comedy&lt;br /&gt;
News&lt;br /&gt;
Dance&lt;br /&gt;
Country&lt;br /&gt;
Gothic&lt;br /&gt;
# etc.&lt;br /&gt;
[STATION]&lt;br /&gt;
# Shoutcast radio stations&lt;br /&gt;
# Use a &#039;|&#039; between each field - don&#039;t mind spaces before and after fields, they will be trimmed&lt;br /&gt;
# field1:genre, field2:station name, field3: station description, field4: station http://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt; or https://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;&lt;br /&gt;
# Note that genre must match case-insensitive a value previously entered in section [GENRE]&lt;br /&gt;
Classic Rock    | Absolute         |    Absolute Radio                  | http://205.188.215.226:8018&lt;br /&gt;
# etc.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===TODO===&lt;br /&gt;
&lt;br /&gt;
Planned for upcoming release 0.4:&lt;br /&gt;
* Add a llRegionSay to broadcast the &amp;lt;station&amp;gt;|&amp;lt;genre&amp;gt;|&amp;lt;current songtitle&amp;gt;|&amp;lt;url&amp;gt; to the region and add a script that displays that info on a remote Xytext board. (for use with a remote controller and/or remote display board anywhere in the region/parcel)&lt;br /&gt;
* llResetScript on owner change&lt;br /&gt;
* Relax on URL format&lt;br /&gt;
* Allow multiple genres per station&lt;/div&gt;</description>
			<pubDate>Thu, 10 Feb 2011 00:25:18 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)</comments>
		</item>
		<item>
			<title>Shoutcast - radio controller v0.3 (remake of similar scripts)</title>
			<link>https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133917</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133917</guid>
			<description>&lt;p&gt;Flennan Roffo: /* TODO */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}}&lt;br /&gt;
=Shoutcast - radio controller=&lt;br /&gt;
This script controls a shoutcast radio receiver and lets you select the stations that you configured on a notecard. Menu driven. Output of station description, genre and current song title using Xy text.&lt;br /&gt;
&lt;br /&gt;
==Versions==&lt;br /&gt;
&lt;br /&gt;
Current version: v0.3 released 10-2-2011&lt;br /&gt;
&lt;br /&gt;
==Main script==&lt;br /&gt;
&lt;br /&gt;
This script should be put into the &lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// Script:  Shoutcast - radio controller&lt;br /&gt;
// Version: 0.3 - released 10-2-2011&lt;br /&gt;
// Logic Scripts (Flennan Roffo)&lt;br /&gt;
// (c) 2010 - Flennan Roffo (Logic Scripts)&lt;br /&gt;
// &lt;br /&gt;
// This script is a remake of a couple of similar script:&lt;br /&gt;
// + LandOwnersRadio V2.0 by Scripter Coba  (( menu driven / notecard config script to select the radio station and sets parcel music url ))&lt;br /&gt;
// + Raven radio infoboard by Jamie Otis    (( worked at the basis of sis service [sis.slserver.com/sis.php] used Xy text display         ))&lt;br /&gt;
// + currentPlaying by Darkie Minotaur      (( used the /7.html info to fetch current song title info, displayed as float text            ))&lt;br /&gt;
//&lt;br /&gt;
// Purpose:&lt;br /&gt;
// * Sets the parcel audio URL and displays the channel info&lt;br /&gt;
// * Uses Xytext to display the info.&lt;br /&gt;
// * Fetches song title info from the shoutcast url&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.1 release&lt;br /&gt;
// * On/Off option&lt;br /&gt;
// * Allows multiple menus (if options per menu &amp;gt; 12) using a prev/next button&lt;br /&gt;
// * Checks if your url is well-formatted&lt;br /&gt;
// * Will delete genres for which no stations exist&lt;br /&gt;
// * Will skip stations that have same url and same genre (you can however have an identical station url under different genres).&lt;br /&gt;
// * New notecard format&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.2 release&lt;br /&gt;
// * Configurable button text&lt;br /&gt;
// * Gets parcel URL and automatically sets the genre/station and on/off status accordingly (&amp;lt;-- doesn&#039;t work)&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Update -- 0.3 release&lt;br /&gt;
// * Fixed bug (only first station in genre displayed in menu)&lt;br /&gt;
// * Auto reset script when config card updated&lt;br /&gt;
// Notes:&lt;br /&gt;
// * Expects url to be in the format: &amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;, where &amp;lt;ip&amp;gt; has the format: xxx.xxx.xxx.xxx&lt;br /&gt;
// * Deletes entries in category (genre) for which no stations are configured with notice.&lt;br /&gt;
// * Skips stations which have identical URL AND same category (genre).&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Upcoming release -- 0.4&lt;br /&gt;
// * Will add functions for remote controller(s) and remote display(s) using llRegionSay to communicate over a channel.&lt;br /&gt;
// * Should relax on the constraints about the input format of URL&#039;s (currently requires that URL has format: xxx.xxx.xxx.xxx/yyyy)&lt;br /&gt;
// * Fix button placement&lt;br /&gt;
// * Implement script reset on change of owner&lt;br /&gt;
// * Permit station to be put under multiple genres, using a comma-seperated list of genres in the section [STATION]&lt;br /&gt;
//   (currently this is only possible by duplicating the entire line and change the genre.)&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// BUGS &amp;amp; FEATURE REQUESTS&lt;br /&gt;
//&lt;br /&gt;
// Please inform the author, Logic Scripts (flennan.roffo) about any bugs or annoyances.&lt;br /&gt;
// Feature requests can also be submitted to the author.&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// LICENCE INFO&lt;br /&gt;
//&lt;br /&gt;
// This program is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string info_notecard=&amp;quot;Radio Control info&amp;quot;;              ///////    EDITABLE  \\\\\\&lt;br /&gt;
string config_notecard=&amp;quot;Radio Control config&amp;quot;;          ///////    EDITABLE  \\\\\\&lt;br /&gt;
string comment_char=&amp;quot;#&amp;quot;;                                ///////    EDITABLE  \\\\\\&lt;br /&gt;
list sep_char_list= [&amp;quot;|&amp;quot;];                              ///////    EDITABLE  \\\\\\&lt;br /&gt;
float update_time=5.0;                                  ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string no_title_info=&amp;quot;(no title info available)&amp;quot;;       ///////    EDITABLE  \\\\\\&lt;br /&gt;
&lt;br /&gt;
// not used currently - for showing info on current song title elsewhere in the region&lt;br /&gt;
integer broadcast_channel=-1234;                        ///////    EDITABLE  \\\\\\ &lt;br /&gt;
&lt;br /&gt;
// Buttons&lt;br /&gt;
&lt;br /&gt;
string button_MAIN = &amp;quot;MAIN&amp;quot;;&lt;br /&gt;
string button_HELP = &amp;quot;HELP&amp;quot;;&lt;br /&gt;
string button_NEXT = &amp;quot;&amp;gt;&amp;gt;&amp;quot;;&lt;br /&gt;
string button_PREV = &amp;quot;&amp;lt;&amp;lt;&amp;quot;;&lt;br /&gt;
string button_ON   = &amp;quot;ON&amp;quot;;&lt;br /&gt;
string button_OFF  = &amp;quot;OFF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// List of categories (=genres)&lt;br /&gt;
&lt;br /&gt;
list category_list=[];&lt;br /&gt;
&lt;br /&gt;
// List of stations. KEEP THESE LISTS IN SYNCH!&lt;br /&gt;
&lt;br /&gt;
list station_category=[];&lt;br /&gt;
list station_name=[];&lt;br /&gt;
list station_desc=[];&lt;br /&gt;
list station_url=[];&lt;br /&gt;
&lt;br /&gt;
// Last song title played&lt;br /&gt;
string last_title_info=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
integer radio_status=0;    // 0 - OFF   1 - ON&lt;br /&gt;
string parcel_url=&amp;quot;&amp;quot;;&lt;br /&gt;
integer lineno=0;&lt;br /&gt;
key reqid=NULL_KEY;&lt;br /&gt;
key httpreq_id=NULL_KEY;&lt;br /&gt;
integer config_error=FALSE;&lt;br /&gt;
integer flag;&lt;br /&gt;
integer section=0;&lt;br /&gt;
&lt;br /&gt;
// Access values. Note that users who are banned can not access the device even when access is public&lt;br /&gt;
integer owner_access=TRUE;&lt;br /&gt;
integer group_access=FALSE;&lt;br /&gt;
integer public_access=TRUE;&lt;br /&gt;
list banned_keys=[];&lt;br /&gt;
&lt;br /&gt;
// Channels for menu and user input&lt;br /&gt;
integer menu_channel;&lt;br /&gt;
integer listen_handle;&lt;br /&gt;
&lt;br /&gt;
// Menu&lt;br /&gt;
integer menu_type=0;         // 0 - Main menu (genres)   1 - Station menu (stations)&lt;br /&gt;
integer menu_num=0;          // When more menu options need to be selectable then can be displayed on a menu (12), this is the menu number - menu number 0 is the first menu.&lt;br /&gt;
&lt;br /&gt;
// Genres and stations&lt;br /&gt;
&lt;br /&gt;
integer category_index=0;    // Current index in category_list  (genre)&lt;br /&gt;
integer station_index=0;     // Current index in station_*      (station)&lt;br /&gt;
&lt;br /&gt;
integer num_categories=0;&lt;br /&gt;
integer num_stations=0;&lt;br /&gt;
&lt;br /&gt;
// Make request for title info using HTTP request&lt;br /&gt;
retrieve_titelinfo()&lt;br /&gt;
{&lt;br /&gt;
    string url=llList2String(station_url,station_index);&lt;br /&gt;
    httpreq_id=llHTTPRequest(url + &amp;quot;/7.html  HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n&amp;quot;,[],&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Display a line on an Xytext device linked in&lt;br /&gt;
display_line(string line, string message)&lt;br /&gt;
{&lt;br /&gt;
    // Setup XYtext Variables&lt;br /&gt;
    integer DISPLAY_STRING      = 204000; &lt;br /&gt;
//    integer DISPLAY_EXTENDED    = 204001;     (not used)&lt;br /&gt;
//    integer REMAP_INDICES       = 204002;     (not used) &lt;br /&gt;
//    integer RESET_INDICES       = 204003;     (not used)&lt;br /&gt;
//    integer SET_CELL_INFO       = 204004;     (not used)&lt;br /&gt;
//    integer SET_FONT_TEXTURE    = 204005;     (not used)&lt;br /&gt;
//    integer SET_THICKNESS       = 204006;     (not used)&lt;br /&gt;
//    integer SET_COLOR           = 204007;     (not used)&lt;br /&gt;
&lt;br /&gt;
    llMessageLinked(LINK_SET,DISPLAY_STRING,message,line);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Clear the Xytext display&lt;br /&gt;
clear_display() &lt;br /&gt;
{&lt;br /&gt;
    // Clears the display&lt;br /&gt;
    display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio Station ID&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;2&amp;quot;,&amp;quot;Music Genre....&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;3&amp;quot;,&amp;quot;Now Playing....&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Make a menu / dialog&lt;br /&gt;
make_menu(key id)&lt;br /&gt;
{&lt;br /&gt;
     menu_channel=random_channel();&lt;br /&gt;
&lt;br /&gt;
    if (radio_status == 0)&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        llDialog(id,&amp;quot;Menu: Status\n\nRadio is OFF&amp;quot;, [ &amp;quot;ON&amp;quot;, &amp;quot;HELP&amp;quot; ],menu_channel);&lt;br /&gt;
    }&lt;br /&gt;
    else &lt;br /&gt;
    {&lt;br /&gt;
        if (menu_type ==0)&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Genres&amp;quot;, category_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Stations\nGenre: &amp;quot; + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (listen_handle != 0)    llListenRemove(listen_handle);&lt;br /&gt;
    listen_handle=llListen(menu_channel,&amp;quot;&amp;quot;,id,&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Make the menu option list for menu: catagories (genres)&lt;br /&gt;
list category_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
&lt;br /&gt;
    if (len &amp;gt; 9)   // If more then 9 items (12 minus the 3 buttons for MAIN/HELP and PREV, NEXT)&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;   // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc. &lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt; last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
&lt;br /&gt;
             while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_HELP;&lt;br /&gt;
             else&lt;br /&gt;
                 menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_OFF;&lt;br /&gt;
             else&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num != last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;       &lt;br /&gt;
        }            &lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
        menu+=(list)button_OFF;&lt;br /&gt;
        menu+=(list)button_HELP;&lt;br /&gt;
    }        &lt;br /&gt;
    &lt;br /&gt;
    return menu;    // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns the number of stations in a certain category&lt;br /&gt;
integer stations_in_category(integer cat)&lt;br /&gt;
{&lt;br /&gt;
    integer count=0;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
    string category=llList2String(category_list,cat);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (category == llList2String(category_list,i))&lt;br /&gt;
            count++;&lt;br /&gt;
&lt;br /&gt;
    return count;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Not used currently -- to fix button placement&lt;br /&gt;
list order_buttons(list buttons)&lt;br /&gt;
{&lt;br /&gt;
    integer offset;&lt;br /&gt;
    list fixt;&lt;br /&gt;
    integer flag=0;&lt;br /&gt;
&lt;br /&gt;
    while((offset = llGetListLength(buttons)))&lt;br /&gt;
    {&lt;br /&gt;
        if (offset &amp;gt; 3)&lt;br /&gt;
            flag=1;&lt;br /&gt;
        else&lt;br /&gt;
            flag=0;&lt;br /&gt;
&lt;br /&gt;
        fixt += llList2List(buttons, offset = -3 * flag, -1);&lt;br /&gt;
        buttons = llDeleteSubList(buttons, offset, -1);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return fixt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns a list of station names in a certain category (genre)&lt;br /&gt;
list station_list(integer category)&lt;br /&gt;
{&lt;br /&gt;
    list s=[];&lt;br /&gt;
    integer i;&lt;br /&gt;
    string cname=llList2String(category_list,category_index);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; llGetListLength(station_name); i++)&lt;br /&gt;
        if (llList2String(station_category,i) == cname)&lt;br /&gt;
            s+=(list)llList2String(station_name,i);&lt;br /&gt;
&lt;br /&gt;
    return s;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns the list of stations for the station menu, depending on the submenu number&lt;br /&gt;
list station_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
    list stations=station_list(category_index);&lt;br /&gt;
    integer len=llGetListLength(stations);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
        &lt;br /&gt;
    if (len &amp;gt; 11)       // 12 - 1 for MAIN menu&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;&lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt;= last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
             integer last=9*num+8;&lt;br /&gt;
&lt;br /&gt;
             menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;gt; 0)&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;lt; last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;                      &lt;br /&gt;
&lt;br /&gt;
            if (len &amp;gt; last)&lt;br /&gt;
                len =last;&lt;br /&gt;
                &lt;br /&gt;
            while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(stations,len);&lt;br /&gt;
        }&lt;br /&gt;
    }            &lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(stations,len);&lt;br /&gt;
    }        &lt;br /&gt;
&lt;br /&gt;
    return menu; // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns whether av with key id has access&lt;br /&gt;
integer has_access(key id)&lt;br /&gt;
{&lt;br /&gt;
    if (llListFindList(banned_keys,(list)id) != -1)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    if (owner_access &amp;amp;&amp;amp; id == llGetOwner())&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (group_access &amp;amp;&amp;amp; llSameGroup(id))&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (public_access)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Gets a random channel -- uses a wide range of big negative channel numbers seldomly used&lt;br /&gt;
integer random_channel()&lt;br /&gt;
{&lt;br /&gt;
    integer min=-2147483647;&lt;br /&gt;
    integer max=-1000;&lt;br /&gt;
&lt;br /&gt;
    return (integer) (min + llFrand(max-min));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Check for the format of the url string  -- is very selective about url format&lt;br /&gt;
// expects:   xxx.xxx.xxx.xxx:xxxx    (ip adress in number notation with port adress)&lt;br /&gt;
// Next release will relax on this constraint.&lt;br /&gt;
integer check_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    integer pos=0;&lt;br /&gt;
&lt;br /&gt;
    if (llGetSubString(url,0,6) == &amp;quot;http://&amp;quot;)&lt;br /&gt;
        pos=7;        &lt;br /&gt;
    if (llGetSubString(url,0,7) == &amp;quot;https://&amp;quot;)&lt;br /&gt;
        pos=8;&lt;br /&gt;
&lt;br /&gt;
    if (pos==0)   return FALSE;&lt;br /&gt;
&lt;br /&gt;
    string str_ip_port=llGetSubString(url,pos,-1);&lt;br /&gt;
    list list_ip_port=llParseString2List(str_ip_port,[&amp;quot;:&amp;quot;],[]);                 // split in ip-adress and port&lt;br /&gt;
    list list_ip=llParseString2List(llList2String(list_ip_port,0),[&amp;quot;.&amp;quot;],[]);    // split ip-adress elements&lt;br /&gt;
&lt;br /&gt;
    if (llGetListLength(list_ip_port) != 2 || llGetListLength(list_ip) != 4)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer test;&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;4;i++)&lt;br /&gt;
    {&lt;br /&gt;
        test=llList2Integer(list_ip,i);&lt;br /&gt;
        if (llList2String(list_ip,i) != (string)test)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        if (test &amp;lt; 0 || test &amp;gt; 255)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    test=llList2Integer(list_ip_port,1);&lt;br /&gt;
    if (llList2String(list_ip_port,1) != (string)test)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns a true value depending on the first character in input - anything else is assumed false.&lt;br /&gt;
integer true_value(string input)&lt;br /&gt;
{&lt;br /&gt;
    string value=llToLower(llGetSubString(input,0,0));&lt;br /&gt;
&lt;br /&gt;
    if (value == &amp;quot;y&amp;quot; || value == &amp;quot;t&amp;quot; || value ==&amp;quot;1&amp;quot;)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Return if more input should be processed (if not at EOF) - sets ConfigError if any config error found.&lt;br /&gt;
integer process_line(string dataline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(dataline,STRING_TRIM);&lt;br /&gt;
    integer index=llSubStringIndex(line,comment_char);&lt;br /&gt;
    &lt;br /&gt;
    if (index==0)       // line starts with comment - ignore line&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (index!=-1)&lt;br /&gt;
        line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL);   // skip everything after comment_char and trim tail&lt;br /&gt;
&lt;br /&gt;
    if (line==&amp;quot;&amp;quot;)       // Ignore blank lines&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (llToLower(line) == &amp;quot;[access]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 1;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[banned]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 2;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[genre]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 3;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[station]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 4;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llGetSubString(line,0,0) == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; llGetSubString(line,-1,-1) == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: malformed section found at line &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
        config_error=TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: no section found on line: &amp;quot; + (string) lineno);&lt;br /&gt;
        config_error = TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    list breakup=llParseString2List(line,[&amp;quot;=&amp;quot;],[]);&lt;br /&gt;
    string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);&lt;br /&gt;
    string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);&lt;br /&gt;
&lt;br /&gt;
    if (section == 1)            // access&lt;br /&gt;
    {&lt;br /&gt;
        field=llToLower(field);&lt;br /&gt;
&lt;br /&gt;
        if (field==&amp;quot;owner&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            owner_access=true_value(values);                       &lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;group&amp;quot;)&lt;br /&gt;
        {    &lt;br /&gt;
            group_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;public&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            public_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: invalid option on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 2)         // ban list&lt;br /&gt;
    {&lt;br /&gt;
        key try=(key) field;&lt;br /&gt;
&lt;br /&gt;
        if (try)&lt;br /&gt;
        {&lt;br /&gt;
            banned_keys+=(list)((key) field);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 3)           // categories&lt;br /&gt;
    {&lt;br /&gt;
        if (llListFindList(category_list,(list)field) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            category_list+=(list)field;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;genre: &#039;&amp;quot; + field + &amp;quot;&#039; already entered; double entry skipped.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 4)            // stations&lt;br /&gt;
    {&lt;br /&gt;
        list parse=llParseString2List(line,sep_char_list, []);&lt;br /&gt;
        string category=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);&lt;br /&gt;
        string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);&lt;br /&gt;
    &lt;br /&gt;
        if (!available_category(category))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: unknown genre on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (check_url(url))&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                num_stations++;&lt;br /&gt;
                station_category+=(list)category;&lt;br /&gt;
                station_name+=(list)name;&lt;br /&gt;
                station_desc+=(list)desc;&lt;br /&gt;
                station_url+=(list)url;&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llWhisper(0,&amp;quot;This station is already entered under the same genre and same url and is skipped.\nStation: &amp;quot; + name + &amp;quot;\nGenre: &#039;&amp;quot; + category + &amp;quot;&#039;\nURL: &amp;quot; + url);&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: malformed url on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
     &lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Sets the parcel URL and updates the display&lt;br /&gt;
set_parcel_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    parcel_url=url;&lt;br /&gt;
    llSetParcelMusicURL(parcel_url);&lt;br /&gt;
&lt;br /&gt;
    if (parcel_url==&amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        clear_display();&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is OFF&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;station now set to &amp;quot; + llList2String(station_desc,station_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Station: &amp;quot; + llList2String(station_desc,station_index));&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;Genre  : &amp;quot; + llList2String(category_list,category_index));&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;Now playing.....&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns if a category (genre) exists.&lt;br /&gt;
integer available_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;len;i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(category_list,i)))&lt;br /&gt;
            return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns if a category (genre) is empty   (NOTE: same function as available_category(), but logical negate of it. One of these can be removed.)&lt;br /&gt;
integer empty_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(station_category,i)))&lt;br /&gt;
            return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Removes categories (genres) for which no station is known.&lt;br /&gt;
skip_empty_categories()&lt;br /&gt;
{&lt;br /&gt;
    integer i=0;&lt;br /&gt;
&lt;br /&gt;
    while (i&amp;lt;llGetListLength(category_list))&lt;br /&gt;
    {&lt;br /&gt;
        if (empty_category(llList2String(category_list,i)))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;Warning: Genre &#039;&amp;quot; + llList2String(category_list,i) + &amp;quot;&#039; contains no stations and is deleted.&amp;quot;);&lt;br /&gt;
            category_list=llDeleteSubList(category_list,i,i);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            i++;&lt;br /&gt;
    }&lt;br /&gt;
            &lt;br /&gt;
    num_categories=llGetListLength(category_list);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state default&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        flag=FALSE;&lt;br /&gt;
        lineno=0;&lt;br /&gt;
        config_error=FALSE;&lt;br /&gt;
        num_stations=0;&lt;br /&gt;
        num_categories=0;&lt;br /&gt;
        radio_status=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(config_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
           reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
           llWhisper(0, &amp;quot;Reading config notecard...&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;1&amp;quot;,&amp;quot;Reading configuration.&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;2&amp;quot;,&amp;quot;Wait....&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;No config notecard &#039;&amp;quot; +  config_notecard + &amp;quot;&#039; present.&amp;quot;);&lt;br /&gt;
            state offline;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (reqid==id)&lt;br /&gt;
        {        &lt;br /&gt;
            if (data==EOF)&lt;br /&gt;
            {&lt;br /&gt;
                skip_empty_categories();&lt;br /&gt;
                llWhisper(0,&amp;quot;Configuration ok.\n&amp;quot; + (string)num_categories + &amp;quot; genres and &amp;quot; + (string)num_stations + &amp;quot; stations.&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Configuration OK&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;2&amp;quot;,&amp;quot;Genres  : &amp;quot; + (string)num_categories);&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Stations: &amp;quot; + (string)num_stations);&lt;br /&gt;
                state menu;&lt;br /&gt;
            }&lt;br /&gt;
            else &lt;br /&gt;
            {&lt;br /&gt;
                if (process_line(data))&lt;br /&gt;
                    reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
                else if (config_error)&lt;br /&gt;
                {&lt;br /&gt;
                    llWhisper(0,&amp;quot;errors found in configuration. please correct them.&amp;quot;);&lt;br /&gt;
                    state offline;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state offline&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state offline&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;Reset on owner touch or when notecard updated.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    touch_start(integer t)&lt;br /&gt;
    {&lt;br /&gt;
        if (llDetectedKey(0)==llGetOwner())&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY &amp;amp;&amp;amp; flag)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state menu&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state menu&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        listen_handle=0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        if (param &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
        key toucher=llDetectedKey(0);&lt;br /&gt;
&lt;br /&gt;
        if (has_access(toucher))&lt;br /&gt;
        {&lt;br /&gt;
            make_menu(toucher);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;sorry, no access.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    listen(integer chan, string name,key id,string msg)&lt;br /&gt;
    {&lt;br /&gt;
        integer index;&lt;br /&gt;
&lt;br /&gt;
        if (menu_type == 0)          // main menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_ON)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=1;&lt;br /&gt;
                set_parcel_url(parcel_url);               &lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is ON&amp;quot;);&lt;br /&gt;
                menu_num=0;&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned on.&amp;quot;);&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=0;&lt;br /&gt;
                set_parcel_url(&amp;quot;&amp;quot;);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned off.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
                {&lt;br /&gt;
                    llGiveInventory(id,info_notecard);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                    llWhisper(0,&amp;quot;sorry, help not available.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (radio_status == 1)&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(category_list, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: genre not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    category_index=index;&lt;br /&gt;
                    llWhisper(0,&amp;quot;Genre now set to &amp;quot; + llList2String(category_list,category_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
                    menu_type=1;&lt;br /&gt;
                    menu_num=0;&lt;br /&gt;
                    make_menu(id);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (menu_type == 1 &amp;amp;&amp;amp; radio_status == 1)     // station menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(station_name, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: station not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    station_index=index;&lt;br /&gt;
                    string new_url=llList2String(station_url,station_index);&lt;br /&gt;
&lt;br /&gt;
                    if (new_url != parcel_url)&lt;br /&gt;
                    {&lt;br /&gt;
                        set_parcel_url(new_url);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        retrieve_titelinfo();&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_response(key id, integer status, list meta, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == httpreq_id)&lt;br /&gt;
        {&lt;br /&gt;
            if (status == 200)&lt;br /&gt;
            {&lt;br /&gt;
                string feed = llGetSubString(body,llSubStringIndex(body, &amp;quot;&amp;lt;body&amp;gt;&amp;quot;) + llStringLength(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;), llSubStringIndex(body,&amp;quot;&amp;lt;/body&amp;gt;&amp;quot;) - 1);&lt;br /&gt;
                list feed_list = llParseString2List(feed,[&amp;quot;,&amp;quot;],[]);&lt;br /&gt;
                string current_title_info= llList2String(feed_list,6);&lt;br /&gt;
                integer length = llGetListLength(feed_list);&lt;br /&gt;
        &lt;br /&gt;
                if(llList2String(feed_list,7))&lt;br /&gt;
                {&lt;br /&gt;
                    integer a = 7;&lt;br /&gt;
                    for(; a&amp;lt;length; ++a)&lt;br /&gt;
                    {&lt;br /&gt;
                        current_title_info += &amp;quot;, &amp;quot; + llList2String(feed_list,a);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
         &lt;br /&gt;
                if (current_title_info != last_title_info)&lt;br /&gt;
                {&lt;br /&gt;
                    last_title_info = current_title_info;&lt;br /&gt;
                    display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + current_title_info);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + no_title_info);&lt;br /&gt;
            }&lt;br /&gt;
        }    &lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY &amp;amp;&amp;amp; flag)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
// end of script&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
===Notecard format===&lt;br /&gt;
Example notecard&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# New format Shoutcast - radio controller config notecard&lt;br /&gt;
# The format is divided in 4 sections:&lt;br /&gt;
# 1 - Access configuration&lt;br /&gt;
# 2 - Ban list (keys)&lt;br /&gt;
# 3 - Categories  (same as genres)&lt;br /&gt;
# 4 - Station info (category, name, desc, url)&lt;br /&gt;
# The &#039;#&#039; character defines the start of a comment and can be anywhere on a line. &lt;br /&gt;
# Everything after the &#039;#&#039; incuding the &#039;#&#039; itself is ignored.&lt;br /&gt;
# Case is not important (but information on display will show as entered)&lt;br /&gt;
# Spaces before and/or after fields are trimmed.&lt;br /&gt;
# Empty lines are ignored.&lt;br /&gt;
&lt;br /&gt;
[ACCESS]&lt;br /&gt;
owner=yes       # yes, true,1      means owner has access. everything else not.&lt;br /&gt;
group=yes       #  ,,  ,,  ,,      means group has acess.    ,,        ,,   ,,&lt;br /&gt;
public=yes      #  ,,  ,,  ,,      means public has access.  ,,        ,,   ,, &lt;br /&gt;
&lt;br /&gt;
[BANNED]&lt;br /&gt;
# keys of banned residents&lt;br /&gt;
&lt;br /&gt;
[GENRE]&lt;br /&gt;
# genre name&lt;br /&gt;
Hard Rock&lt;br /&gt;
Classic Rock&lt;br /&gt;
Oldies&lt;br /&gt;
Rap/Urban&lt;br /&gt;
Comedy&lt;br /&gt;
News&lt;br /&gt;
Dance&lt;br /&gt;
Country&lt;br /&gt;
Gothic&lt;br /&gt;
# etc.&lt;br /&gt;
[STATION]&lt;br /&gt;
# Shoutcast radio stations&lt;br /&gt;
# Use a &#039;|&#039; between each field - don&#039;t mind spaces before and after fields, they will be trimmed&lt;br /&gt;
# field1:genre, field2:station name, field3: station description, field4: station http://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt; or https://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;&lt;br /&gt;
# Note that genre must match case-insensitive a value previously entered in section [GENRE]&lt;br /&gt;
Classic Rock    | Absolute         |    Absolute Radio                  | http://205.188.215.226:8018&lt;br /&gt;
# etc.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===TODO===&lt;br /&gt;
&lt;br /&gt;
Planned for upcoming release 0.4:&lt;br /&gt;
* Add a llRegionSay to broadcast the &amp;lt;station&amp;gt;|&amp;lt;genre&amp;gt;|&amp;lt;current songtitle&amp;gt;|&amp;lt;url&amp;gt; to the region and add a script that displays that info on a remote Xytext board. (for use with a remote controller and/or remote display board anywhere in the region/parcel)&lt;br /&gt;
* llResetScript on owner change&lt;br /&gt;
* Relax on URL format&lt;br /&gt;
* Allow multiple genres per station&lt;/div&gt;</description>
			<pubDate>Thu, 10 Feb 2011 00:22:21 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)</comments>
		</item>
		<item>
			<title>Shoutcast - radio controller v0.3 (remake of similar scripts)</title>
			<link>https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133916</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133916</guid>
			<description>&lt;p&gt;Flennan Roffo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}}&lt;br /&gt;
=Shoutcast - radio controller=&lt;br /&gt;
This script controls a shoutcast radio receiver and lets you select the stations that you configured on a notecard. Menu driven. Output of station description, genre and current song title using Xy text.&lt;br /&gt;
&lt;br /&gt;
==Versions==&lt;br /&gt;
&lt;br /&gt;
Current version: v0.3 released 10-2-2011&lt;br /&gt;
&lt;br /&gt;
==Main script==&lt;br /&gt;
&lt;br /&gt;
This script should be put into the &lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// Script:  Shoutcast - radio controller&lt;br /&gt;
// Version: 0.3 - released 10-2-2011&lt;br /&gt;
// Logic Scripts (Flennan Roffo)&lt;br /&gt;
// (c) 2010 - Flennan Roffo (Logic Scripts)&lt;br /&gt;
// &lt;br /&gt;
// This script is a remake of a couple of similar script:&lt;br /&gt;
// + LandOwnersRadio V2.0 by Scripter Coba  (( menu driven / notecard config script to select the radio station and sets parcel music url ))&lt;br /&gt;
// + Raven radio infoboard by Jamie Otis    (( worked at the basis of sis service [sis.slserver.com/sis.php] used Xy text display         ))&lt;br /&gt;
// + currentPlaying by Darkie Minotaur      (( used the /7.html info to fetch current song title info, displayed as float text            ))&lt;br /&gt;
//&lt;br /&gt;
// Purpose:&lt;br /&gt;
// * Sets the parcel audio URL and displays the channel info&lt;br /&gt;
// * Uses Xytext to display the info.&lt;br /&gt;
// * Fetches song title info from the shoutcast url&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.1 release&lt;br /&gt;
// * On/Off option&lt;br /&gt;
// * Allows multiple menus (if options per menu &amp;gt; 12) using a prev/next button&lt;br /&gt;
// * Checks if your url is well-formatted&lt;br /&gt;
// * Will delete genres for which no stations exist&lt;br /&gt;
// * Will skip stations that have same url and same genre (you can however have an identical station url under different genres).&lt;br /&gt;
// * New notecard format&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.2 release&lt;br /&gt;
// * Configurable button text&lt;br /&gt;
// * Gets parcel URL and automatically sets the genre/station and on/off status accordingly (&amp;lt;-- doesn&#039;t work)&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Update -- 0.3 release&lt;br /&gt;
// * Fixed bug (only first station in genre displayed in menu)&lt;br /&gt;
// * Auto reset script when config card updated&lt;br /&gt;
// Notes:&lt;br /&gt;
// * Expects url to be in the format: &amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;, where &amp;lt;ip&amp;gt; has the format: xxx.xxx.xxx.xxx&lt;br /&gt;
// * Deletes entries in category (genre) for which no stations are configured with notice.&lt;br /&gt;
// * Skips stations which have identical URL AND same category (genre).&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Upcoming release -- 0.4&lt;br /&gt;
// * Will add functions for remote controller(s) and remote display(s) using llRegionSay to communicate over a channel.&lt;br /&gt;
// * Should relax on the constraints about the input format of URL&#039;s (currently requires that URL has format: xxx.xxx.xxx.xxx/yyyy)&lt;br /&gt;
// * Fix button placement&lt;br /&gt;
// * Implement script reset on change of owner&lt;br /&gt;
// * Permit station to be put under multiple genres, using a comma-seperated list of genres in the section [STATION]&lt;br /&gt;
//   (currently this is only possible by duplicating the entire line and change the genre.)&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// BUGS &amp;amp; FEATURE REQUESTS&lt;br /&gt;
//&lt;br /&gt;
// Please inform the author, Logic Scripts (flennan.roffo) about any bugs or annoyances.&lt;br /&gt;
// Feature requests can also be submitted to the author.&lt;br /&gt;
/////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// LICENCE INFO&lt;br /&gt;
//&lt;br /&gt;
// This program is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string info_notecard=&amp;quot;Radio Control info&amp;quot;;              ///////    EDITABLE  \\\\\\&lt;br /&gt;
string config_notecard=&amp;quot;Radio Control config&amp;quot;;          ///////    EDITABLE  \\\\\\&lt;br /&gt;
string comment_char=&amp;quot;#&amp;quot;;                                ///////    EDITABLE  \\\\\\&lt;br /&gt;
list sep_char_list= [&amp;quot;|&amp;quot;];                              ///////    EDITABLE  \\\\\\&lt;br /&gt;
float update_time=5.0;                                  ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string no_title_info=&amp;quot;(no title info available)&amp;quot;;       ///////    EDITABLE  \\\\\\&lt;br /&gt;
&lt;br /&gt;
// not used currently - for showing info on current song title elsewhere in the region&lt;br /&gt;
integer broadcast_channel=-1234;                        ///////    EDITABLE  \\\\\\ &lt;br /&gt;
&lt;br /&gt;
// Buttons&lt;br /&gt;
&lt;br /&gt;
string button_MAIN = &amp;quot;MAIN&amp;quot;;&lt;br /&gt;
string button_HELP = &amp;quot;HELP&amp;quot;;&lt;br /&gt;
string button_NEXT = &amp;quot;&amp;gt;&amp;gt;&amp;quot;;&lt;br /&gt;
string button_PREV = &amp;quot;&amp;lt;&amp;lt;&amp;quot;;&lt;br /&gt;
string button_ON   = &amp;quot;ON&amp;quot;;&lt;br /&gt;
string button_OFF  = &amp;quot;OFF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// List of categories (=genres)&lt;br /&gt;
&lt;br /&gt;
list category_list=[];&lt;br /&gt;
&lt;br /&gt;
// List of stations. KEEP THESE LISTS IN SYNCH!&lt;br /&gt;
&lt;br /&gt;
list station_category=[];&lt;br /&gt;
list station_name=[];&lt;br /&gt;
list station_desc=[];&lt;br /&gt;
list station_url=[];&lt;br /&gt;
&lt;br /&gt;
// Last song title played&lt;br /&gt;
string last_title_info=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
integer radio_status=0;    // 0 - OFF   1 - ON&lt;br /&gt;
string parcel_url=&amp;quot;&amp;quot;;&lt;br /&gt;
integer lineno=0;&lt;br /&gt;
key reqid=NULL_KEY;&lt;br /&gt;
key httpreq_id=NULL_KEY;&lt;br /&gt;
integer config_error=FALSE;&lt;br /&gt;
integer flag;&lt;br /&gt;
integer section=0;&lt;br /&gt;
&lt;br /&gt;
// Access values. Note that users who are banned can not access the device even when access is public&lt;br /&gt;
integer owner_access=TRUE;&lt;br /&gt;
integer group_access=FALSE;&lt;br /&gt;
integer public_access=TRUE;&lt;br /&gt;
list banned_keys=[];&lt;br /&gt;
&lt;br /&gt;
// Channels for menu and user input&lt;br /&gt;
integer menu_channel;&lt;br /&gt;
integer listen_handle;&lt;br /&gt;
&lt;br /&gt;
// Menu&lt;br /&gt;
integer menu_type=0;         // 0 - Main menu (genres)   1 - Station menu (stations)&lt;br /&gt;
integer menu_num=0;          // When more menu options need to be selectable then can be displayed on a menu (12), this is the menu number - menu number 0 is the first menu.&lt;br /&gt;
&lt;br /&gt;
// Genres and stations&lt;br /&gt;
&lt;br /&gt;
integer category_index=0;    // Current index in category_list  (genre)&lt;br /&gt;
integer station_index=0;     // Current index in station_*      (station)&lt;br /&gt;
&lt;br /&gt;
integer num_categories=0;&lt;br /&gt;
integer num_stations=0;&lt;br /&gt;
&lt;br /&gt;
// Make request for title info using HTTP request&lt;br /&gt;
retrieve_titelinfo()&lt;br /&gt;
{&lt;br /&gt;
    string url=llList2String(station_url,station_index);&lt;br /&gt;
    httpreq_id=llHTTPRequest(url + &amp;quot;/7.html  HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n&amp;quot;,[],&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Display a line on an Xytext device linked in&lt;br /&gt;
display_line(string line, string message)&lt;br /&gt;
{&lt;br /&gt;
    // Setup XYtext Variables&lt;br /&gt;
    integer DISPLAY_STRING      = 204000; &lt;br /&gt;
//    integer DISPLAY_EXTENDED    = 204001;     (not used)&lt;br /&gt;
//    integer REMAP_INDICES       = 204002;     (not used) &lt;br /&gt;
//    integer RESET_INDICES       = 204003;     (not used)&lt;br /&gt;
//    integer SET_CELL_INFO       = 204004;     (not used)&lt;br /&gt;
//    integer SET_FONT_TEXTURE    = 204005;     (not used)&lt;br /&gt;
//    integer SET_THICKNESS       = 204006;     (not used)&lt;br /&gt;
//    integer SET_COLOR           = 204007;     (not used)&lt;br /&gt;
&lt;br /&gt;
    llMessageLinked(LINK_SET,DISPLAY_STRING,message,line);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Clear the Xytext display&lt;br /&gt;
clear_display() &lt;br /&gt;
{&lt;br /&gt;
    // Clears the display&lt;br /&gt;
    display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio Station ID&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;2&amp;quot;,&amp;quot;Music Genre....&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;3&amp;quot;,&amp;quot;Now Playing....&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Make a menu / dialog&lt;br /&gt;
make_menu(key id)&lt;br /&gt;
{&lt;br /&gt;
     menu_channel=random_channel();&lt;br /&gt;
&lt;br /&gt;
    if (radio_status == 0)&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        llDialog(id,&amp;quot;Menu: Status\n\nRadio is OFF&amp;quot;, [ &amp;quot;ON&amp;quot;, &amp;quot;HELP&amp;quot; ],menu_channel);&lt;br /&gt;
    }&lt;br /&gt;
    else &lt;br /&gt;
    {&lt;br /&gt;
        if (menu_type ==0)&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Genres&amp;quot;, category_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Stations\nGenre: &amp;quot; + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (listen_handle != 0)    llListenRemove(listen_handle);&lt;br /&gt;
    listen_handle=llListen(menu_channel,&amp;quot;&amp;quot;,id,&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Make the menu option list for menu: catagories (genres)&lt;br /&gt;
list category_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
&lt;br /&gt;
    if (len &amp;gt; 9)   // If more then 9 items (12 minus the 3 buttons for MAIN/HELP and PREV, NEXT)&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;   // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc. &lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt; last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
&lt;br /&gt;
             while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_HELP;&lt;br /&gt;
             else&lt;br /&gt;
                 menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_OFF;&lt;br /&gt;
             else&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num != last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;       &lt;br /&gt;
        }            &lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
        menu+=(list)button_OFF;&lt;br /&gt;
        menu+=(list)button_HELP;&lt;br /&gt;
    }        &lt;br /&gt;
    &lt;br /&gt;
    return menu;    // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns the number of stations in a certain category&lt;br /&gt;
integer stations_in_category(integer cat)&lt;br /&gt;
{&lt;br /&gt;
    integer count=0;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
    string category=llList2String(category_list,cat);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (category == llList2String(category_list,i))&lt;br /&gt;
            count++;&lt;br /&gt;
&lt;br /&gt;
    return count;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Not used currently -- to fix button placement&lt;br /&gt;
list order_buttons(list buttons)&lt;br /&gt;
{&lt;br /&gt;
    integer offset;&lt;br /&gt;
    list fixt;&lt;br /&gt;
    integer flag=0;&lt;br /&gt;
&lt;br /&gt;
    while((offset = llGetListLength(buttons)))&lt;br /&gt;
    {&lt;br /&gt;
        if (offset &amp;gt; 3)&lt;br /&gt;
            flag=1;&lt;br /&gt;
        else&lt;br /&gt;
            flag=0;&lt;br /&gt;
&lt;br /&gt;
        fixt += llList2List(buttons, offset = -3 * flag, -1);&lt;br /&gt;
        buttons = llDeleteSubList(buttons, offset, -1);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return fixt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns a list of station names in a certain category (genre)&lt;br /&gt;
list station_list(integer category)&lt;br /&gt;
{&lt;br /&gt;
    list s=[];&lt;br /&gt;
    integer i;&lt;br /&gt;
    string cname=llList2String(category_list,category_index);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; llGetListLength(station_name); i++)&lt;br /&gt;
        if (llList2String(station_category,i) == cname)&lt;br /&gt;
            s+=(list)llList2String(station_name,i);&lt;br /&gt;
&lt;br /&gt;
    return s;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns the list of stations for the station menu, depending on the submenu number&lt;br /&gt;
list station_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
    list stations=station_list(category_index);&lt;br /&gt;
    integer len=llGetListLength(stations);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
        &lt;br /&gt;
    if (len &amp;gt; 11)       // 12 - 1 for MAIN menu&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;&lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt;= last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
             integer last=9*num+8;&lt;br /&gt;
&lt;br /&gt;
             menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;gt; 0)&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;lt; last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;                      &lt;br /&gt;
&lt;br /&gt;
            if (len &amp;gt; last)&lt;br /&gt;
                len =last;&lt;br /&gt;
                &lt;br /&gt;
            while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(stations,len);&lt;br /&gt;
        }&lt;br /&gt;
    }            &lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(stations,len);&lt;br /&gt;
    }        &lt;br /&gt;
&lt;br /&gt;
    return menu; // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns whether av with key id has access&lt;br /&gt;
integer has_access(key id)&lt;br /&gt;
{&lt;br /&gt;
    if (llListFindList(banned_keys,(list)id) != -1)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    if (owner_access &amp;amp;&amp;amp; id == llGetOwner())&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (group_access &amp;amp;&amp;amp; llSameGroup(id))&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (public_access)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Gets a random channel -- uses a wide range of big negative channel numbers seldomly used&lt;br /&gt;
integer random_channel()&lt;br /&gt;
{&lt;br /&gt;
    integer min=-2147483647;&lt;br /&gt;
    integer max=-1000;&lt;br /&gt;
&lt;br /&gt;
    return (integer) (min + llFrand(max-min));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Check for the format of the url string  -- is very selective about url format&lt;br /&gt;
// expects:   xxx.xxx.xxx.xxx:xxxx    (ip adress in number notation with port adress)&lt;br /&gt;
// Next release will relax on this constraint.&lt;br /&gt;
integer check_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    integer pos=0;&lt;br /&gt;
&lt;br /&gt;
    if (llGetSubString(url,0,6) == &amp;quot;http://&amp;quot;)&lt;br /&gt;
        pos=7;        &lt;br /&gt;
    if (llGetSubString(url,0,7) == &amp;quot;https://&amp;quot;)&lt;br /&gt;
        pos=8;&lt;br /&gt;
&lt;br /&gt;
    if (pos==0)   return FALSE;&lt;br /&gt;
&lt;br /&gt;
    string str_ip_port=llGetSubString(url,pos,-1);&lt;br /&gt;
    list list_ip_port=llParseString2List(str_ip_port,[&amp;quot;:&amp;quot;],[]);                 // split in ip-adress and port&lt;br /&gt;
    list list_ip=llParseString2List(llList2String(list_ip_port,0),[&amp;quot;.&amp;quot;],[]);    // split ip-adress elements&lt;br /&gt;
&lt;br /&gt;
    if (llGetListLength(list_ip_port) != 2 || llGetListLength(list_ip) != 4)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer test;&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;4;i++)&lt;br /&gt;
    {&lt;br /&gt;
        test=llList2Integer(list_ip,i);&lt;br /&gt;
        if (llList2String(list_ip,i) != (string)test)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        if (test &amp;lt; 0 || test &amp;gt; 255)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    test=llList2Integer(list_ip_port,1);&lt;br /&gt;
    if (llList2String(list_ip_port,1) != (string)test)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns a true value depending on the first character in input - anything else is assumed false.&lt;br /&gt;
integer true_value(string input)&lt;br /&gt;
{&lt;br /&gt;
    string value=llToLower(llGetSubString(input,0,0));&lt;br /&gt;
&lt;br /&gt;
    if (value == &amp;quot;y&amp;quot; || value == &amp;quot;t&amp;quot; || value ==&amp;quot;1&amp;quot;)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Return if more input should be processed (if not at EOF) - sets ConfigError if any config error found.&lt;br /&gt;
integer process_line(string dataline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(dataline,STRING_TRIM);&lt;br /&gt;
    integer index=llSubStringIndex(line,comment_char);&lt;br /&gt;
    &lt;br /&gt;
    if (index==0)       // line starts with comment - ignore line&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (index!=-1)&lt;br /&gt;
        line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL);   // skip everything after comment_char and trim tail&lt;br /&gt;
&lt;br /&gt;
    if (line==&amp;quot;&amp;quot;)       // Ignore blank lines&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (llToLower(line) == &amp;quot;[access]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 1;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[banned]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 2;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[genre]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 3;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[station]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 4;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llGetSubString(line,0,0) == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; llGetSubString(line,-1,-1) == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: malformed section found at line &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
        config_error=TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: no section found on line: &amp;quot; + (string) lineno);&lt;br /&gt;
        config_error = TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    list breakup=llParseString2List(line,[&amp;quot;=&amp;quot;],[]);&lt;br /&gt;
    string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);&lt;br /&gt;
    string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);&lt;br /&gt;
&lt;br /&gt;
    if (section == 1)            // access&lt;br /&gt;
    {&lt;br /&gt;
        field=llToLower(field);&lt;br /&gt;
&lt;br /&gt;
        if (field==&amp;quot;owner&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            owner_access=true_value(values);                       &lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;group&amp;quot;)&lt;br /&gt;
        {    &lt;br /&gt;
            group_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;public&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            public_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: invalid option on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 2)         // ban list&lt;br /&gt;
    {&lt;br /&gt;
        key try=(key) field;&lt;br /&gt;
&lt;br /&gt;
        if (try)&lt;br /&gt;
        {&lt;br /&gt;
            banned_keys+=(list)((key) field);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 3)           // categories&lt;br /&gt;
    {&lt;br /&gt;
        if (llListFindList(category_list,(list)field) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            category_list+=(list)field;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;genre: &#039;&amp;quot; + field + &amp;quot;&#039; already entered; double entry skipped.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 4)            // stations&lt;br /&gt;
    {&lt;br /&gt;
        list parse=llParseString2List(line,sep_char_list, []);&lt;br /&gt;
        string category=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);&lt;br /&gt;
        string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);&lt;br /&gt;
    &lt;br /&gt;
        if (!available_category(category))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: unknown genre on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (check_url(url))&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                num_stations++;&lt;br /&gt;
                station_category+=(list)category;&lt;br /&gt;
                station_name+=(list)name;&lt;br /&gt;
                station_desc+=(list)desc;&lt;br /&gt;
                station_url+=(list)url;&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llWhisper(0,&amp;quot;This station is already entered under the same genre and same url and is skipped.\nStation: &amp;quot; + name + &amp;quot;\nGenre: &#039;&amp;quot; + category + &amp;quot;&#039;\nURL: &amp;quot; + url);&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: malformed url on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
     &lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Sets the parcel URL and updates the display&lt;br /&gt;
set_parcel_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    parcel_url=url;&lt;br /&gt;
    llSetParcelMusicURL(parcel_url);&lt;br /&gt;
&lt;br /&gt;
    if (parcel_url==&amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        clear_display();&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is OFF&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;station now set to &amp;quot; + llList2String(station_desc,station_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Station: &amp;quot; + llList2String(station_desc,station_index));&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;Genre  : &amp;quot; + llList2String(category_list,category_index));&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;Now playing.....&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns if a category (genre) exists.&lt;br /&gt;
integer available_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;len;i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(category_list,i)))&lt;br /&gt;
            return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Returns if a category (genre) is empty   (NOTE: same function as available_category(), but logical negate of it. One of these can be removed.)&lt;br /&gt;
integer empty_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(station_category,i)))&lt;br /&gt;
            return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Removes categories (genres) for which no station is known.&lt;br /&gt;
skip_empty_categories()&lt;br /&gt;
{&lt;br /&gt;
    integer i=0;&lt;br /&gt;
&lt;br /&gt;
    while (i&amp;lt;llGetListLength(category_list))&lt;br /&gt;
    {&lt;br /&gt;
        if (empty_category(llList2String(category_list,i)))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;Warning: Genre &#039;&amp;quot; + llList2String(category_list,i) + &amp;quot;&#039; contains no stations and is deleted.&amp;quot;);&lt;br /&gt;
            category_list=llDeleteSubList(category_list,i,i);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            i++;&lt;br /&gt;
    }&lt;br /&gt;
            &lt;br /&gt;
    num_categories=llGetListLength(category_list);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state default&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        flag=FALSE;&lt;br /&gt;
        lineno=0;&lt;br /&gt;
        config_error=FALSE;&lt;br /&gt;
        num_stations=0;&lt;br /&gt;
        num_categories=0;&lt;br /&gt;
        radio_status=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(config_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
           reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
           llWhisper(0, &amp;quot;Reading config notecard...&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;1&amp;quot;,&amp;quot;Reading configuration.&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;2&amp;quot;,&amp;quot;Wait....&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;No config notecard &#039;&amp;quot; +  config_notecard + &amp;quot;&#039; present.&amp;quot;);&lt;br /&gt;
            state offline;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (reqid==id)&lt;br /&gt;
        {        &lt;br /&gt;
            if (data==EOF)&lt;br /&gt;
            {&lt;br /&gt;
                skip_empty_categories();&lt;br /&gt;
                llWhisper(0,&amp;quot;Configuration ok.\n&amp;quot; + (string)num_categories + &amp;quot; genres and &amp;quot; + (string)num_stations + &amp;quot; stations.&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Configuration OK&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;2&amp;quot;,&amp;quot;Genres  : &amp;quot; + (string)num_categories);&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Stations: &amp;quot; + (string)num_stations);&lt;br /&gt;
                state menu;&lt;br /&gt;
            }&lt;br /&gt;
            else &lt;br /&gt;
            {&lt;br /&gt;
                if (process_line(data))&lt;br /&gt;
                    reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
                else if (config_error)&lt;br /&gt;
                {&lt;br /&gt;
                    llWhisper(0,&amp;quot;errors found in configuration. please correct them.&amp;quot;);&lt;br /&gt;
                    state offline;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state offline&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state offline&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;Reset on owner touch or when notecard updated.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    touch_start(integer t)&lt;br /&gt;
    {&lt;br /&gt;
        if (llDetectedKey(0)==llGetOwner())&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY &amp;amp;&amp;amp; flag)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state menu&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state menu&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        listen_handle=0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        if (param &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
        key toucher=llDetectedKey(0);&lt;br /&gt;
&lt;br /&gt;
        if (has_access(toucher))&lt;br /&gt;
        {&lt;br /&gt;
            make_menu(toucher);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;sorry, no access.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    listen(integer chan, string name,key id,string msg)&lt;br /&gt;
    {&lt;br /&gt;
        integer index;&lt;br /&gt;
&lt;br /&gt;
        if (menu_type == 0)          // main menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_ON)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=1;&lt;br /&gt;
                set_parcel_url(parcel_url);               &lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is ON&amp;quot;);&lt;br /&gt;
                menu_num=0;&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned on.&amp;quot;);&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=0;&lt;br /&gt;
                set_parcel_url(&amp;quot;&amp;quot;);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned off.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
                {&lt;br /&gt;
                    llGiveInventory(id,info_notecard);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                    llWhisper(0,&amp;quot;sorry, help not available.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (radio_status == 1)&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(category_list, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: genre not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    category_index=index;&lt;br /&gt;
                    llWhisper(0,&amp;quot;Genre now set to &amp;quot; + llList2String(category_list,category_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
                    menu_type=1;&lt;br /&gt;
                    menu_num=0;&lt;br /&gt;
                    make_menu(id);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (menu_type == 1 &amp;amp;&amp;amp; radio_status == 1)     // station menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(station_name, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: station not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    station_index=index;&lt;br /&gt;
                    string new_url=llList2String(station_url,station_index);&lt;br /&gt;
&lt;br /&gt;
                    if (new_url != parcel_url)&lt;br /&gt;
                    {&lt;br /&gt;
                        set_parcel_url(new_url);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        retrieve_titelinfo();&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_response(key id, integer status, list meta, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == httpreq_id)&lt;br /&gt;
        {&lt;br /&gt;
            if (status == 200)&lt;br /&gt;
            {&lt;br /&gt;
                string feed = llGetSubString(body,llSubStringIndex(body, &amp;quot;&amp;lt;body&amp;gt;&amp;quot;) + llStringLength(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;), llSubStringIndex(body,&amp;quot;&amp;lt;/body&amp;gt;&amp;quot;) - 1);&lt;br /&gt;
                list feed_list = llParseString2List(feed,[&amp;quot;,&amp;quot;],[]);&lt;br /&gt;
                string current_title_info= llList2String(feed_list,6);&lt;br /&gt;
                integer length = llGetListLength(feed_list);&lt;br /&gt;
        &lt;br /&gt;
                if(llList2String(feed_list,7))&lt;br /&gt;
                {&lt;br /&gt;
                    integer a = 7;&lt;br /&gt;
                    for(; a&amp;lt;length; ++a)&lt;br /&gt;
                    {&lt;br /&gt;
                        current_title_info += &amp;quot;, &amp;quot; + llList2String(feed_list,a);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
         &lt;br /&gt;
                if (current_title_info != last_title_info)&lt;br /&gt;
                {&lt;br /&gt;
                    last_title_info = current_title_info;&lt;br /&gt;
                    display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + current_title_info);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + no_title_info);&lt;br /&gt;
            }&lt;br /&gt;
        }    &lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY &amp;amp;&amp;amp; flag)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
// end of script&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
===Notecard format===&lt;br /&gt;
Example notecard&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# New format Shoutcast - radio controller config notecard&lt;br /&gt;
# The format is divided in 4 sections:&lt;br /&gt;
# 1 - Access configuration&lt;br /&gt;
# 2 - Ban list (keys)&lt;br /&gt;
# 3 - Categories  (same as genres)&lt;br /&gt;
# 4 - Station info (category, name, desc, url)&lt;br /&gt;
# The &#039;#&#039; character defines the start of a comment and can be anywhere on a line. &lt;br /&gt;
# Everything after the &#039;#&#039; incuding the &#039;#&#039; itself is ignored.&lt;br /&gt;
# Case is not important (but information on display will show as entered)&lt;br /&gt;
# Spaces before and/or after fields are trimmed.&lt;br /&gt;
# Empty lines are ignored.&lt;br /&gt;
&lt;br /&gt;
[ACCESS]&lt;br /&gt;
owner=yes       # yes, true,1      means owner has access. everything else not.&lt;br /&gt;
group=yes       #  ,,  ,,  ,,      means group has acess.    ,,        ,,   ,,&lt;br /&gt;
public=yes      #  ,,  ,,  ,,      means public has access.  ,,        ,,   ,, &lt;br /&gt;
&lt;br /&gt;
[BANNED]&lt;br /&gt;
# keys of banned residents&lt;br /&gt;
&lt;br /&gt;
[GENRE]&lt;br /&gt;
# genre name&lt;br /&gt;
Hard Rock&lt;br /&gt;
Classic Rock&lt;br /&gt;
Oldies&lt;br /&gt;
Rap/Urban&lt;br /&gt;
Comedy&lt;br /&gt;
News&lt;br /&gt;
Dance&lt;br /&gt;
Country&lt;br /&gt;
Gothic&lt;br /&gt;
# etc.&lt;br /&gt;
[STATION]&lt;br /&gt;
# Shoutcast radio stations&lt;br /&gt;
# Use a &#039;|&#039; between each field - don&#039;t mind spaces before and after fields, they will be trimmed&lt;br /&gt;
# field1:genre, field2:station name, field3: station description, field4: station http://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt; or https://&amp;lt;ip&amp;gt;:&amp;lt;port&amp;gt;&lt;br /&gt;
# Note that genre must match case-insensitive a value previously entered in section [GENRE]&lt;br /&gt;
Classic Rock    | Absolute         |    Absolute Radio                  | http://205.188.215.226:8018&lt;br /&gt;
# etc.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===TODO===&lt;br /&gt;
&lt;br /&gt;
Planned for upcoming release 0.4:&lt;br /&gt;
* Add a llRegionSay to broadcast the &amp;lt;station&amp;gt;|&amp;lt;genre&amp;gt;|&amp;lt;current songtitle&amp;gt;|&amp;lt;url&amp;gt; to the region and add a script that displays that info on a remote Xytext board.&lt;br /&gt;
  (for use with a remote controller and/or remote display board anywhere in the region/parcel)&lt;br /&gt;
* llResetScript on owner change&lt;br /&gt;
* Relax on URL format&lt;br /&gt;
* Allow multiple genres per station&lt;/div&gt;</description>
			<pubDate>Thu, 10 Feb 2011 00:20:21 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)</comments>
		</item>
		<item>
			<title>SL Mail V1.2</title>
			<link>https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=1133913</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=1133913</guid>
			<description>&lt;p&gt;Flennan Roffo: /* Second Life mail client */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}} __NOTOC__&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
Updated: 10-2-2011&lt;br /&gt;
&lt;br /&gt;
=&#039;&#039;&#039;Second Life mail client&#039;&#039;&#039;=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Send and receive email from within Second Life from and to any address.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implemented with Address Book function (in a notecard named &#039;Address Book&#039;) to stores addresses by name  and to compile groups of named addresses. Current version is stand-alone (no server functionality) and uses chat commands only.&lt;br /&gt;
&lt;br /&gt;
[[Image:BannerSLMail.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.slmail.info slmail.info] &amp;lt;strike&amp;gt;(website coming soon!)&amp;lt;/strike&amp;gt; &amp;lt;b&amp;gt;url slmail.info no longer used for SL Mail, and was taken for some other purpose.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Release Notes V1.2=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 Release notes (edition 2, 4 sept 2007)&lt;br /&gt;
&lt;br /&gt;
===IMPORTANT NOTICE===&lt;br /&gt;
&lt;br /&gt;
Development of SL Mail was abandoned midyear 2008. The domain slmail.info was abandoned and is now taken by another domain holder (ISS) who has nothing to do with SL Mail.&lt;br /&gt;
&lt;br /&gt;
SL Mail is considered for redevelopment under the same terms, using a version of the &#039;&#039;Serverless Key Exchange&#039;&#039; script. This allows mail clients to exchange their key adresses to other rezzed mail clients in world, and send each other info about the public name they use, and other info that could be usefull. This protocol does not use a central server.&lt;br /&gt;
&lt;br /&gt;
See: [https://wiki.secondlife.com/wiki/Serverless_Key_Exchange Serverless Key Exchange]&lt;br /&gt;
&lt;br /&gt;
Future annoucements about SL Mail development will be made here.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;LICENCE INFO&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
This program is free software: you can redistribute it and/or modify&lt;br /&gt;
it under the terms of the GNU General Public License as published by&lt;br /&gt;
the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
(at your option) any later version.&lt;br /&gt;
&lt;br /&gt;
This program is distributed in the hope that it will be useful,&lt;br /&gt;
but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
GNU General Public License for more details.&lt;br /&gt;
&lt;br /&gt;
You should have received a copy of the GNU General Public License&lt;br /&gt;
along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;PRODUCTION &amp;amp; MAINTANENCE&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
by Logic Scripted Products and Script Services&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.logicscripts.org logicscripts.org] &amp;lt;strike&amp;gt;(website coming soon!)&amp;lt;/strike&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SLurl:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Beeratron&lt;br /&gt;
|x=57&lt;br /&gt;
|y=168&lt;br /&gt;
|z=75&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Contact: [[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;DESCRIPTION&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is a simple tool to send and receive mail from within SL.&lt;br /&gt;
You can either compose a message yourself using chat recording, or choose a notecard from inventory to send. The Address Book functionality allows you to use short names for mail recipients stored in a notecard. The current version does not have a persisent mail address. Watch out for the upcoming next release (V1.3) which will facilitate persisent in-world mail addresses and will be enhanced with many new features (See: Requests For Change (RFC).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;COMMANDS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Help&#039;&#039;&#039;&lt;br /&gt;
||Show Help about available commands&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Record&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording (for owner only).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Stop&#039;&#039;&#039;&lt;br /&gt;
||Stops the chat recording without sending&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Continue&#039;&#039;&#039;&lt;br /&gt;
||Continues a previously stopped chat recording. Lines will be appended to you recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Show&#039;&#039;&#039;&lt;br /&gt;
||Shows the content of the recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send&#039;&#039;&#039;&lt;br /&gt;
||If recording, stops the recording, and sends the mail (need to supply mail address and subject first!)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send &amp;lt;notecard&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Sends the content of the notecard, instead of the chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Ignore&#039;&#039;&#039;&lt;br /&gt;
||Ignores your current chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject &amp;lt;subject&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the subject of the mail.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail subject.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Set the HOME address of the owner (mail will be forwarder to this address when offline).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home&#039;&#039;&#039;&lt;br /&gt;
||Show the HOME address.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Info&#039;&#039;&#039;&lt;br /&gt;
||Shows the mail address the object this script is running in uses (e.g. &amp;lt;object-key&amp;gt;@lsl.secondlife.com).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Read&#039;&#039;&#039;&lt;br /&gt;
||Reads the current message from the mail buffer (the mail buffer gets filled with mail you receive)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Select &amp;lt;msg&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Select a message number from the availabe messages in the mail buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Next&#039;&#039;&#039;&lt;br /&gt;
||Make next message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Prev&#039;&#039;&#039;&lt;br /&gt;
||Make previous message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@First&#039;&#039;&#039;&lt;br /&gt;
||Make the first message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Last&#039;&#039;&#039;&lt;br /&gt;
||Make the last message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Clear&#039;&#039;&#039;&lt;br /&gt;
||Clear the mail buffer&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Delete&#039;&#039;&#039;&lt;br /&gt;
||Deletes only the current message&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Reply&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording to reply to the current message. Mail adress and subject are filled in automatically.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* Commands are case insensitive (&amp;quot;@read&amp;quot; == &amp;quot;@READ&amp;quot;). Arguments might not be case insensitive.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;ADDRESS BOOK FORMAT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
A notecard of the name &#039;Address Book&#039; is read during initialization which may contain Address Book items and Groups.&lt;br /&gt;
The notecard is split in two sections, which need to be defined in that particular order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[ADDRESS BOOK]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Defines the section in which you can put names for mail addresses,  like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name1=account@thisdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name2=user@otherdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[GROUP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define groups of previously defined names under a new name, like for instance:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyGroup=Name1, Name2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note that names of groups and individual mail adresses share the same namespace and must be unique.&lt;br /&gt;
&lt;br /&gt;
So when you filled in your mail adresses in the Address Book, you can now use:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail Name1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to  &amp;lt;account@thisdomain.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail MyGroup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to &amp;lt;account@thisdomain.com&amp;gt; and &amp;lt;user@otherdomain.com&amp;gt;&lt;br /&gt;
Mails will be sent one after another.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* Names for Addreses and Groups are case insensitive (e.g. &amp;quot;mary&amp;quot;  == &amp;quot;MARY&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* The special address &#039;Self&#039; can be used in commands where otherwise an address specification can be used. &#039;Self&#039; is case insensitive (e.g. &amp;quot;self&amp;quot; == &amp;quot;SELF&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LIMITATIONS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
The current version is limited by the following:&lt;br /&gt;
&lt;br /&gt;
* Chat recording lines are limited by the 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Output of lines from the mail buffer are also limited by this 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Incoming mail is limited to a 1000 (1024?) byte limit&lt;br /&gt;
&lt;br /&gt;
* Outgoing mai is limited by a 4096 byte limit, which includes the standard mail header (region/location info on the first two lines)&lt;br /&gt;
&lt;br /&gt;
We are making adjustments to this release to help overcome these limitations. At least the line lenght limit can be overcome by introducing a line continuation character (for example a hyphen &#039;-&#039;) that when used at the end of a line appends the next line, so lines longer then 255 bytes are possible then.&lt;br /&gt;
&lt;br /&gt;
To overcome the outgoing mail length limit, the mail can be broken textualy into parts, and each part can be send seperatedely, with an indication in the subject or in an introduced primary line of the mail body to indicate that the mail was split into parts.&lt;br /&gt;
For incoming mail and at least to receive mail from other SL Mail programs, a protocol will be introduced to receive mail in parts that are joined together after receiving them to form a single mail.&lt;br /&gt;
&lt;br /&gt;
These enhancements will be made available in the next release (V1.3) of SL Mail &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;BUGS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Report any bugs you find in this release to Logic (IM: Flennan Roffo).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;REQUEST FOR CHANGE (RFC)&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Do you have additional wishes for enhancement of this product?&lt;br /&gt;
Contact Flennan Roffo and we will see if they can be implemented in the next release.&lt;br /&gt;
&lt;br /&gt;
Existing RFC&#039;s are:&lt;br /&gt;
&lt;br /&gt;
* Menu support for commands.&lt;br /&gt;
&lt;br /&gt;
* Lines on incoming/outgoing mail longer than 255 bytes.&lt;br /&gt;
&lt;br /&gt;
* Send messages longer than 4096 (minus SL mail header) bytes.&lt;br /&gt;
&lt;br /&gt;
* Receive messages longer than 1024 bytes.&lt;br /&gt;
&lt;br /&gt;
* Permanent mail addresses for the SL Mail client (like: &amp;lt;Flennan.Roffo@somedomain.sl&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Add your RFC!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In-world join the group &amp;quot;SL Mail&amp;quot; for bug reports, feature requests, the latest SL Mail release, and notices about development issues.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scripts=&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==Script: SL Mail v1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail core module which scans for incoming mail messages and executes commands used by the owner.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail V1.2.lsl&lt;br /&gt;
// (c) 2007 Logic Scripted Products and Script Services&lt;br /&gt;
// Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
// VERSION&lt;br /&gt;
// Version: 1.2&lt;br /&gt;
&lt;br /&gt;
// HISTORY&lt;br /&gt;
// Date         Version     Author              Comment&lt;br /&gt;
// --------------------------------------------------------------------------------------&lt;br /&gt;
// 28 aug 2007  V 1.0       Flennan Roffo       Created&lt;br /&gt;
//&lt;br /&gt;
//  1 sep 2007  V 1.1       Flennan Roffo       @Reply empties the recording buffer.&lt;br /&gt;
//                                                @Send while recording ends recording&lt;br /&gt;
//                                                and sends the mail if a mail address&lt;br /&gt;
//                                                and subject are supplied.&lt;br /&gt;
//                                                Fixed incorrect date in Unix2DateTime.&lt;br /&gt;
//  3 sep 2007  V 1.2       Flennan Roffo       Notification options:&lt;br /&gt;
//                                              - When online, send an IM when mail is received.&lt;br /&gt;
//                                              - When offline, send to HOME mail adress.&lt;br /&gt;
//                                              Adressbook&lt;br /&gt;
//                                              - Read adress book from config notecard.&lt;br /&gt;
&lt;br /&gt;
// LICENCE&lt;br /&gt;
// This program is free software; you can redistribute it and/or&lt;br /&gt;
// modify it under the terms of the GNU General Public License&lt;br /&gt;
// as published by the Free Software Foundation; either version 2&lt;br /&gt;
// of the License, or (at your option) any later version.&lt;br /&gt;
// &lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
// &lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program; if not, write to the Free Software&lt;br /&gt;
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
// (Also available at http://www.gnu.org/copyleft/gpl.html) &lt;br /&gt;
&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// Let&#039;s you record a message and sent to email and get messages and reply to messages.&lt;br /&gt;
// Must supply a valid mail adress and non-empty subject using chat commands.&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
// 1) Check for the maximum length of an email message (including newline and header).&lt;br /&gt;
// 2) Read adress book from notecard.                                    *DONE*&lt;br /&gt;
// 3) Send incoming mail to personal mail adress when offline.            *DONE*&lt;br /&gt;
// 4) Alert with an IM when online upon receiving new mail.                *DONE*&lt;br /&gt;
&lt;br /&gt;
string   SL_MAIL_VERSION = &amp;quot;V 1.2&amp;quot;;&lt;br /&gt;
string   SL_MAIL_DATE    = &amp;quot; 2 sep 2007&amp;quot;;&lt;br /&gt;
integer  ErrorFlag         = FALSE;&lt;br /&gt;
list     ScriptList        = [ &amp;quot;SL Mail Help V1.2&amp;quot;, &amp;quot;SL Mail AddressBook V1.2&amp;quot;, &lt;br /&gt;
                                &amp;quot;SL Mail OnlineStatus V1.2&amp;quot;, &amp;quot;SL Mail FetchNotecard V1.2&amp;quot; ];    &lt;br /&gt;
string   LSL_DOMAIN=&amp;quot;lsl.secondlife.com&amp;quot;; &lt;br /&gt;
integer  StatusOnline=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Commands&lt;br /&gt;
&lt;br /&gt;
string  COMMAND_RECORD     = &amp;quot;@RECORD&amp;quot;;&lt;br /&gt;
string  COMMAND_CONTINUE   = &amp;quot;@CONTINUE&amp;quot;;&lt;br /&gt;
string  COMMAND_STOP       = &amp;quot;@STOP&amp;quot;;&lt;br /&gt;
string  COMMAND_MAIL       = &amp;quot;@MAIL&amp;quot;;&lt;br /&gt;
string  COMMAND_SUBJECT    = &amp;quot;@SUBJECT&amp;quot;;&lt;br /&gt;
string  COMMAND_SEND       = &amp;quot;@SEND&amp;quot;;&lt;br /&gt;
string  COMMAND_SEE        = &amp;quot;@SEE&amp;quot;;&lt;br /&gt;
string  COMMAND_IGNORE     = &amp;quot;@IGNORE&amp;quot;;&lt;br /&gt;
string  COMMAND_READ       = &amp;quot;@READ&amp;quot;;&lt;br /&gt;
string  COMMAND_DELETE     = &amp;quot;@DELETE&amp;quot;;&lt;br /&gt;
string  COMMAND_CLEAR      = &amp;quot;@CLEAR&amp;quot;;&lt;br /&gt;
string  COMMAND_REPLY      = &amp;quot;@REPLY&amp;quot;;&lt;br /&gt;
string  COMMAND_NEXT       = &amp;quot;@NEXT&amp;quot;;&lt;br /&gt;
string  COMMAND_PREV       = &amp;quot;@PREV&amp;quot;;&lt;br /&gt;
string  COMMAND_FIRST      = &amp;quot;@FIRST&amp;quot;;&lt;br /&gt;
string  COMMAND_LAST       = &amp;quot;@LAST&amp;quot;;&lt;br /&gt;
string  COMMAND_LIST       = &amp;quot;@LIST&amp;quot;;&lt;br /&gt;
string  COMMAND_SELECT     = &amp;quot;@SELECT&amp;quot;;&lt;br /&gt;
string  COMMAND_HELP       = &amp;quot;@HELP&amp;quot;;&lt;br /&gt;
string  COMMAND_INFO       = &amp;quot;@INFO&amp;quot;;&lt;br /&gt;
string  COMMAND_RESET      = &amp;quot;@RESET&amp;quot;;&lt;br /&gt;
string  COMMAND_SHOW       = &amp;quot;@SHOW&amp;quot;;&lt;br /&gt;
string  COMMAND_ON         = &amp;quot;@ON&amp;quot;;&lt;br /&gt;
string  COMMAND_OFF        = &amp;quot;@OFF&amp;quot;;&lt;br /&gt;
string  COMMAND_HOME       = &amp;quot;@HOME&amp;quot;;&lt;br /&gt;
string  COMMAND_LOAD       = &amp;quot;@LOAD&amp;quot;;&lt;br /&gt;
string  COMMAND_ADDRESS    = &amp;quot;@ADDRESS&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Recording&lt;br /&gt;
&lt;br /&gt;
integer Recording = FALSE;&lt;br /&gt;
&lt;br /&gt;
list    ChatRecording=[];&lt;br /&gt;
integer NumLines=0;&lt;br /&gt;
integer Length=0;&lt;br /&gt;
&lt;br /&gt;
list     TimeList=[];&lt;br /&gt;
list     AddressList=[];&lt;br /&gt;
list     SubjectList=[];&lt;br /&gt;
list     BodyList=[];&lt;br /&gt;
integer  NumMessages=0;&lt;br /&gt;
integer  CurrentMessage=-1;&lt;br /&gt;
&lt;br /&gt;
float    MAIL_FETCH_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
// Link Messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP                        = 10000;&lt;br /&gt;
integer MSG_STATUS_ONLINE               = 30000;&lt;br /&gt;
integer MSG_STATUS_OFFLINE              = 30100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED          = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR           = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Unix Time conversion //////////////////&lt;br /&gt;
&lt;br /&gt;
integer DAYS_PER_YEAR        = 365;                // Non leap year&lt;br /&gt;
integer SECONDS_PER_YEAR     = 31536000;          // Non leap year&lt;br /&gt;
integer SECONDS_PER_DAY      = 86400;&lt;br /&gt;
integer SECONDS_PER_HOUR     = 3600;&lt;br /&gt;
integer SECONDS_PER_MINUTE   = 60;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// LeapYear() /////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer LeapYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (year % 4 == 0)&lt;br /&gt;
    {&lt;br /&gt;
        if (year % 100 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (year % 400 == 0)&lt;br /&gt;
            {&lt;br /&gt;
                return 1;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// DaysPerMonth() ///////////////////////////////////////&lt;br /&gt;
                &lt;br /&gt;
integer DaysPerMonth(integer year,integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;lt; 8)&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (month == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if (LeapYear(year))&lt;br /&gt;
                {&lt;br /&gt;
                    return 29;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    return 28;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 30;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 30;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////// DaysPerYear() ////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DaysPerYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (LeapYear(year))&lt;br /&gt;
        return DAYS_PER_YEAR + 1;&lt;br /&gt;
    else&lt;br /&gt;
        return DAYS_PER_YEAR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Unix2DataTime() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list Unix2DateTime(integer unixtime)&lt;br /&gt;
{&lt;br /&gt;
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;&lt;br /&gt;
    integer day = days_since_1_1_1970 + 1;&lt;br /&gt;
    integer year  = 1970;&lt;br /&gt;
    integer days_per_year = DaysPerYear(year);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_year)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_year;&lt;br /&gt;
        ++year;&lt;br /&gt;
        days_per_year = DaysPerYear(year);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer month = 1;&lt;br /&gt;
    integer days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_month)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_month;&lt;br /&gt;
        &lt;br /&gt;
        if (++month &amp;gt; 12)&lt;br /&gt;
        {    &lt;br /&gt;
            ++year;&lt;br /&gt;
            month = 1;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;&lt;br /&gt;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;&lt;br /&gt;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;&lt;br /&gt;
    integer minute      = second / SECONDS_PER_MINUTE;&lt;br /&gt;
    second               = second % SECONDS_PER_MINUTE;&lt;br /&gt;
    &lt;br /&gt;
    return [ year, month, day, hour, minute, second ];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// MonthName() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list MonthNameList = [     &amp;quot;JAN&amp;quot;, &amp;quot;FEB&amp;quot;, &amp;quot;MAR&amp;quot;, &amp;quot;APR&amp;quot;, &amp;quot;MAY&amp;quot;, &amp;quot;JUN&amp;quot;, &lt;br /&gt;
                        &amp;quot;JUL&amp;quot;, &amp;quot;AUG&amp;quot;, &amp;quot;SEP&amp;quot;, &amp;quot;OCT&amp;quot; , &amp;quot;NOV&amp;quot;, &amp;quot;DEC&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
string MonthName(integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;gt;= 0 &amp;amp;&amp;amp; month &amp;lt; 12)&lt;br /&gt;
        return llList2String(MonthNameList, month);&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// DateString() ///////////////////////////&lt;br /&gt;
&lt;br /&gt;
string DateString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer year       = llList2Integer(timelist,0);&lt;br /&gt;
    integer month      = llList2Integer(timelist,1);&lt;br /&gt;
    integer day        = llList2Integer(timelist,2);&lt;br /&gt;
    &lt;br /&gt;
    return (string)day + &amp;quot;-&amp;quot; + MonthName(month - 1) + &amp;quot;-&amp;quot; + (string)year;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// TimeString() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string TimeString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer hour          = llList2Integer(timelist,3);&lt;br /&gt;
    integer minute         = llList2Integer(timelist,4);&lt;br /&gt;
    integer second         = llList2Integer(timelist,5);&lt;br /&gt;
    string  hourstr     = (string)hour;&lt;br /&gt;
    string  minutestr   = (string)minute;&lt;br /&gt;
    string  secondstr   = (string)second;&lt;br /&gt;
    &lt;br /&gt;
    if (hour &amp;lt; 10)         hourstr     = &amp;quot;0&amp;quot; + hourstr;&lt;br /&gt;
    if (minute &amp;lt; 10)     minutestr     = &amp;quot;0&amp;quot; + minutestr;&lt;br /&gt;
    if (second &amp;lt; 10)    secondstr    = &amp;quot;0&amp;quot; + secondstr;&lt;br /&gt;
    return hourstr + &amp;quot;:&amp;quot; + minutestr + &amp;quot;:&amp;quot; + secondstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() /////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string body)&lt;br /&gt;
{&lt;br /&gt;
    // llOwnerSay(&amp;quot;Sending message to &#039;&amp;quot; + address + &amp;quot;&#039; with subject &#039;&amp;quot; + subject +&amp;quot;&#039;.&amp;quot;);&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND, body, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// SendHome() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendHome(string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SENDHOME, body, (key)subject);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Show() ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Show()&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;Current chat recording is:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; NumLines; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(ChatRecording,i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;Lines is &amp;quot; + (string)NumLines);&lt;br /&gt;
    llOwnerSay(&amp;quot;Message length is &amp;quot; + (string)Length);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Read() /////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Read()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;Reading message &amp;quot; + (string)CurrentMessage + &amp;quot; from mail buffer.&amp;quot;);&lt;br /&gt;
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);&lt;br /&gt;
    list timelist=Unix2DateTime(time);&lt;br /&gt;
    string Address = llList2String(AddressList,CurrentMessage);&lt;br /&gt;
    string Subject = llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
    string Body    = llList2String(BodyList,CurrentMessage);&lt;br /&gt;
    llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Address: &amp;quot; + Address);&lt;br /&gt;
    llOwnerSay(&amp;quot;Subject: &amp;quot; + Subject);&lt;br /&gt;
    llOwnerSay(&amp;quot;Begin of message body:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    list bodylist=llParseStringKeepNulls(Body, [ &amp;quot;\n&amp;quot; ], []);&lt;br /&gt;
    integer num=llGetListLength(bodylist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(bodylist,i));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;End of message body.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////// List ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
List()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;The mail buffer contains the following messages:\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; NumMessages; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer time=llList2Integer(TimeList,i);&lt;br /&gt;
        list timelist=Unix2DateTime(time);&lt;br /&gt;
        if (i &amp;gt; 0) llOwnerSay(&amp;quot;+-+-+-+-+-+-+-+-+-+-+-+-&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Message: &amp;quot; + (string)i);&lt;br /&gt;
        llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;From:    &amp;quot; + llList2String(AddressList,i));&lt;br /&gt;
        llOwnerSay(&amp;quot;Subject: &amp;quot; + llList2String(SubjectList,i));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////// NotifyNewMail() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
NotifyNewMail(string time, string address, string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    list timelist=Unix2DateTime((integer)time);&lt;br /&gt;
&lt;br /&gt;
    if (StatusOnline)&lt;br /&gt;
    {&lt;br /&gt;
        llInstantMessage(llGetOwner(), &amp;quot;You received a new mail message on &amp;quot; &lt;br /&gt;
                                    + DateString(timelist) + &amp;quot; at &amp;quot; + TimeString(timelist)&lt;br /&gt;
                                    + &amp;quot; from &amp;quot; + address &lt;br /&gt;
                                    + &amp;quot; with the subject &amp;quot; + subject);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        SendHome(&amp;quot;FW: &amp;quot; + subject, &amp;quot;Received at: &amp;quot; + DateString(timelist) + &amp;quot; &amp;quot; + TimeString(timelist) + &amp;quot;\nFrom: &amp;quot; +  address &lt;br /&gt;
                    + &amp;quot;\nBegin message body:\n-------------------\n&amp;quot; + body + &amp;quot;\n-------------------\nEnd message body.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ResetOtherScripts() //////////////////////&lt;br /&gt;
&lt;br /&gt;
ResetOtherScripts()&lt;br /&gt;
{&lt;br /&gt;
    string     name;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(ScriptList);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        name = llList2String(ScriptList,i);&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(name) == INVENTORY_SCRIPT)&lt;br /&gt;
        {&lt;br /&gt;
            llResetOtherScript(name);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Error - script &#039;&amp;quot; + name + &amp;quot;&#039; not found.&amp;quot;);&lt;br /&gt;
            ErrorFlag = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
// default &lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ////////////////////// state_entry() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Welcome to SL Mail, released under GNU software licence.&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Version &amp;quot; + SL_MAIL_VERSION + &amp;quot; &amp;quot; + SL_MAIL_DATE);&lt;br /&gt;
        llOwnerSay(&amp;quot;Produced by Logic Scripted Products &amp;amp; Product Services&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Free memory: &amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
        ResetOtherScripts();&lt;br /&gt;
        &lt;br /&gt;
        if (ErrorFlag)&lt;br /&gt;
            state Error;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// on_rez() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// changed() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_LOADED)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_ERROR)&lt;br /&gt;
        {&lt;br /&gt;
            state Error;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() //////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(MAIL_FETCH_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //////////////////////// on_rez() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// listen() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string trimmessage=llStringTrim(message,STRING_TRIM);&lt;br /&gt;
        list   parse = llParseStringKeepNulls(trimmessage, [ &amp;quot; &amp;quot;], []);&lt;br /&gt;
        string command = llToUpper(llList2String(parse,0));&lt;br /&gt;
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        integer nargs  = llGetListLength(parse);&lt;br /&gt;
        string argstr=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (nargs &amp;gt; 1) argstr=llGetSubString(message, llSubStringIndex(message, &amp;quot; &amp;quot;) + 1, -1);&lt;br /&gt;
            &lt;br /&gt;
        if (Recording)&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Recording stopped. Type @SHOW to see the message you have entered,&amp;quot;&lt;br /&gt;
                            + &amp;quot; or @SEND to send it.&amp;quot;);&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                &lt;br /&gt;
                SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];&lt;br /&gt;
                ++NumLines;&lt;br /&gt;
                Length += llStringLength(message) + 2;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_RECORD)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Start recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                ChatRecording = [];&lt;br /&gt;
                NumLines=0;&lt;br /&gt;
                Length=0;&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CONTINUE)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Continue recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_REPLY)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    string address=llList2String(AddressList,CurrentMessage);&lt;br /&gt;
                    string subject=&amp;quot;Re: &amp;quot; + llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, address, NULL_KEY);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, subject, NULL_KEY);&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines=0;&lt;br /&gt;
                    Length=0;&lt;br /&gt;
                    Recording = TRUE;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_MAIL)&lt;br /&gt;
            {&lt;br /&gt;
                string mailaddress=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailaddress != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, mailaddress, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETADDRESS, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SUBJECT)&lt;br /&gt;
            {&lt;br /&gt;
                string mailsubject=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailsubject != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, mailsubject, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETSUBJECT, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Not recording.&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    if (NumLines == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND_NOTECARD, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_IGNORE)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines = 0;&lt;br /&gt;
                    Length = 0;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Show();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_READ)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumMessages == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Read();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        ++CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        --CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_FIRST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = 0;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LAST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LIST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    List();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SELECT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;Need to supply a message number.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    integer msgnum = (integer)arg;&lt;br /&gt;
                     &lt;br /&gt;
                    if (msgnum &amp;lt; 0 || msgnum &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Message number &amp;quot; + arg + &amp;quot; not in mail buffer.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = msgnum;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_DELETE)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    --NumMessages;&lt;br /&gt;
                     &lt;br /&gt;
                    if (NumMessages == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = -1;&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (CurrentMessage &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CLEAR)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList=[];&lt;br /&gt;
                    AddressList=[];&lt;br /&gt;
                    SubjectList=[];&lt;br /&gt;
                    BodyList=[];&lt;br /&gt;
                    NumMessages=0;&lt;br /&gt;
                    CurrentMessage=-1;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_HELP, arg, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_INFO)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                Show();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_RESET)&lt;br /&gt;
            {&lt;br /&gt;
                llResetScript();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                state not_running;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HOME)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs==1)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETHOME, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETHOME, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// email() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    email(string time, string address, string subject, string body, integer queued)&lt;br /&gt;
    {&lt;br /&gt;
        NotifyNewMail(time, address, subject, body);&lt;br /&gt;
        TimeList = (TimeList=[]) + TimeList + [time];&lt;br /&gt;
        AddressList = (AddressList=[]) + AddressList + [address];&lt;br /&gt;
        SubjectList = (SubjectList=[]) + SubjectList + [subject];&lt;br /&gt;
        BodyList = (BodyList=[]) + BodyList + [body];&lt;br /&gt;
        ++NumMessages;&lt;br /&gt;
        &lt;br /&gt;
        if (CurrentMessage == -1)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = NumMessages - 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_REPLY)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state not_running&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state not_running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;SL Mailbox switched OFF. Say @ON to switch it back on.&amp;quot;);&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// on_rez() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// listen() ////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer chan, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string command=llToUpper(message);&lt;br /&gt;
        &lt;br /&gt;
        if (command == COMMAND_ON)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state Error&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state Error&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Error in SL Mail: not all component scripts found.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// End SL Mail V1.2.lsl&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Address Book V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Read and interpret the contents of the Address Book.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail AddressBook V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// &lt;br /&gt;
//  Read the Address Book from a notecard named &amp;quot;Address Book&amp;quot;.&lt;br /&gt;
//&lt;br /&gt;
//  The Address Book has the following format:&lt;br /&gt;
//  &lt;br /&gt;
//  [ADDRESS BOOK]&lt;br /&gt;
//  Name1=username@yourdomain.com&lt;br /&gt;
//  Name2=otheruser@otherdomain.com&lt;br /&gt;
//  ...&lt;br /&gt;
//  [GROUP]&lt;br /&gt;
//  group1=Name1, Name2&lt;br /&gt;
//  ...&lt;br /&gt;
//&lt;br /&gt;
//  Notes:&lt;br /&gt;
//  1. Group and Name share the same namespace, and must be unique.&lt;br /&gt;
//  2. It is allowed to have a name in the addressbook with multiple addresses, seperated by comma&#039;s.&lt;br /&gt;
// &lt;br /&gt;
/////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string  CurrentMailAddress = &amp;quot;&amp;quot;;&lt;br /&gt;
string  CurrentMailSubject = &amp;quot;&amp;quot;;&lt;br /&gt;
integer StatusOnline = FALSE;&lt;br /&gt;
&lt;br /&gt;
// Fetch or Send notecard&lt;br /&gt;
&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Names&lt;br /&gt;
&lt;br /&gt;
list    AddressBookList=[];&lt;br /&gt;
list    MailAddressList=[];&lt;br /&gt;
&lt;br /&gt;
string  STRING_HOME=&amp;quot;HOME&amp;quot;;&lt;br /&gt;
string  STRING_SELF=&amp;quot;SELF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Groups&lt;br /&gt;
&lt;br /&gt;
list   GroupList=[];&lt;br /&gt;
list   GroupNameList=[];&lt;br /&gt;
&lt;br /&gt;
string LSL_DOMAIN = &amp;quot;lsl.secondlife.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Read Address Book notecard&lt;br /&gt;
&lt;br /&gt;
string  ADDRESSBOOK_NOTECARD=&amp;quot;Address Book&amp;quot;;&lt;br /&gt;
integer Line=0;&lt;br /&gt;
key     reqAddressBook=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
integer Section=0;&lt;br /&gt;
integer SECTION_ADDRESS_BOOK=1;&lt;br /&gt;
integer SECTION_GROUP=2;&lt;br /&gt;
string  STRING_ADDRESS_BOOK=&amp;quot;ADDRESS BOOK&amp;quot;;&lt;br /&gt;
string  STRING_GROUP=&amp;quot;GROUP&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Links messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
integer MSG_MESSAGE_NOTIFY              = 90900;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED            = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR            = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// GetSelfAddress() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
string GetSelfAddress()&lt;br /&gt;
{&lt;br /&gt;
    return (string)llGetKey() + &amp;quot;@&amp;quot; + LSL_DOMAIN;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Info() /////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Info()&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;The mail address for this object is: &amp;quot; &lt;br /&gt;
                    + GetSelfAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// IsValidKeyFormat() //////////////////////&lt;br /&gt;
&lt;br /&gt;
integer IsValidKeyFormat(string str)&lt;br /&gt;
{&lt;br /&gt;
    string keychars = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    if (llStringLength(str) != 36)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    if( (llGetSubString( str, 8, 8 )   != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 13, 13 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 18, 18 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 23, 23 )  != &amp;quot;-&amp;quot; ) )&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 9; i &amp;lt; 13; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 14; i &amp;lt; 18; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 19; i &amp;lt; 23; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 24; i &amp;lt; 36; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// ValidMailAddress() ////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer ValidMailAddress(string arg)&lt;br /&gt;
{&lt;br /&gt;
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));&lt;br /&gt;
    &lt;br /&gt;
    if (adress == &amp;quot;&amp;quot;)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    list parse = llParseStringKeepNulls(adress, [ &amp;quot;@&amp;quot; ], []);&lt;br /&gt;
    string account = llList2String(parse,0);&lt;br /&gt;
    string domain  = llList2String(parse,1);&lt;br /&gt;
    &lt;br /&gt;
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    &lt;br /&gt;
    if (domain == LSL_DOMAIN)&lt;br /&gt;
    {&lt;br /&gt;
        return IsValidKeyFormat(account);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list parsedomain = llParseString2List(domain, [ &amp;quot;.&amp;quot; ], []);&lt;br /&gt;
    &lt;br /&gt;
        if (llGetListLength(parsedomain) &amp;lt; 2)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        &lt;br /&gt;
        integer num = llGetListLength(parsedomain);&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llStringLength(llList2String(parsedomain,i)) &amp;lt; 2)&lt;br /&gt;
            {&lt;br /&gt;
                return FALSE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetAddressStr() ///////////////////&lt;br /&gt;
&lt;br /&gt;
string GetAndCheckAddressStr(string address)&lt;br /&gt;
{&lt;br /&gt;
    list addresslist = llCSV2List(address);&lt;br /&gt;
    integer num=llGetListLength(addresslist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    string addressstr=&amp;quot;&amp;quot;;&lt;br /&gt;
    string curaddress=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        curaddress=llList2String(addresslist,i);&lt;br /&gt;
        &lt;br /&gt;
        if (ValidMailAddress(curaddress))&lt;br /&gt;
        {&lt;br /&gt;
            addressstr = (addressstr=&amp;quot;&amp;quot;) + addressstr + curaddress + &amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address string: &#039;&amp;quot; &lt;br /&gt;
                            + curaddress + &amp;quot;&#039;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return llGetSubString(addressstr, 0, -2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ProcessLine() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
ProcessLine(string rawline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(rawline,STRING_TRIM);&lt;br /&gt;
    string first=llGetSubString(line,0,0);&lt;br /&gt;
    string last=llGetSubString(line,-1,-1);&lt;br /&gt;
    &lt;br /&gt;
    // Ignore a blank line or comment line&lt;br /&gt;
    if (line == &amp;quot;&amp;quot; || first == &amp;quot;#&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // Check for the right section&lt;br /&gt;
    &lt;br /&gt;
    if (first == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; last == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        string sectionstr=llToUpper(llStringTrim(llGetSubString(line,1,-2),STRING_TRIM));&lt;br /&gt;
        &lt;br /&gt;
        if (sectionstr == STRING_ADDRESS_BOOK)&lt;br /&gt;
        {&lt;br /&gt;
            Section = SECTION_ADDRESS_BOOK;&lt;br /&gt;
        }&lt;br /&gt;
        else if (sectionstr == STRING_GROUP)&lt;br /&gt;
        {&lt;br /&gt;
            if (Section == 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                        + &amp;quot;. Group section defined before Address Book section.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Section = SECTION_GROUP;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid section header &#039;&amp;quot; + sectionstr &lt;br /&gt;
                        + &amp;quot;&#039; in &amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Must be in a section&lt;br /&gt;
    &lt;br /&gt;
    if (Section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;. No section header.&amp;quot;, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    list     parse=llParseString2List(line, [ &amp;quot;=&amp;quot; ], []);&lt;br /&gt;
    integer  num=llGetListLength(parse);&lt;br /&gt;
    &lt;br /&gt;
    // Format must be correct&lt;br /&gt;
    &lt;br /&gt;
    if (num != 2)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; +  (string)(Line+1) + &amp;quot;:\n&amp;quot; + rawline, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (Section == SECTION_ADDRESS_BOOK)&lt;br /&gt;
    {&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(name) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + name &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ name ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            string address=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
            string addressstr=GetAndCheckAddressStr(address);&lt;br /&gt;
            &lt;br /&gt;
            if (addressstr != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                AddressBookList     = (AddressBookList=[])     + AddressBookList     + [ name ];&lt;br /&gt;
                MailAddressList     = (MailAddressList=[])     + MailAddressList     + [ addressstr ];&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;No valid mail address for &#039;&amp;quot; + name &lt;br /&gt;
                    + &amp;quot;&#039;. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                    + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name &lt;br /&gt;
                + &amp;quot;&#039; already defined. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // Group&lt;br /&gt;
    {&lt;br /&gt;
        string group=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(group) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + group &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ group ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(GroupList, [ group ]) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                string names=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
                list   namelist=llCSV2List(names);&lt;br /&gt;
                integer num=llGetListLength(namelist);&lt;br /&gt;
                integer i;&lt;br /&gt;
                integer index;&lt;br /&gt;
                string  name;&lt;br /&gt;
                string  namestr=&amp;quot;&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
                for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                    name=llList2String(namelist,i);&lt;br /&gt;
                    index=llListFindList(AddressBookList, [ name ]);&lt;br /&gt;
            &lt;br /&gt;
                    if (index == -1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name + &amp;quot;&#039; defined in Group &#039;&amp;quot; &lt;br /&gt;
                                + group + &amp;quot;&#039; not found in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY); &lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        namestr = (namestr=&amp;quot;&amp;quot;) + namestr + name + &amp;quot;,&amp;quot;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (namestr != &amp;quot;&amp;quot;)&lt;br /&gt;
                {    &lt;br /&gt;
                    namestr=llGetSubString(namestr,0,-2);&lt;br /&gt;
                    GroupList         = (GroupList=[])         + GroupList     + [ group ];&lt;br /&gt;
                    GroupNameList     = (GroupNameList=[])    + GroupNameList + [ namestr ];&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                        + &amp;quot;&#039; has no valid names. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                        + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                    + &amp;quot;&#039; already defined in Group. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                    + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group&lt;br /&gt;
                + &amp;quot;&#039; already defined in Address Book. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// GetGroupAddressList ///////////////&lt;br /&gt;
&lt;br /&gt;
string GetGroupAddressList(string group)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(GroupList, [ group ]);&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(GroupList);&lt;br /&gt;
    string  grouplist=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        for (i = index; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2String(GroupList,i) == group)&lt;br /&gt;
            {&lt;br /&gt;
                grouplist = (grouplist=&amp;quot;&amp;quot;) + grouplist + llList2String(GroupNameList,i) + &amp;quot;,&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (grouplist != &amp;quot;&amp;quot;) grouplist=llGetSubString(grouplist,0,-2);   // remove last &amp;quot;,&amp;quot;&lt;br /&gt;
        return grouplist;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// SetMailAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetMailAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ address ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        index=llListFindList(GroupList, [ address ]);&lt;br /&gt;
        &lt;br /&gt;
        if (index == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llToUpper(address) == STRING_SELF)&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = GetSelfAddress();&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if(ValidMailAddress(address))&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = address;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Mail adress &amp;quot; + address &lt;br /&gt;
                            + &amp;quot; : not found in adress book or invalid format.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailAddress = GetGroupAddressList(address);&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        CurrentMailAddress = llList2String(MailAddressList,index);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                        + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string message)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No mail address defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No subject defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list mailaddresslist=llCSV2List(CurrentMailAddress);&lt;br /&gt;
        integer num=llGetListLength(mailaddresslist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(mailaddresslist,i);&lt;br /&gt;
            llEmail(address, CurrentMailSubject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMailHome() ////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMailHome(string message, string subject)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, STRING_HOME &lt;br /&gt;
                + &amp;quot; not set. Set your home adress with @HOME &amp;lt;address&amp;gt;.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        string homeaddress=llList2String(AddressBookList,index);&lt;br /&gt;
        list   homelist=llCSV2List(homeaddress);&lt;br /&gt;
        integer num=llGetListLength(homelist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(homelist,i);&lt;br /&gt;
            llEmail(address, subject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
string GetHomeAddress()&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;not set&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2String(MailAddressList,index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetHomeAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        AddressBookList     = (AddressBookList=[]) + [ STRING_HOME ] + AddressBookList;&lt;br /&gt;
        MailAddressList     = (MailAddressList=[]) + [ GetAndCheckAddressStr(address) ]  + MailAddressList;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MailAddressList = llListReplaceList(MailAddressList, [ GetAndCheckAddressStr(address) ], index, index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        Line=0;&lt;br /&gt;
        Section=0;&lt;br /&gt;
        llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// dataserver() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqAddressBook)&lt;br /&gt;
        {&lt;br /&gt;
            reqAddressBook = NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                ProcessLine(data);&lt;br /&gt;
                reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Address Book loaded.&amp;quot;, NULL_KEY);&lt;br /&gt;
                state running;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// timer() ///////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_ERROR, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Could not read Address Book: &amp;quot; &lt;br /&gt;
                            + ADDRESSBOOK_NOTECARD + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// link_message() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_MESSAGE_GETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is empty.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailSubject = message;&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is empty.&amp;quot;, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            SetMailAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Body of message to send is empty. &amp;quot; &lt;br /&gt;
                                +  &amp;quot;No mail is send.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SENDHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SendMailHome(message, (string)id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetInventoryType(message) == INVENTORY_NOTECARD)&lt;br /&gt;
            {&lt;br /&gt;
                Notecard2Fetch = message;                &lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_READ, message, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + message + &amp;quot; not found.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_NOTECARD_FETCHED)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + Notecard2Fetch &lt;br /&gt;
                            + &amp;quot; was empty or could not be read.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Home address is: &amp;quot; + GetHomeAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SetHomeAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_INFO)&lt;br /&gt;
        {&lt;br /&gt;
            Info();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
// End SL Mail AddressBook V1.2.lsl&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail FetchNotecard V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch the contents of a notecard and return it via link message as a string.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Notecard&lt;br /&gt;
&lt;br /&gt;
integer Line=0;&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
key     reqNotecard=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=10.0;&lt;br /&gt;
integer Fetched=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Lines&lt;br /&gt;
&lt;br /&gt;
list LineList=[];&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    /////////////////////// dataserver() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqNotecard)&lt;br /&gt;
        {&lt;br /&gt;
            reqNotecard=NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                LineList = (LineList=[]) + LineList + [ data ];&lt;br /&gt;
                reqNotecard = llGetNotecardLine(Notecard2Fetch, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Fetched=TRUE;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, llDumpList2String(LineList, &amp;quot;\n&amp;quot;), NULL_KEY);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /////////////////////// timer() ///////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        if (!Fetched)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            llSetTimerEvent(0.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer send, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_NOTECARD_READ)&lt;br /&gt;
        {&lt;br /&gt;
            Line=0;&lt;br /&gt;
            Notecard2Fetch=message;&lt;br /&gt;
            LineList=[];&lt;br /&gt;
            Fetched=FALSE;&lt;br /&gt;
            reqNotecard=llGetNotecardLine(Notecard2Fetch, Line);&lt;br /&gt;
            llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL OnlineStatus V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch online status of owner.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Online status&lt;br /&gt;
&lt;br /&gt;
key     reqOnlineStatus=NULL_KEY;&lt;br /&gt;
float   STATUS_INTERVAL=2.0;&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_STATUS_ONLINE       = 30000;&lt;br /&gt;
integer MS_STATUS_OFFLINE       = 30100;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus=llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
        llSetTimerEvent(STATUS_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// dataserver() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqOnlineStatus)&lt;br /&gt;
        {&lt;br /&gt;
            reqOnlineStatus = NULL_KEY;&lt;br /&gt;
        &lt;br /&gt;
            if (data==&amp;quot;1&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_STATUS_ONLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if (data==&amp;quot;0&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MS_STATUS_OFFLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus = llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Help V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Display help information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail Help V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP    = 10000;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Help() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Help()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;HELP for SL Mail V1.2.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;COMMANDS:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HELP               - displays help info.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@INFO               - display mailaddress of this object.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RECORD             - start recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CONTINUE           - continue recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@STOP               - stop recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@IGNORE             - ignore the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SHOW               - show what your recorded.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SEND               - send the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@MAIL &amp;lt;mailadress&amp;gt;  - set the mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SUBJECT subject    - set the mail subject.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LIST               - list messages in mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SELECT &amp;lt;message&amp;gt;   - select message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@READ               - read current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@NEXT               - read next message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@PREV               - read previous message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@FIRST              - read first message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LAST               - read last message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@DELETE             - delete current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CLEAR              - clear the mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@REPLY              - reply to current message.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RESET              - reset the script.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HOME               - set the home mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@OFF                - switch mailbox OFF.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@ON                 - switch mailbox ON.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_HELP)&lt;br /&gt;
        {&lt;br /&gt;
            Help();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail Help V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}&lt;/div&gt;</description>
			<pubDate>Wed, 09 Feb 2011 23:23:45 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:SL_Mail_V1.2</comments>
		</item>
		<item>
			<title>SL Mail V1.2</title>
			<link>https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=1133912</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=1133912</guid>
			<description>&lt;p&gt;Flennan Roffo: /* PRODUCTION &amp;amp; MAINTANENCE */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}} __NOTOC__&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=&#039;&#039;&#039;Second Life mail client&#039;&#039;&#039;=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Send and receive email from within Second Life from and to any address.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implemented with Address Book function (in a notecard named &#039;Address Book&#039;) to stores addresses by name  and to compile groups of named addresses. Current version is stand-alone (no server functionality) and uses chat commands only.&lt;br /&gt;
&lt;br /&gt;
[[Image:BannerSLMail.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.slmail.info slmail.info] &amp;lt;strike&amp;gt;(website coming soon!)&amp;lt;/strike&amp;gt; &amp;lt;b&amp;gt;url slmail.info no longer used for SL Mail, and was taken for some other purpose.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Release Notes V1.2=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 Release notes (edition 2, 4 sept 2007)&lt;br /&gt;
&lt;br /&gt;
===IMPORTANT NOTICE===&lt;br /&gt;
&lt;br /&gt;
Development of SL Mail was abandoned midyear 2008. The domain slmail.info was abandoned and is now taken by another domain holder (ISS) who has nothing to do with SL Mail.&lt;br /&gt;
&lt;br /&gt;
SL Mail is considered for redevelopment under the same terms, using a version of the &#039;&#039;Serverless Key Exchange&#039;&#039; script. This allows mail clients to exchange their key adresses to other rezzed mail clients in world, and send each other info about the public name they use, and other info that could be usefull. This protocol does not use a central server.&lt;br /&gt;
&lt;br /&gt;
See: [https://wiki.secondlife.com/wiki/Serverless_Key_Exchange Serverless Key Exchange]&lt;br /&gt;
&lt;br /&gt;
Future annoucements about SL Mail development will be made here.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;LICENCE INFO&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
This program is free software: you can redistribute it and/or modify&lt;br /&gt;
it under the terms of the GNU General Public License as published by&lt;br /&gt;
the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
(at your option) any later version.&lt;br /&gt;
&lt;br /&gt;
This program is distributed in the hope that it will be useful,&lt;br /&gt;
but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
GNU General Public License for more details.&lt;br /&gt;
&lt;br /&gt;
You should have received a copy of the GNU General Public License&lt;br /&gt;
along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;PRODUCTION &amp;amp; MAINTANENCE&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
by Logic Scripted Products and Script Services&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.logicscripts.org logicscripts.org] &amp;lt;strike&amp;gt;(website coming soon!)&amp;lt;/strike&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SLurl:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Beeratron&lt;br /&gt;
|x=57&lt;br /&gt;
|y=168&lt;br /&gt;
|z=75&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Contact: [[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;DESCRIPTION&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is a simple tool to send and receive mail from within SL.&lt;br /&gt;
You can either compose a message yourself using chat recording, or choose a notecard from inventory to send. The Address Book functionality allows you to use short names for mail recipients stored in a notecard. The current version does not have a persisent mail address. Watch out for the upcoming next release (V1.3) which will facilitate persisent in-world mail addresses and will be enhanced with many new features (See: Requests For Change (RFC).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;COMMANDS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Help&#039;&#039;&#039;&lt;br /&gt;
||Show Help about available commands&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Record&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording (for owner only).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Stop&#039;&#039;&#039;&lt;br /&gt;
||Stops the chat recording without sending&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Continue&#039;&#039;&#039;&lt;br /&gt;
||Continues a previously stopped chat recording. Lines will be appended to you recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Show&#039;&#039;&#039;&lt;br /&gt;
||Shows the content of the recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send&#039;&#039;&#039;&lt;br /&gt;
||If recording, stops the recording, and sends the mail (need to supply mail address and subject first!)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send &amp;lt;notecard&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Sends the content of the notecard, instead of the chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Ignore&#039;&#039;&#039;&lt;br /&gt;
||Ignores your current chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject &amp;lt;subject&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the subject of the mail.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail subject.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Set the HOME address of the owner (mail will be forwarder to this address when offline).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home&#039;&#039;&#039;&lt;br /&gt;
||Show the HOME address.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Info&#039;&#039;&#039;&lt;br /&gt;
||Shows the mail address the object this script is running in uses (e.g. &amp;lt;object-key&amp;gt;@lsl.secondlife.com).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Read&#039;&#039;&#039;&lt;br /&gt;
||Reads the current message from the mail buffer (the mail buffer gets filled with mail you receive)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Select &amp;lt;msg&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Select a message number from the availabe messages in the mail buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Next&#039;&#039;&#039;&lt;br /&gt;
||Make next message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Prev&#039;&#039;&#039;&lt;br /&gt;
||Make previous message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@First&#039;&#039;&#039;&lt;br /&gt;
||Make the first message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Last&#039;&#039;&#039;&lt;br /&gt;
||Make the last message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Clear&#039;&#039;&#039;&lt;br /&gt;
||Clear the mail buffer&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Delete&#039;&#039;&#039;&lt;br /&gt;
||Deletes only the current message&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Reply&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording to reply to the current message. Mail adress and subject are filled in automatically.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* Commands are case insensitive (&amp;quot;@read&amp;quot; == &amp;quot;@READ&amp;quot;). Arguments might not be case insensitive.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;ADDRESS BOOK FORMAT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
A notecard of the name &#039;Address Book&#039; is read during initialization which may contain Address Book items and Groups.&lt;br /&gt;
The notecard is split in two sections, which need to be defined in that particular order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[ADDRESS BOOK]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Defines the section in which you can put names for mail addresses,  like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name1=account@thisdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name2=user@otherdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[GROUP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define groups of previously defined names under a new name, like for instance:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyGroup=Name1, Name2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note that names of groups and individual mail adresses share the same namespace and must be unique.&lt;br /&gt;
&lt;br /&gt;
So when you filled in your mail adresses in the Address Book, you can now use:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail Name1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to  &amp;lt;account@thisdomain.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail MyGroup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to &amp;lt;account@thisdomain.com&amp;gt; and &amp;lt;user@otherdomain.com&amp;gt;&lt;br /&gt;
Mails will be sent one after another.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* Names for Addreses and Groups are case insensitive (e.g. &amp;quot;mary&amp;quot;  == &amp;quot;MARY&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* The special address &#039;Self&#039; can be used in commands where otherwise an address specification can be used. &#039;Self&#039; is case insensitive (e.g. &amp;quot;self&amp;quot; == &amp;quot;SELF&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LIMITATIONS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
The current version is limited by the following:&lt;br /&gt;
&lt;br /&gt;
* Chat recording lines are limited by the 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Output of lines from the mail buffer are also limited by this 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Incoming mail is limited to a 1000 (1024?) byte limit&lt;br /&gt;
&lt;br /&gt;
* Outgoing mai is limited by a 4096 byte limit, which includes the standard mail header (region/location info on the first two lines)&lt;br /&gt;
&lt;br /&gt;
We are making adjustments to this release to help overcome these limitations. At least the line lenght limit can be overcome by introducing a line continuation character (for example a hyphen &#039;-&#039;) that when used at the end of a line appends the next line, so lines longer then 255 bytes are possible then.&lt;br /&gt;
&lt;br /&gt;
To overcome the outgoing mail length limit, the mail can be broken textualy into parts, and each part can be send seperatedely, with an indication in the subject or in an introduced primary line of the mail body to indicate that the mail was split into parts.&lt;br /&gt;
For incoming mail and at least to receive mail from other SL Mail programs, a protocol will be introduced to receive mail in parts that are joined together after receiving them to form a single mail.&lt;br /&gt;
&lt;br /&gt;
These enhancements will be made available in the next release (V1.3) of SL Mail &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;BUGS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Report any bugs you find in this release to Logic (IM: Flennan Roffo).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;REQUEST FOR CHANGE (RFC)&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Do you have additional wishes for enhancement of this product?&lt;br /&gt;
Contact Flennan Roffo and we will see if they can be implemented in the next release.&lt;br /&gt;
&lt;br /&gt;
Existing RFC&#039;s are:&lt;br /&gt;
&lt;br /&gt;
* Menu support for commands.&lt;br /&gt;
&lt;br /&gt;
* Lines on incoming/outgoing mail longer than 255 bytes.&lt;br /&gt;
&lt;br /&gt;
* Send messages longer than 4096 (minus SL mail header) bytes.&lt;br /&gt;
&lt;br /&gt;
* Receive messages longer than 1024 bytes.&lt;br /&gt;
&lt;br /&gt;
* Permanent mail addresses for the SL Mail client (like: &amp;lt;Flennan.Roffo@somedomain.sl&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Add your RFC!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In-world join the group &amp;quot;SL Mail&amp;quot; for bug reports, feature requests, the latest SL Mail release, and notices about development issues.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scripts=&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==Script: SL Mail v1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail core module which scans for incoming mail messages and executes commands used by the owner.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail V1.2.lsl&lt;br /&gt;
// (c) 2007 Logic Scripted Products and Script Services&lt;br /&gt;
// Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
// VERSION&lt;br /&gt;
// Version: 1.2&lt;br /&gt;
&lt;br /&gt;
// HISTORY&lt;br /&gt;
// Date         Version     Author              Comment&lt;br /&gt;
// --------------------------------------------------------------------------------------&lt;br /&gt;
// 28 aug 2007  V 1.0       Flennan Roffo       Created&lt;br /&gt;
//&lt;br /&gt;
//  1 sep 2007  V 1.1       Flennan Roffo       @Reply empties the recording buffer.&lt;br /&gt;
//                                                @Send while recording ends recording&lt;br /&gt;
//                                                and sends the mail if a mail address&lt;br /&gt;
//                                                and subject are supplied.&lt;br /&gt;
//                                                Fixed incorrect date in Unix2DateTime.&lt;br /&gt;
//  3 sep 2007  V 1.2       Flennan Roffo       Notification options:&lt;br /&gt;
//                                              - When online, send an IM when mail is received.&lt;br /&gt;
//                                              - When offline, send to HOME mail adress.&lt;br /&gt;
//                                              Adressbook&lt;br /&gt;
//                                              - Read adress book from config notecard.&lt;br /&gt;
&lt;br /&gt;
// LICENCE&lt;br /&gt;
// This program is free software; you can redistribute it and/or&lt;br /&gt;
// modify it under the terms of the GNU General Public License&lt;br /&gt;
// as published by the Free Software Foundation; either version 2&lt;br /&gt;
// of the License, or (at your option) any later version.&lt;br /&gt;
// &lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
// &lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program; if not, write to the Free Software&lt;br /&gt;
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
// (Also available at http://www.gnu.org/copyleft/gpl.html) &lt;br /&gt;
&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// Let&#039;s you record a message and sent to email and get messages and reply to messages.&lt;br /&gt;
// Must supply a valid mail adress and non-empty subject using chat commands.&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
// 1) Check for the maximum length of an email message (including newline and header).&lt;br /&gt;
// 2) Read adress book from notecard.                                    *DONE*&lt;br /&gt;
// 3) Send incoming mail to personal mail adress when offline.            *DONE*&lt;br /&gt;
// 4) Alert with an IM when online upon receiving new mail.                *DONE*&lt;br /&gt;
&lt;br /&gt;
string   SL_MAIL_VERSION = &amp;quot;V 1.2&amp;quot;;&lt;br /&gt;
string   SL_MAIL_DATE    = &amp;quot; 2 sep 2007&amp;quot;;&lt;br /&gt;
integer  ErrorFlag         = FALSE;&lt;br /&gt;
list     ScriptList        = [ &amp;quot;SL Mail Help V1.2&amp;quot;, &amp;quot;SL Mail AddressBook V1.2&amp;quot;, &lt;br /&gt;
                                &amp;quot;SL Mail OnlineStatus V1.2&amp;quot;, &amp;quot;SL Mail FetchNotecard V1.2&amp;quot; ];    &lt;br /&gt;
string   LSL_DOMAIN=&amp;quot;lsl.secondlife.com&amp;quot;; &lt;br /&gt;
integer  StatusOnline=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Commands&lt;br /&gt;
&lt;br /&gt;
string  COMMAND_RECORD     = &amp;quot;@RECORD&amp;quot;;&lt;br /&gt;
string  COMMAND_CONTINUE   = &amp;quot;@CONTINUE&amp;quot;;&lt;br /&gt;
string  COMMAND_STOP       = &amp;quot;@STOP&amp;quot;;&lt;br /&gt;
string  COMMAND_MAIL       = &amp;quot;@MAIL&amp;quot;;&lt;br /&gt;
string  COMMAND_SUBJECT    = &amp;quot;@SUBJECT&amp;quot;;&lt;br /&gt;
string  COMMAND_SEND       = &amp;quot;@SEND&amp;quot;;&lt;br /&gt;
string  COMMAND_SEE        = &amp;quot;@SEE&amp;quot;;&lt;br /&gt;
string  COMMAND_IGNORE     = &amp;quot;@IGNORE&amp;quot;;&lt;br /&gt;
string  COMMAND_READ       = &amp;quot;@READ&amp;quot;;&lt;br /&gt;
string  COMMAND_DELETE     = &amp;quot;@DELETE&amp;quot;;&lt;br /&gt;
string  COMMAND_CLEAR      = &amp;quot;@CLEAR&amp;quot;;&lt;br /&gt;
string  COMMAND_REPLY      = &amp;quot;@REPLY&amp;quot;;&lt;br /&gt;
string  COMMAND_NEXT       = &amp;quot;@NEXT&amp;quot;;&lt;br /&gt;
string  COMMAND_PREV       = &amp;quot;@PREV&amp;quot;;&lt;br /&gt;
string  COMMAND_FIRST      = &amp;quot;@FIRST&amp;quot;;&lt;br /&gt;
string  COMMAND_LAST       = &amp;quot;@LAST&amp;quot;;&lt;br /&gt;
string  COMMAND_LIST       = &amp;quot;@LIST&amp;quot;;&lt;br /&gt;
string  COMMAND_SELECT     = &amp;quot;@SELECT&amp;quot;;&lt;br /&gt;
string  COMMAND_HELP       = &amp;quot;@HELP&amp;quot;;&lt;br /&gt;
string  COMMAND_INFO       = &amp;quot;@INFO&amp;quot;;&lt;br /&gt;
string  COMMAND_RESET      = &amp;quot;@RESET&amp;quot;;&lt;br /&gt;
string  COMMAND_SHOW       = &amp;quot;@SHOW&amp;quot;;&lt;br /&gt;
string  COMMAND_ON         = &amp;quot;@ON&amp;quot;;&lt;br /&gt;
string  COMMAND_OFF        = &amp;quot;@OFF&amp;quot;;&lt;br /&gt;
string  COMMAND_HOME       = &amp;quot;@HOME&amp;quot;;&lt;br /&gt;
string  COMMAND_LOAD       = &amp;quot;@LOAD&amp;quot;;&lt;br /&gt;
string  COMMAND_ADDRESS    = &amp;quot;@ADDRESS&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Recording&lt;br /&gt;
&lt;br /&gt;
integer Recording = FALSE;&lt;br /&gt;
&lt;br /&gt;
list    ChatRecording=[];&lt;br /&gt;
integer NumLines=0;&lt;br /&gt;
integer Length=0;&lt;br /&gt;
&lt;br /&gt;
list     TimeList=[];&lt;br /&gt;
list     AddressList=[];&lt;br /&gt;
list     SubjectList=[];&lt;br /&gt;
list     BodyList=[];&lt;br /&gt;
integer  NumMessages=0;&lt;br /&gt;
integer  CurrentMessage=-1;&lt;br /&gt;
&lt;br /&gt;
float    MAIL_FETCH_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
// Link Messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP                        = 10000;&lt;br /&gt;
integer MSG_STATUS_ONLINE               = 30000;&lt;br /&gt;
integer MSG_STATUS_OFFLINE              = 30100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED          = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR           = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Unix Time conversion //////////////////&lt;br /&gt;
&lt;br /&gt;
integer DAYS_PER_YEAR        = 365;                // Non leap year&lt;br /&gt;
integer SECONDS_PER_YEAR     = 31536000;          // Non leap year&lt;br /&gt;
integer SECONDS_PER_DAY      = 86400;&lt;br /&gt;
integer SECONDS_PER_HOUR     = 3600;&lt;br /&gt;
integer SECONDS_PER_MINUTE   = 60;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// LeapYear() /////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer LeapYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (year % 4 == 0)&lt;br /&gt;
    {&lt;br /&gt;
        if (year % 100 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (year % 400 == 0)&lt;br /&gt;
            {&lt;br /&gt;
                return 1;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// DaysPerMonth() ///////////////////////////////////////&lt;br /&gt;
                &lt;br /&gt;
integer DaysPerMonth(integer year,integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;lt; 8)&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (month == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if (LeapYear(year))&lt;br /&gt;
                {&lt;br /&gt;
                    return 29;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    return 28;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 30;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 30;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////// DaysPerYear() ////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DaysPerYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (LeapYear(year))&lt;br /&gt;
        return DAYS_PER_YEAR + 1;&lt;br /&gt;
    else&lt;br /&gt;
        return DAYS_PER_YEAR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Unix2DataTime() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list Unix2DateTime(integer unixtime)&lt;br /&gt;
{&lt;br /&gt;
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;&lt;br /&gt;
    integer day = days_since_1_1_1970 + 1;&lt;br /&gt;
    integer year  = 1970;&lt;br /&gt;
    integer days_per_year = DaysPerYear(year);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_year)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_year;&lt;br /&gt;
        ++year;&lt;br /&gt;
        days_per_year = DaysPerYear(year);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer month = 1;&lt;br /&gt;
    integer days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_month)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_month;&lt;br /&gt;
        &lt;br /&gt;
        if (++month &amp;gt; 12)&lt;br /&gt;
        {    &lt;br /&gt;
            ++year;&lt;br /&gt;
            month = 1;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;&lt;br /&gt;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;&lt;br /&gt;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;&lt;br /&gt;
    integer minute      = second / SECONDS_PER_MINUTE;&lt;br /&gt;
    second               = second % SECONDS_PER_MINUTE;&lt;br /&gt;
    &lt;br /&gt;
    return [ year, month, day, hour, minute, second ];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// MonthName() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list MonthNameList = [     &amp;quot;JAN&amp;quot;, &amp;quot;FEB&amp;quot;, &amp;quot;MAR&amp;quot;, &amp;quot;APR&amp;quot;, &amp;quot;MAY&amp;quot;, &amp;quot;JUN&amp;quot;, &lt;br /&gt;
                        &amp;quot;JUL&amp;quot;, &amp;quot;AUG&amp;quot;, &amp;quot;SEP&amp;quot;, &amp;quot;OCT&amp;quot; , &amp;quot;NOV&amp;quot;, &amp;quot;DEC&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
string MonthName(integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;gt;= 0 &amp;amp;&amp;amp; month &amp;lt; 12)&lt;br /&gt;
        return llList2String(MonthNameList, month);&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// DateString() ///////////////////////////&lt;br /&gt;
&lt;br /&gt;
string DateString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer year       = llList2Integer(timelist,0);&lt;br /&gt;
    integer month      = llList2Integer(timelist,1);&lt;br /&gt;
    integer day        = llList2Integer(timelist,2);&lt;br /&gt;
    &lt;br /&gt;
    return (string)day + &amp;quot;-&amp;quot; + MonthName(month - 1) + &amp;quot;-&amp;quot; + (string)year;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// TimeString() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string TimeString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer hour          = llList2Integer(timelist,3);&lt;br /&gt;
    integer minute         = llList2Integer(timelist,4);&lt;br /&gt;
    integer second         = llList2Integer(timelist,5);&lt;br /&gt;
    string  hourstr     = (string)hour;&lt;br /&gt;
    string  minutestr   = (string)minute;&lt;br /&gt;
    string  secondstr   = (string)second;&lt;br /&gt;
    &lt;br /&gt;
    if (hour &amp;lt; 10)         hourstr     = &amp;quot;0&amp;quot; + hourstr;&lt;br /&gt;
    if (minute &amp;lt; 10)     minutestr     = &amp;quot;0&amp;quot; + minutestr;&lt;br /&gt;
    if (second &amp;lt; 10)    secondstr    = &amp;quot;0&amp;quot; + secondstr;&lt;br /&gt;
    return hourstr + &amp;quot;:&amp;quot; + minutestr + &amp;quot;:&amp;quot; + secondstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() /////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string body)&lt;br /&gt;
{&lt;br /&gt;
    // llOwnerSay(&amp;quot;Sending message to &#039;&amp;quot; + address + &amp;quot;&#039; with subject &#039;&amp;quot; + subject +&amp;quot;&#039;.&amp;quot;);&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND, body, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// SendHome() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendHome(string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SENDHOME, body, (key)subject);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Show() ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Show()&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;Current chat recording is:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; NumLines; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(ChatRecording,i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;Lines is &amp;quot; + (string)NumLines);&lt;br /&gt;
    llOwnerSay(&amp;quot;Message length is &amp;quot; + (string)Length);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Read() /////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Read()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;Reading message &amp;quot; + (string)CurrentMessage + &amp;quot; from mail buffer.&amp;quot;);&lt;br /&gt;
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);&lt;br /&gt;
    list timelist=Unix2DateTime(time);&lt;br /&gt;
    string Address = llList2String(AddressList,CurrentMessage);&lt;br /&gt;
    string Subject = llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
    string Body    = llList2String(BodyList,CurrentMessage);&lt;br /&gt;
    llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Address: &amp;quot; + Address);&lt;br /&gt;
    llOwnerSay(&amp;quot;Subject: &amp;quot; + Subject);&lt;br /&gt;
    llOwnerSay(&amp;quot;Begin of message body:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    list bodylist=llParseStringKeepNulls(Body, [ &amp;quot;\n&amp;quot; ], []);&lt;br /&gt;
    integer num=llGetListLength(bodylist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(bodylist,i));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;End of message body.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////// List ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
List()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;The mail buffer contains the following messages:\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; NumMessages; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer time=llList2Integer(TimeList,i);&lt;br /&gt;
        list timelist=Unix2DateTime(time);&lt;br /&gt;
        if (i &amp;gt; 0) llOwnerSay(&amp;quot;+-+-+-+-+-+-+-+-+-+-+-+-&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Message: &amp;quot; + (string)i);&lt;br /&gt;
        llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;From:    &amp;quot; + llList2String(AddressList,i));&lt;br /&gt;
        llOwnerSay(&amp;quot;Subject: &amp;quot; + llList2String(SubjectList,i));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////// NotifyNewMail() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
NotifyNewMail(string time, string address, string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    list timelist=Unix2DateTime((integer)time);&lt;br /&gt;
&lt;br /&gt;
    if (StatusOnline)&lt;br /&gt;
    {&lt;br /&gt;
        llInstantMessage(llGetOwner(), &amp;quot;You received a new mail message on &amp;quot; &lt;br /&gt;
                                    + DateString(timelist) + &amp;quot; at &amp;quot; + TimeString(timelist)&lt;br /&gt;
                                    + &amp;quot; from &amp;quot; + address &lt;br /&gt;
                                    + &amp;quot; with the subject &amp;quot; + subject);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        SendHome(&amp;quot;FW: &amp;quot; + subject, &amp;quot;Received at: &amp;quot; + DateString(timelist) + &amp;quot; &amp;quot; + TimeString(timelist) + &amp;quot;\nFrom: &amp;quot; +  address &lt;br /&gt;
                    + &amp;quot;\nBegin message body:\n-------------------\n&amp;quot; + body + &amp;quot;\n-------------------\nEnd message body.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ResetOtherScripts() //////////////////////&lt;br /&gt;
&lt;br /&gt;
ResetOtherScripts()&lt;br /&gt;
{&lt;br /&gt;
    string     name;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(ScriptList);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        name = llList2String(ScriptList,i);&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(name) == INVENTORY_SCRIPT)&lt;br /&gt;
        {&lt;br /&gt;
            llResetOtherScript(name);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Error - script &#039;&amp;quot; + name + &amp;quot;&#039; not found.&amp;quot;);&lt;br /&gt;
            ErrorFlag = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
// default &lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ////////////////////// state_entry() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Welcome to SL Mail, released under GNU software licence.&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Version &amp;quot; + SL_MAIL_VERSION + &amp;quot; &amp;quot; + SL_MAIL_DATE);&lt;br /&gt;
        llOwnerSay(&amp;quot;Produced by Logic Scripted Products &amp;amp; Product Services&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Free memory: &amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
        ResetOtherScripts();&lt;br /&gt;
        &lt;br /&gt;
        if (ErrorFlag)&lt;br /&gt;
            state Error;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// on_rez() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// changed() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_LOADED)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_ERROR)&lt;br /&gt;
        {&lt;br /&gt;
            state Error;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() //////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(MAIL_FETCH_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //////////////////////// on_rez() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// listen() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string trimmessage=llStringTrim(message,STRING_TRIM);&lt;br /&gt;
        list   parse = llParseStringKeepNulls(trimmessage, [ &amp;quot; &amp;quot;], []);&lt;br /&gt;
        string command = llToUpper(llList2String(parse,0));&lt;br /&gt;
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        integer nargs  = llGetListLength(parse);&lt;br /&gt;
        string argstr=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (nargs &amp;gt; 1) argstr=llGetSubString(message, llSubStringIndex(message, &amp;quot; &amp;quot;) + 1, -1);&lt;br /&gt;
            &lt;br /&gt;
        if (Recording)&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Recording stopped. Type @SHOW to see the message you have entered,&amp;quot;&lt;br /&gt;
                            + &amp;quot; or @SEND to send it.&amp;quot;);&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                &lt;br /&gt;
                SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];&lt;br /&gt;
                ++NumLines;&lt;br /&gt;
                Length += llStringLength(message) + 2;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_RECORD)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Start recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                ChatRecording = [];&lt;br /&gt;
                NumLines=0;&lt;br /&gt;
                Length=0;&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CONTINUE)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Continue recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_REPLY)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    string address=llList2String(AddressList,CurrentMessage);&lt;br /&gt;
                    string subject=&amp;quot;Re: &amp;quot; + llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, address, NULL_KEY);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, subject, NULL_KEY);&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines=0;&lt;br /&gt;
                    Length=0;&lt;br /&gt;
                    Recording = TRUE;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_MAIL)&lt;br /&gt;
            {&lt;br /&gt;
                string mailaddress=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailaddress != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, mailaddress, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETADDRESS, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SUBJECT)&lt;br /&gt;
            {&lt;br /&gt;
                string mailsubject=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailsubject != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, mailsubject, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETSUBJECT, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Not recording.&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    if (NumLines == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND_NOTECARD, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_IGNORE)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines = 0;&lt;br /&gt;
                    Length = 0;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Show();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_READ)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumMessages == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Read();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        ++CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        --CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_FIRST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = 0;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LAST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LIST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    List();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SELECT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;Need to supply a message number.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    integer msgnum = (integer)arg;&lt;br /&gt;
                     &lt;br /&gt;
                    if (msgnum &amp;lt; 0 || msgnum &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Message number &amp;quot; + arg + &amp;quot; not in mail buffer.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = msgnum;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_DELETE)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    --NumMessages;&lt;br /&gt;
                     &lt;br /&gt;
                    if (NumMessages == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = -1;&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (CurrentMessage &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CLEAR)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList=[];&lt;br /&gt;
                    AddressList=[];&lt;br /&gt;
                    SubjectList=[];&lt;br /&gt;
                    BodyList=[];&lt;br /&gt;
                    NumMessages=0;&lt;br /&gt;
                    CurrentMessage=-1;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_HELP, arg, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_INFO)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                Show();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_RESET)&lt;br /&gt;
            {&lt;br /&gt;
                llResetScript();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                state not_running;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HOME)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs==1)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETHOME, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETHOME, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// email() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    email(string time, string address, string subject, string body, integer queued)&lt;br /&gt;
    {&lt;br /&gt;
        NotifyNewMail(time, address, subject, body);&lt;br /&gt;
        TimeList = (TimeList=[]) + TimeList + [time];&lt;br /&gt;
        AddressList = (AddressList=[]) + AddressList + [address];&lt;br /&gt;
        SubjectList = (SubjectList=[]) + SubjectList + [subject];&lt;br /&gt;
        BodyList = (BodyList=[]) + BodyList + [body];&lt;br /&gt;
        ++NumMessages;&lt;br /&gt;
        &lt;br /&gt;
        if (CurrentMessage == -1)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = NumMessages - 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_REPLY)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state not_running&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state not_running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;SL Mailbox switched OFF. Say @ON to switch it back on.&amp;quot;);&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// on_rez() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// listen() ////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer chan, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string command=llToUpper(message);&lt;br /&gt;
        &lt;br /&gt;
        if (command == COMMAND_ON)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state Error&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state Error&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Error in SL Mail: not all component scripts found.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// End SL Mail V1.2.lsl&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Address Book V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Read and interpret the contents of the Address Book.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail AddressBook V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// &lt;br /&gt;
//  Read the Address Book from a notecard named &amp;quot;Address Book&amp;quot;.&lt;br /&gt;
//&lt;br /&gt;
//  The Address Book has the following format:&lt;br /&gt;
//  &lt;br /&gt;
//  [ADDRESS BOOK]&lt;br /&gt;
//  Name1=username@yourdomain.com&lt;br /&gt;
//  Name2=otheruser@otherdomain.com&lt;br /&gt;
//  ...&lt;br /&gt;
//  [GROUP]&lt;br /&gt;
//  group1=Name1, Name2&lt;br /&gt;
//  ...&lt;br /&gt;
//&lt;br /&gt;
//  Notes:&lt;br /&gt;
//  1. Group and Name share the same namespace, and must be unique.&lt;br /&gt;
//  2. It is allowed to have a name in the addressbook with multiple addresses, seperated by comma&#039;s.&lt;br /&gt;
// &lt;br /&gt;
/////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string  CurrentMailAddress = &amp;quot;&amp;quot;;&lt;br /&gt;
string  CurrentMailSubject = &amp;quot;&amp;quot;;&lt;br /&gt;
integer StatusOnline = FALSE;&lt;br /&gt;
&lt;br /&gt;
// Fetch or Send notecard&lt;br /&gt;
&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Names&lt;br /&gt;
&lt;br /&gt;
list    AddressBookList=[];&lt;br /&gt;
list    MailAddressList=[];&lt;br /&gt;
&lt;br /&gt;
string  STRING_HOME=&amp;quot;HOME&amp;quot;;&lt;br /&gt;
string  STRING_SELF=&amp;quot;SELF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Groups&lt;br /&gt;
&lt;br /&gt;
list   GroupList=[];&lt;br /&gt;
list   GroupNameList=[];&lt;br /&gt;
&lt;br /&gt;
string LSL_DOMAIN = &amp;quot;lsl.secondlife.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Read Address Book notecard&lt;br /&gt;
&lt;br /&gt;
string  ADDRESSBOOK_NOTECARD=&amp;quot;Address Book&amp;quot;;&lt;br /&gt;
integer Line=0;&lt;br /&gt;
key     reqAddressBook=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
integer Section=0;&lt;br /&gt;
integer SECTION_ADDRESS_BOOK=1;&lt;br /&gt;
integer SECTION_GROUP=2;&lt;br /&gt;
string  STRING_ADDRESS_BOOK=&amp;quot;ADDRESS BOOK&amp;quot;;&lt;br /&gt;
string  STRING_GROUP=&amp;quot;GROUP&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Links messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
integer MSG_MESSAGE_NOTIFY              = 90900;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED            = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR            = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// GetSelfAddress() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
string GetSelfAddress()&lt;br /&gt;
{&lt;br /&gt;
    return (string)llGetKey() + &amp;quot;@&amp;quot; + LSL_DOMAIN;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Info() /////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Info()&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;The mail address for this object is: &amp;quot; &lt;br /&gt;
                    + GetSelfAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// IsValidKeyFormat() //////////////////////&lt;br /&gt;
&lt;br /&gt;
integer IsValidKeyFormat(string str)&lt;br /&gt;
{&lt;br /&gt;
    string keychars = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    if (llStringLength(str) != 36)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    if( (llGetSubString( str, 8, 8 )   != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 13, 13 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 18, 18 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 23, 23 )  != &amp;quot;-&amp;quot; ) )&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 9; i &amp;lt; 13; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 14; i &amp;lt; 18; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 19; i &amp;lt; 23; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 24; i &amp;lt; 36; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// ValidMailAddress() ////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer ValidMailAddress(string arg)&lt;br /&gt;
{&lt;br /&gt;
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));&lt;br /&gt;
    &lt;br /&gt;
    if (adress == &amp;quot;&amp;quot;)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    list parse = llParseStringKeepNulls(adress, [ &amp;quot;@&amp;quot; ], []);&lt;br /&gt;
    string account = llList2String(parse,0);&lt;br /&gt;
    string domain  = llList2String(parse,1);&lt;br /&gt;
    &lt;br /&gt;
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    &lt;br /&gt;
    if (domain == LSL_DOMAIN)&lt;br /&gt;
    {&lt;br /&gt;
        return IsValidKeyFormat(account);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list parsedomain = llParseString2List(domain, [ &amp;quot;.&amp;quot; ], []);&lt;br /&gt;
    &lt;br /&gt;
        if (llGetListLength(parsedomain) &amp;lt; 2)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        &lt;br /&gt;
        integer num = llGetListLength(parsedomain);&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llStringLength(llList2String(parsedomain,i)) &amp;lt; 2)&lt;br /&gt;
            {&lt;br /&gt;
                return FALSE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetAddressStr() ///////////////////&lt;br /&gt;
&lt;br /&gt;
string GetAndCheckAddressStr(string address)&lt;br /&gt;
{&lt;br /&gt;
    list addresslist = llCSV2List(address);&lt;br /&gt;
    integer num=llGetListLength(addresslist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    string addressstr=&amp;quot;&amp;quot;;&lt;br /&gt;
    string curaddress=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        curaddress=llList2String(addresslist,i);&lt;br /&gt;
        &lt;br /&gt;
        if (ValidMailAddress(curaddress))&lt;br /&gt;
        {&lt;br /&gt;
            addressstr = (addressstr=&amp;quot;&amp;quot;) + addressstr + curaddress + &amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address string: &#039;&amp;quot; &lt;br /&gt;
                            + curaddress + &amp;quot;&#039;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return llGetSubString(addressstr, 0, -2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ProcessLine() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
ProcessLine(string rawline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(rawline,STRING_TRIM);&lt;br /&gt;
    string first=llGetSubString(line,0,0);&lt;br /&gt;
    string last=llGetSubString(line,-1,-1);&lt;br /&gt;
    &lt;br /&gt;
    // Ignore a blank line or comment line&lt;br /&gt;
    if (line == &amp;quot;&amp;quot; || first == &amp;quot;#&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // Check for the right section&lt;br /&gt;
    &lt;br /&gt;
    if (first == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; last == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        string sectionstr=llToUpper(llStringTrim(llGetSubString(line,1,-2),STRING_TRIM));&lt;br /&gt;
        &lt;br /&gt;
        if (sectionstr == STRING_ADDRESS_BOOK)&lt;br /&gt;
        {&lt;br /&gt;
            Section = SECTION_ADDRESS_BOOK;&lt;br /&gt;
        }&lt;br /&gt;
        else if (sectionstr == STRING_GROUP)&lt;br /&gt;
        {&lt;br /&gt;
            if (Section == 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                        + &amp;quot;. Group section defined before Address Book section.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Section = SECTION_GROUP;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid section header &#039;&amp;quot; + sectionstr &lt;br /&gt;
                        + &amp;quot;&#039; in &amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Must be in a section&lt;br /&gt;
    &lt;br /&gt;
    if (Section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;. No section header.&amp;quot;, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    list     parse=llParseString2List(line, [ &amp;quot;=&amp;quot; ], []);&lt;br /&gt;
    integer  num=llGetListLength(parse);&lt;br /&gt;
    &lt;br /&gt;
    // Format must be correct&lt;br /&gt;
    &lt;br /&gt;
    if (num != 2)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; +  (string)(Line+1) + &amp;quot;:\n&amp;quot; + rawline, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (Section == SECTION_ADDRESS_BOOK)&lt;br /&gt;
    {&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(name) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + name &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ name ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            string address=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
            string addressstr=GetAndCheckAddressStr(address);&lt;br /&gt;
            &lt;br /&gt;
            if (addressstr != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                AddressBookList     = (AddressBookList=[])     + AddressBookList     + [ name ];&lt;br /&gt;
                MailAddressList     = (MailAddressList=[])     + MailAddressList     + [ addressstr ];&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;No valid mail address for &#039;&amp;quot; + name &lt;br /&gt;
                    + &amp;quot;&#039;. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                    + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name &lt;br /&gt;
                + &amp;quot;&#039; already defined. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // Group&lt;br /&gt;
    {&lt;br /&gt;
        string group=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(group) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + group &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ group ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(GroupList, [ group ]) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                string names=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
                list   namelist=llCSV2List(names);&lt;br /&gt;
                integer num=llGetListLength(namelist);&lt;br /&gt;
                integer i;&lt;br /&gt;
                integer index;&lt;br /&gt;
                string  name;&lt;br /&gt;
                string  namestr=&amp;quot;&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
                for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                    name=llList2String(namelist,i);&lt;br /&gt;
                    index=llListFindList(AddressBookList, [ name ]);&lt;br /&gt;
            &lt;br /&gt;
                    if (index == -1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name + &amp;quot;&#039; defined in Group &#039;&amp;quot; &lt;br /&gt;
                                + group + &amp;quot;&#039; not found in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY); &lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        namestr = (namestr=&amp;quot;&amp;quot;) + namestr + name + &amp;quot;,&amp;quot;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (namestr != &amp;quot;&amp;quot;)&lt;br /&gt;
                {    &lt;br /&gt;
                    namestr=llGetSubString(namestr,0,-2);&lt;br /&gt;
                    GroupList         = (GroupList=[])         + GroupList     + [ group ];&lt;br /&gt;
                    GroupNameList     = (GroupNameList=[])    + GroupNameList + [ namestr ];&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                        + &amp;quot;&#039; has no valid names. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                        + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                    + &amp;quot;&#039; already defined in Group. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                    + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group&lt;br /&gt;
                + &amp;quot;&#039; already defined in Address Book. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// GetGroupAddressList ///////////////&lt;br /&gt;
&lt;br /&gt;
string GetGroupAddressList(string group)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(GroupList, [ group ]);&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(GroupList);&lt;br /&gt;
    string  grouplist=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        for (i = index; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2String(GroupList,i) == group)&lt;br /&gt;
            {&lt;br /&gt;
                grouplist = (grouplist=&amp;quot;&amp;quot;) + grouplist + llList2String(GroupNameList,i) + &amp;quot;,&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (grouplist != &amp;quot;&amp;quot;) grouplist=llGetSubString(grouplist,0,-2);   // remove last &amp;quot;,&amp;quot;&lt;br /&gt;
        return grouplist;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// SetMailAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetMailAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ address ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        index=llListFindList(GroupList, [ address ]);&lt;br /&gt;
        &lt;br /&gt;
        if (index == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llToUpper(address) == STRING_SELF)&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = GetSelfAddress();&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if(ValidMailAddress(address))&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = address;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Mail adress &amp;quot; + address &lt;br /&gt;
                            + &amp;quot; : not found in adress book or invalid format.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailAddress = GetGroupAddressList(address);&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        CurrentMailAddress = llList2String(MailAddressList,index);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                        + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string message)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No mail address defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No subject defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list mailaddresslist=llCSV2List(CurrentMailAddress);&lt;br /&gt;
        integer num=llGetListLength(mailaddresslist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(mailaddresslist,i);&lt;br /&gt;
            llEmail(address, CurrentMailSubject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMailHome() ////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMailHome(string message, string subject)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, STRING_HOME &lt;br /&gt;
                + &amp;quot; not set. Set your home adress with @HOME &amp;lt;address&amp;gt;.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        string homeaddress=llList2String(AddressBookList,index);&lt;br /&gt;
        list   homelist=llCSV2List(homeaddress);&lt;br /&gt;
        integer num=llGetListLength(homelist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(homelist,i);&lt;br /&gt;
            llEmail(address, subject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
string GetHomeAddress()&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;not set&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2String(MailAddressList,index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetHomeAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        AddressBookList     = (AddressBookList=[]) + [ STRING_HOME ] + AddressBookList;&lt;br /&gt;
        MailAddressList     = (MailAddressList=[]) + [ GetAndCheckAddressStr(address) ]  + MailAddressList;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MailAddressList = llListReplaceList(MailAddressList, [ GetAndCheckAddressStr(address) ], index, index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        Line=0;&lt;br /&gt;
        Section=0;&lt;br /&gt;
        llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// dataserver() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqAddressBook)&lt;br /&gt;
        {&lt;br /&gt;
            reqAddressBook = NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                ProcessLine(data);&lt;br /&gt;
                reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Address Book loaded.&amp;quot;, NULL_KEY);&lt;br /&gt;
                state running;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// timer() ///////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_ERROR, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Could not read Address Book: &amp;quot; &lt;br /&gt;
                            + ADDRESSBOOK_NOTECARD + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// link_message() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_MESSAGE_GETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is empty.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailSubject = message;&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is empty.&amp;quot;, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            SetMailAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Body of message to send is empty. &amp;quot; &lt;br /&gt;
                                +  &amp;quot;No mail is send.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SENDHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SendMailHome(message, (string)id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetInventoryType(message) == INVENTORY_NOTECARD)&lt;br /&gt;
            {&lt;br /&gt;
                Notecard2Fetch = message;                &lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_READ, message, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + message + &amp;quot; not found.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_NOTECARD_FETCHED)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + Notecard2Fetch &lt;br /&gt;
                            + &amp;quot; was empty or could not be read.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Home address is: &amp;quot; + GetHomeAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SetHomeAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_INFO)&lt;br /&gt;
        {&lt;br /&gt;
            Info();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
// End SL Mail AddressBook V1.2.lsl&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail FetchNotecard V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch the contents of a notecard and return it via link message as a string.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Notecard&lt;br /&gt;
&lt;br /&gt;
integer Line=0;&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
key     reqNotecard=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=10.0;&lt;br /&gt;
integer Fetched=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Lines&lt;br /&gt;
&lt;br /&gt;
list LineList=[];&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    /////////////////////// dataserver() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqNotecard)&lt;br /&gt;
        {&lt;br /&gt;
            reqNotecard=NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                LineList = (LineList=[]) + LineList + [ data ];&lt;br /&gt;
                reqNotecard = llGetNotecardLine(Notecard2Fetch, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Fetched=TRUE;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, llDumpList2String(LineList, &amp;quot;\n&amp;quot;), NULL_KEY);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /////////////////////// timer() ///////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        if (!Fetched)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            llSetTimerEvent(0.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer send, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_NOTECARD_READ)&lt;br /&gt;
        {&lt;br /&gt;
            Line=0;&lt;br /&gt;
            Notecard2Fetch=message;&lt;br /&gt;
            LineList=[];&lt;br /&gt;
            Fetched=FALSE;&lt;br /&gt;
            reqNotecard=llGetNotecardLine(Notecard2Fetch, Line);&lt;br /&gt;
            llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL OnlineStatus V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch online status of owner.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Online status&lt;br /&gt;
&lt;br /&gt;
key     reqOnlineStatus=NULL_KEY;&lt;br /&gt;
float   STATUS_INTERVAL=2.0;&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_STATUS_ONLINE       = 30000;&lt;br /&gt;
integer MS_STATUS_OFFLINE       = 30100;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus=llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
        llSetTimerEvent(STATUS_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// dataserver() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqOnlineStatus)&lt;br /&gt;
        {&lt;br /&gt;
            reqOnlineStatus = NULL_KEY;&lt;br /&gt;
        &lt;br /&gt;
            if (data==&amp;quot;1&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_STATUS_ONLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if (data==&amp;quot;0&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MS_STATUS_OFFLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus = llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Help V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Display help information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail Help V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP    = 10000;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Help() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Help()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;HELP for SL Mail V1.2.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;COMMANDS:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HELP               - displays help info.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@INFO               - display mailaddress of this object.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RECORD             - start recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CONTINUE           - continue recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@STOP               - stop recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@IGNORE             - ignore the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SHOW               - show what your recorded.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SEND               - send the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@MAIL &amp;lt;mailadress&amp;gt;  - set the mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SUBJECT subject    - set the mail subject.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LIST               - list messages in mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SELECT &amp;lt;message&amp;gt;   - select message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@READ               - read current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@NEXT               - read next message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@PREV               - read previous message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@FIRST              - read first message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LAST               - read last message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@DELETE             - delete current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CLEAR              - clear the mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@REPLY              - reply to current message.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RESET              - reset the script.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HOME               - set the home mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@OFF                - switch mailbox OFF.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@ON                 - switch mailbox ON.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_HELP)&lt;br /&gt;
        {&lt;br /&gt;
            Help();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail Help V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}&lt;/div&gt;</description>
			<pubDate>Wed, 09 Feb 2011 23:22:06 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:SL_Mail_V1.2</comments>
		</item>
		<item>
			<title>SL Mail V1.2</title>
			<link>https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=1133911</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=1133911</guid>
			<description>&lt;p&gt;Flennan Roffo: /* PRODUCTION &amp;amp; MAINTANENCE */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}} __NOTOC__&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=&#039;&#039;&#039;Second Life mail client&#039;&#039;&#039;=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Send and receive email from within Second Life from and to any address.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implemented with Address Book function (in a notecard named &#039;Address Book&#039;) to stores addresses by name  and to compile groups of named addresses. Current version is stand-alone (no server functionality) and uses chat commands only.&lt;br /&gt;
&lt;br /&gt;
[[Image:BannerSLMail.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.slmail.info slmail.info] &amp;lt;strike&amp;gt;(website coming soon!)&amp;lt;/strike&amp;gt; &amp;lt;b&amp;gt;url slmail.info no longer used for SL Mail, and was taken for some other purpose.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Release Notes V1.2=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 Release notes (edition 2, 4 sept 2007)&lt;br /&gt;
&lt;br /&gt;
===IMPORTANT NOTICE===&lt;br /&gt;
&lt;br /&gt;
Development of SL Mail was abandoned midyear 2008. The domain slmail.info was abandoned and is now taken by another domain holder (ISS) who has nothing to do with SL Mail.&lt;br /&gt;
&lt;br /&gt;
SL Mail is considered for redevelopment under the same terms, using a version of the &#039;&#039;Serverless Key Exchange&#039;&#039; script. This allows mail clients to exchange their key adresses to other rezzed mail clients in world, and send each other info about the public name they use, and other info that could be usefull. This protocol does not use a central server.&lt;br /&gt;
&lt;br /&gt;
See: [https://wiki.secondlife.com/wiki/Serverless_Key_Exchange Serverless Key Exchange]&lt;br /&gt;
&lt;br /&gt;
Future annoucements about SL Mail development will be made here.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;LICENCE INFO&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
This program is free software: you can redistribute it and/or modify&lt;br /&gt;
it under the terms of the GNU General Public License as published by&lt;br /&gt;
the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
(at your option) any later version.&lt;br /&gt;
&lt;br /&gt;
This program is distributed in the hope that it will be useful,&lt;br /&gt;
but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
GNU General Public License for more details.&lt;br /&gt;
&lt;br /&gt;
You should have received a copy of the GNU General Public License&lt;br /&gt;
along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;PRODUCTION &amp;amp; MAINTANENCE&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
by Logic Scripted Products and Script Services&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.logicscripts.org logicscripts.org] &amp;lt;strike&amp;gt;(website coming soon!)&amp;lt;/strike&amp;gt;&lt;br /&gt;
&lt;br /&gt;
SLurl:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Contact: [[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
&lt;br /&gt;
Email: [mailto:info@slmail.info &#039;&#039;&#039;info&#039;&#039;&#039;] or [mailto:Flennan.Roffo@slmail.info &#039;&#039;&#039;Flennan Roffo&#039;&#039;&#039;]&lt;br /&gt;
&#039;&#039;&#039;* The slmail.info URL appears to not be registered and this information appears to be out of date. *&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;DESCRIPTION&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is a simple tool to send and receive mail from within SL.&lt;br /&gt;
You can either compose a message yourself using chat recording, or choose a notecard from inventory to send. The Address Book functionality allows you to use short names for mail recipients stored in a notecard. The current version does not have a persisent mail address. Watch out for the upcoming next release (V1.3) which will facilitate persisent in-world mail addresses and will be enhanced with many new features (See: Requests For Change (RFC).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;COMMANDS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Help&#039;&#039;&#039;&lt;br /&gt;
||Show Help about available commands&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Record&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording (for owner only).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Stop&#039;&#039;&#039;&lt;br /&gt;
||Stops the chat recording without sending&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Continue&#039;&#039;&#039;&lt;br /&gt;
||Continues a previously stopped chat recording. Lines will be appended to you recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Show&#039;&#039;&#039;&lt;br /&gt;
||Shows the content of the recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send&#039;&#039;&#039;&lt;br /&gt;
||If recording, stops the recording, and sends the mail (need to supply mail address and subject first!)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send &amp;lt;notecard&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Sends the content of the notecard, instead of the chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Ignore&#039;&#039;&#039;&lt;br /&gt;
||Ignores your current chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject &amp;lt;subject&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the subject of the mail.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail subject.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Set the HOME address of the owner (mail will be forwarder to this address when offline).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home&#039;&#039;&#039;&lt;br /&gt;
||Show the HOME address.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Info&#039;&#039;&#039;&lt;br /&gt;
||Shows the mail address the object this script is running in uses (e.g. &amp;lt;object-key&amp;gt;@lsl.secondlife.com).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Read&#039;&#039;&#039;&lt;br /&gt;
||Reads the current message from the mail buffer (the mail buffer gets filled with mail you receive)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Select &amp;lt;msg&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Select a message number from the availabe messages in the mail buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Next&#039;&#039;&#039;&lt;br /&gt;
||Make next message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Prev&#039;&#039;&#039;&lt;br /&gt;
||Make previous message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@First&#039;&#039;&#039;&lt;br /&gt;
||Make the first message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Last&#039;&#039;&#039;&lt;br /&gt;
||Make the last message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Clear&#039;&#039;&#039;&lt;br /&gt;
||Clear the mail buffer&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Delete&#039;&#039;&#039;&lt;br /&gt;
||Deletes only the current message&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Reply&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording to reply to the current message. Mail adress and subject are filled in automatically.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* Commands are case insensitive (&amp;quot;@read&amp;quot; == &amp;quot;@READ&amp;quot;). Arguments might not be case insensitive.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;ADDRESS BOOK FORMAT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
A notecard of the name &#039;Address Book&#039; is read during initialization which may contain Address Book items and Groups.&lt;br /&gt;
The notecard is split in two sections, which need to be defined in that particular order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[ADDRESS BOOK]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Defines the section in which you can put names for mail addresses,  like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name1=account@thisdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name2=user@otherdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[GROUP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define groups of previously defined names under a new name, like for instance:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyGroup=Name1, Name2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note that names of groups and individual mail adresses share the same namespace and must be unique.&lt;br /&gt;
&lt;br /&gt;
So when you filled in your mail adresses in the Address Book, you can now use:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail Name1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to  &amp;lt;account@thisdomain.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail MyGroup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to &amp;lt;account@thisdomain.com&amp;gt; and &amp;lt;user@otherdomain.com&amp;gt;&lt;br /&gt;
Mails will be sent one after another.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* Names for Addreses and Groups are case insensitive (e.g. &amp;quot;mary&amp;quot;  == &amp;quot;MARY&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* The special address &#039;Self&#039; can be used in commands where otherwise an address specification can be used. &#039;Self&#039; is case insensitive (e.g. &amp;quot;self&amp;quot; == &amp;quot;SELF&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LIMITATIONS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
The current version is limited by the following:&lt;br /&gt;
&lt;br /&gt;
* Chat recording lines are limited by the 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Output of lines from the mail buffer are also limited by this 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Incoming mail is limited to a 1000 (1024?) byte limit&lt;br /&gt;
&lt;br /&gt;
* Outgoing mai is limited by a 4096 byte limit, which includes the standard mail header (region/location info on the first two lines)&lt;br /&gt;
&lt;br /&gt;
We are making adjustments to this release to help overcome these limitations. At least the line lenght limit can be overcome by introducing a line continuation character (for example a hyphen &#039;-&#039;) that when used at the end of a line appends the next line, so lines longer then 255 bytes are possible then.&lt;br /&gt;
&lt;br /&gt;
To overcome the outgoing mail length limit, the mail can be broken textualy into parts, and each part can be send seperatedely, with an indication in the subject or in an introduced primary line of the mail body to indicate that the mail was split into parts.&lt;br /&gt;
For incoming mail and at least to receive mail from other SL Mail programs, a protocol will be introduced to receive mail in parts that are joined together after receiving them to form a single mail.&lt;br /&gt;
&lt;br /&gt;
These enhancements will be made available in the next release (V1.3) of SL Mail &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;BUGS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Report any bugs you find in this release to Logic (IM: Flennan Roffo).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;REQUEST FOR CHANGE (RFC)&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Do you have additional wishes for enhancement of this product?&lt;br /&gt;
Contact Flennan Roffo and we will see if they can be implemented in the next release.&lt;br /&gt;
&lt;br /&gt;
Existing RFC&#039;s are:&lt;br /&gt;
&lt;br /&gt;
* Menu support for commands.&lt;br /&gt;
&lt;br /&gt;
* Lines on incoming/outgoing mail longer than 255 bytes.&lt;br /&gt;
&lt;br /&gt;
* Send messages longer than 4096 (minus SL mail header) bytes.&lt;br /&gt;
&lt;br /&gt;
* Receive messages longer than 1024 bytes.&lt;br /&gt;
&lt;br /&gt;
* Permanent mail addresses for the SL Mail client (like: &amp;lt;Flennan.Roffo@somedomain.sl&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Add your RFC!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In-world join the group &amp;quot;SL Mail&amp;quot; for bug reports, feature requests, the latest SL Mail release, and notices about development issues.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scripts=&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==Script: SL Mail v1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail core module which scans for incoming mail messages and executes commands used by the owner.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail V1.2.lsl&lt;br /&gt;
// (c) 2007 Logic Scripted Products and Script Services&lt;br /&gt;
// Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
// VERSION&lt;br /&gt;
// Version: 1.2&lt;br /&gt;
&lt;br /&gt;
// HISTORY&lt;br /&gt;
// Date         Version     Author              Comment&lt;br /&gt;
// --------------------------------------------------------------------------------------&lt;br /&gt;
// 28 aug 2007  V 1.0       Flennan Roffo       Created&lt;br /&gt;
//&lt;br /&gt;
//  1 sep 2007  V 1.1       Flennan Roffo       @Reply empties the recording buffer.&lt;br /&gt;
//                                                @Send while recording ends recording&lt;br /&gt;
//                                                and sends the mail if a mail address&lt;br /&gt;
//                                                and subject are supplied.&lt;br /&gt;
//                                                Fixed incorrect date in Unix2DateTime.&lt;br /&gt;
//  3 sep 2007  V 1.2       Flennan Roffo       Notification options:&lt;br /&gt;
//                                              - When online, send an IM when mail is received.&lt;br /&gt;
//                                              - When offline, send to HOME mail adress.&lt;br /&gt;
//                                              Adressbook&lt;br /&gt;
//                                              - Read adress book from config notecard.&lt;br /&gt;
&lt;br /&gt;
// LICENCE&lt;br /&gt;
// This program is free software; you can redistribute it and/or&lt;br /&gt;
// modify it under the terms of the GNU General Public License&lt;br /&gt;
// as published by the Free Software Foundation; either version 2&lt;br /&gt;
// of the License, or (at your option) any later version.&lt;br /&gt;
// &lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
// &lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program; if not, write to the Free Software&lt;br /&gt;
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
// (Also available at http://www.gnu.org/copyleft/gpl.html) &lt;br /&gt;
&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// Let&#039;s you record a message and sent to email and get messages and reply to messages.&lt;br /&gt;
// Must supply a valid mail adress and non-empty subject using chat commands.&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
// 1) Check for the maximum length of an email message (including newline and header).&lt;br /&gt;
// 2) Read adress book from notecard.                                    *DONE*&lt;br /&gt;
// 3) Send incoming mail to personal mail adress when offline.            *DONE*&lt;br /&gt;
// 4) Alert with an IM when online upon receiving new mail.                *DONE*&lt;br /&gt;
&lt;br /&gt;
string   SL_MAIL_VERSION = &amp;quot;V 1.2&amp;quot;;&lt;br /&gt;
string   SL_MAIL_DATE    = &amp;quot; 2 sep 2007&amp;quot;;&lt;br /&gt;
integer  ErrorFlag         = FALSE;&lt;br /&gt;
list     ScriptList        = [ &amp;quot;SL Mail Help V1.2&amp;quot;, &amp;quot;SL Mail AddressBook V1.2&amp;quot;, &lt;br /&gt;
                                &amp;quot;SL Mail OnlineStatus V1.2&amp;quot;, &amp;quot;SL Mail FetchNotecard V1.2&amp;quot; ];    &lt;br /&gt;
string   LSL_DOMAIN=&amp;quot;lsl.secondlife.com&amp;quot;; &lt;br /&gt;
integer  StatusOnline=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Commands&lt;br /&gt;
&lt;br /&gt;
string  COMMAND_RECORD     = &amp;quot;@RECORD&amp;quot;;&lt;br /&gt;
string  COMMAND_CONTINUE   = &amp;quot;@CONTINUE&amp;quot;;&lt;br /&gt;
string  COMMAND_STOP       = &amp;quot;@STOP&amp;quot;;&lt;br /&gt;
string  COMMAND_MAIL       = &amp;quot;@MAIL&amp;quot;;&lt;br /&gt;
string  COMMAND_SUBJECT    = &amp;quot;@SUBJECT&amp;quot;;&lt;br /&gt;
string  COMMAND_SEND       = &amp;quot;@SEND&amp;quot;;&lt;br /&gt;
string  COMMAND_SEE        = &amp;quot;@SEE&amp;quot;;&lt;br /&gt;
string  COMMAND_IGNORE     = &amp;quot;@IGNORE&amp;quot;;&lt;br /&gt;
string  COMMAND_READ       = &amp;quot;@READ&amp;quot;;&lt;br /&gt;
string  COMMAND_DELETE     = &amp;quot;@DELETE&amp;quot;;&lt;br /&gt;
string  COMMAND_CLEAR      = &amp;quot;@CLEAR&amp;quot;;&lt;br /&gt;
string  COMMAND_REPLY      = &amp;quot;@REPLY&amp;quot;;&lt;br /&gt;
string  COMMAND_NEXT       = &amp;quot;@NEXT&amp;quot;;&lt;br /&gt;
string  COMMAND_PREV       = &amp;quot;@PREV&amp;quot;;&lt;br /&gt;
string  COMMAND_FIRST      = &amp;quot;@FIRST&amp;quot;;&lt;br /&gt;
string  COMMAND_LAST       = &amp;quot;@LAST&amp;quot;;&lt;br /&gt;
string  COMMAND_LIST       = &amp;quot;@LIST&amp;quot;;&lt;br /&gt;
string  COMMAND_SELECT     = &amp;quot;@SELECT&amp;quot;;&lt;br /&gt;
string  COMMAND_HELP       = &amp;quot;@HELP&amp;quot;;&lt;br /&gt;
string  COMMAND_INFO       = &amp;quot;@INFO&amp;quot;;&lt;br /&gt;
string  COMMAND_RESET      = &amp;quot;@RESET&amp;quot;;&lt;br /&gt;
string  COMMAND_SHOW       = &amp;quot;@SHOW&amp;quot;;&lt;br /&gt;
string  COMMAND_ON         = &amp;quot;@ON&amp;quot;;&lt;br /&gt;
string  COMMAND_OFF        = &amp;quot;@OFF&amp;quot;;&lt;br /&gt;
string  COMMAND_HOME       = &amp;quot;@HOME&amp;quot;;&lt;br /&gt;
string  COMMAND_LOAD       = &amp;quot;@LOAD&amp;quot;;&lt;br /&gt;
string  COMMAND_ADDRESS    = &amp;quot;@ADDRESS&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Recording&lt;br /&gt;
&lt;br /&gt;
integer Recording = FALSE;&lt;br /&gt;
&lt;br /&gt;
list    ChatRecording=[];&lt;br /&gt;
integer NumLines=0;&lt;br /&gt;
integer Length=0;&lt;br /&gt;
&lt;br /&gt;
list     TimeList=[];&lt;br /&gt;
list     AddressList=[];&lt;br /&gt;
list     SubjectList=[];&lt;br /&gt;
list     BodyList=[];&lt;br /&gt;
integer  NumMessages=0;&lt;br /&gt;
integer  CurrentMessage=-1;&lt;br /&gt;
&lt;br /&gt;
float    MAIL_FETCH_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
// Link Messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP                        = 10000;&lt;br /&gt;
integer MSG_STATUS_ONLINE               = 30000;&lt;br /&gt;
integer MSG_STATUS_OFFLINE              = 30100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED          = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR           = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Unix Time conversion //////////////////&lt;br /&gt;
&lt;br /&gt;
integer DAYS_PER_YEAR        = 365;                // Non leap year&lt;br /&gt;
integer SECONDS_PER_YEAR     = 31536000;          // Non leap year&lt;br /&gt;
integer SECONDS_PER_DAY      = 86400;&lt;br /&gt;
integer SECONDS_PER_HOUR     = 3600;&lt;br /&gt;
integer SECONDS_PER_MINUTE   = 60;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// LeapYear() /////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer LeapYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (year % 4 == 0)&lt;br /&gt;
    {&lt;br /&gt;
        if (year % 100 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (year % 400 == 0)&lt;br /&gt;
            {&lt;br /&gt;
                return 1;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// DaysPerMonth() ///////////////////////////////////////&lt;br /&gt;
                &lt;br /&gt;
integer DaysPerMonth(integer year,integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;lt; 8)&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (month == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if (LeapYear(year))&lt;br /&gt;
                {&lt;br /&gt;
                    return 29;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    return 28;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 30;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 30;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////// DaysPerYear() ////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DaysPerYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (LeapYear(year))&lt;br /&gt;
        return DAYS_PER_YEAR + 1;&lt;br /&gt;
    else&lt;br /&gt;
        return DAYS_PER_YEAR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Unix2DataTime() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list Unix2DateTime(integer unixtime)&lt;br /&gt;
{&lt;br /&gt;
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;&lt;br /&gt;
    integer day = days_since_1_1_1970 + 1;&lt;br /&gt;
    integer year  = 1970;&lt;br /&gt;
    integer days_per_year = DaysPerYear(year);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_year)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_year;&lt;br /&gt;
        ++year;&lt;br /&gt;
        days_per_year = DaysPerYear(year);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer month = 1;&lt;br /&gt;
    integer days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_month)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_month;&lt;br /&gt;
        &lt;br /&gt;
        if (++month &amp;gt; 12)&lt;br /&gt;
        {    &lt;br /&gt;
            ++year;&lt;br /&gt;
            month = 1;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;&lt;br /&gt;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;&lt;br /&gt;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;&lt;br /&gt;
    integer minute      = second / SECONDS_PER_MINUTE;&lt;br /&gt;
    second               = second % SECONDS_PER_MINUTE;&lt;br /&gt;
    &lt;br /&gt;
    return [ year, month, day, hour, minute, second ];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// MonthName() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list MonthNameList = [     &amp;quot;JAN&amp;quot;, &amp;quot;FEB&amp;quot;, &amp;quot;MAR&amp;quot;, &amp;quot;APR&amp;quot;, &amp;quot;MAY&amp;quot;, &amp;quot;JUN&amp;quot;, &lt;br /&gt;
                        &amp;quot;JUL&amp;quot;, &amp;quot;AUG&amp;quot;, &amp;quot;SEP&amp;quot;, &amp;quot;OCT&amp;quot; , &amp;quot;NOV&amp;quot;, &amp;quot;DEC&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
string MonthName(integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;gt;= 0 &amp;amp;&amp;amp; month &amp;lt; 12)&lt;br /&gt;
        return llList2String(MonthNameList, month);&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// DateString() ///////////////////////////&lt;br /&gt;
&lt;br /&gt;
string DateString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer year       = llList2Integer(timelist,0);&lt;br /&gt;
    integer month      = llList2Integer(timelist,1);&lt;br /&gt;
    integer day        = llList2Integer(timelist,2);&lt;br /&gt;
    &lt;br /&gt;
    return (string)day + &amp;quot;-&amp;quot; + MonthName(month - 1) + &amp;quot;-&amp;quot; + (string)year;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// TimeString() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string TimeString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer hour          = llList2Integer(timelist,3);&lt;br /&gt;
    integer minute         = llList2Integer(timelist,4);&lt;br /&gt;
    integer second         = llList2Integer(timelist,5);&lt;br /&gt;
    string  hourstr     = (string)hour;&lt;br /&gt;
    string  minutestr   = (string)minute;&lt;br /&gt;
    string  secondstr   = (string)second;&lt;br /&gt;
    &lt;br /&gt;
    if (hour &amp;lt; 10)         hourstr     = &amp;quot;0&amp;quot; + hourstr;&lt;br /&gt;
    if (minute &amp;lt; 10)     minutestr     = &amp;quot;0&amp;quot; + minutestr;&lt;br /&gt;
    if (second &amp;lt; 10)    secondstr    = &amp;quot;0&amp;quot; + secondstr;&lt;br /&gt;
    return hourstr + &amp;quot;:&amp;quot; + minutestr + &amp;quot;:&amp;quot; + secondstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() /////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string body)&lt;br /&gt;
{&lt;br /&gt;
    // llOwnerSay(&amp;quot;Sending message to &#039;&amp;quot; + address + &amp;quot;&#039; with subject &#039;&amp;quot; + subject +&amp;quot;&#039;.&amp;quot;);&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND, body, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// SendHome() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendHome(string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SENDHOME, body, (key)subject);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Show() ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Show()&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;Current chat recording is:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; NumLines; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(ChatRecording,i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;Lines is &amp;quot; + (string)NumLines);&lt;br /&gt;
    llOwnerSay(&amp;quot;Message length is &amp;quot; + (string)Length);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Read() /////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Read()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;Reading message &amp;quot; + (string)CurrentMessage + &amp;quot; from mail buffer.&amp;quot;);&lt;br /&gt;
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);&lt;br /&gt;
    list timelist=Unix2DateTime(time);&lt;br /&gt;
    string Address = llList2String(AddressList,CurrentMessage);&lt;br /&gt;
    string Subject = llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
    string Body    = llList2String(BodyList,CurrentMessage);&lt;br /&gt;
    llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Address: &amp;quot; + Address);&lt;br /&gt;
    llOwnerSay(&amp;quot;Subject: &amp;quot; + Subject);&lt;br /&gt;
    llOwnerSay(&amp;quot;Begin of message body:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    list bodylist=llParseStringKeepNulls(Body, [ &amp;quot;\n&amp;quot; ], []);&lt;br /&gt;
    integer num=llGetListLength(bodylist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(bodylist,i));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;End of message body.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////// List ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
List()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;The mail buffer contains the following messages:\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; NumMessages; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer time=llList2Integer(TimeList,i);&lt;br /&gt;
        list timelist=Unix2DateTime(time);&lt;br /&gt;
        if (i &amp;gt; 0) llOwnerSay(&amp;quot;+-+-+-+-+-+-+-+-+-+-+-+-&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Message: &amp;quot; + (string)i);&lt;br /&gt;
        llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;From:    &amp;quot; + llList2String(AddressList,i));&lt;br /&gt;
        llOwnerSay(&amp;quot;Subject: &amp;quot; + llList2String(SubjectList,i));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////// NotifyNewMail() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
NotifyNewMail(string time, string address, string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    list timelist=Unix2DateTime((integer)time);&lt;br /&gt;
&lt;br /&gt;
    if (StatusOnline)&lt;br /&gt;
    {&lt;br /&gt;
        llInstantMessage(llGetOwner(), &amp;quot;You received a new mail message on &amp;quot; &lt;br /&gt;
                                    + DateString(timelist) + &amp;quot; at &amp;quot; + TimeString(timelist)&lt;br /&gt;
                                    + &amp;quot; from &amp;quot; + address &lt;br /&gt;
                                    + &amp;quot; with the subject &amp;quot; + subject);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        SendHome(&amp;quot;FW: &amp;quot; + subject, &amp;quot;Received at: &amp;quot; + DateString(timelist) + &amp;quot; &amp;quot; + TimeString(timelist) + &amp;quot;\nFrom: &amp;quot; +  address &lt;br /&gt;
                    + &amp;quot;\nBegin message body:\n-------------------\n&amp;quot; + body + &amp;quot;\n-------------------\nEnd message body.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ResetOtherScripts() //////////////////////&lt;br /&gt;
&lt;br /&gt;
ResetOtherScripts()&lt;br /&gt;
{&lt;br /&gt;
    string     name;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(ScriptList);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        name = llList2String(ScriptList,i);&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(name) == INVENTORY_SCRIPT)&lt;br /&gt;
        {&lt;br /&gt;
            llResetOtherScript(name);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Error - script &#039;&amp;quot; + name + &amp;quot;&#039; not found.&amp;quot;);&lt;br /&gt;
            ErrorFlag = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
// default &lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ////////////////////// state_entry() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Welcome to SL Mail, released under GNU software licence.&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Version &amp;quot; + SL_MAIL_VERSION + &amp;quot; &amp;quot; + SL_MAIL_DATE);&lt;br /&gt;
        llOwnerSay(&amp;quot;Produced by Logic Scripted Products &amp;amp; Product Services&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Free memory: &amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
        ResetOtherScripts();&lt;br /&gt;
        &lt;br /&gt;
        if (ErrorFlag)&lt;br /&gt;
            state Error;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// on_rez() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// changed() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_LOADED)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_ERROR)&lt;br /&gt;
        {&lt;br /&gt;
            state Error;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() //////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(MAIL_FETCH_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //////////////////////// on_rez() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// listen() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string trimmessage=llStringTrim(message,STRING_TRIM);&lt;br /&gt;
        list   parse = llParseStringKeepNulls(trimmessage, [ &amp;quot; &amp;quot;], []);&lt;br /&gt;
        string command = llToUpper(llList2String(parse,0));&lt;br /&gt;
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        integer nargs  = llGetListLength(parse);&lt;br /&gt;
        string argstr=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (nargs &amp;gt; 1) argstr=llGetSubString(message, llSubStringIndex(message, &amp;quot; &amp;quot;) + 1, -1);&lt;br /&gt;
            &lt;br /&gt;
        if (Recording)&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Recording stopped. Type @SHOW to see the message you have entered,&amp;quot;&lt;br /&gt;
                            + &amp;quot; or @SEND to send it.&amp;quot;);&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                &lt;br /&gt;
                SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];&lt;br /&gt;
                ++NumLines;&lt;br /&gt;
                Length += llStringLength(message) + 2;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_RECORD)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Start recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                ChatRecording = [];&lt;br /&gt;
                NumLines=0;&lt;br /&gt;
                Length=0;&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CONTINUE)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Continue recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_REPLY)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    string address=llList2String(AddressList,CurrentMessage);&lt;br /&gt;
                    string subject=&amp;quot;Re: &amp;quot; + llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, address, NULL_KEY);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, subject, NULL_KEY);&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines=0;&lt;br /&gt;
                    Length=0;&lt;br /&gt;
                    Recording = TRUE;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_MAIL)&lt;br /&gt;
            {&lt;br /&gt;
                string mailaddress=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailaddress != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, mailaddress, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETADDRESS, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SUBJECT)&lt;br /&gt;
            {&lt;br /&gt;
                string mailsubject=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailsubject != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, mailsubject, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETSUBJECT, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Not recording.&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    if (NumLines == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND_NOTECARD, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_IGNORE)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines = 0;&lt;br /&gt;
                    Length = 0;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Show();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_READ)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumMessages == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Read();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        ++CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        --CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_FIRST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = 0;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LAST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LIST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    List();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SELECT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;Need to supply a message number.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    integer msgnum = (integer)arg;&lt;br /&gt;
                     &lt;br /&gt;
                    if (msgnum &amp;lt; 0 || msgnum &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Message number &amp;quot; + arg + &amp;quot; not in mail buffer.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = msgnum;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_DELETE)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    --NumMessages;&lt;br /&gt;
                     &lt;br /&gt;
                    if (NumMessages == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = -1;&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (CurrentMessage &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CLEAR)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList=[];&lt;br /&gt;
                    AddressList=[];&lt;br /&gt;
                    SubjectList=[];&lt;br /&gt;
                    BodyList=[];&lt;br /&gt;
                    NumMessages=0;&lt;br /&gt;
                    CurrentMessage=-1;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_HELP, arg, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_INFO)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                Show();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_RESET)&lt;br /&gt;
            {&lt;br /&gt;
                llResetScript();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                state not_running;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HOME)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs==1)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETHOME, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETHOME, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// email() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    email(string time, string address, string subject, string body, integer queued)&lt;br /&gt;
    {&lt;br /&gt;
        NotifyNewMail(time, address, subject, body);&lt;br /&gt;
        TimeList = (TimeList=[]) + TimeList + [time];&lt;br /&gt;
        AddressList = (AddressList=[]) + AddressList + [address];&lt;br /&gt;
        SubjectList = (SubjectList=[]) + SubjectList + [subject];&lt;br /&gt;
        BodyList = (BodyList=[]) + BodyList + [body];&lt;br /&gt;
        ++NumMessages;&lt;br /&gt;
        &lt;br /&gt;
        if (CurrentMessage == -1)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = NumMessages - 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_REPLY)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state not_running&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state not_running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;SL Mailbox switched OFF. Say @ON to switch it back on.&amp;quot;);&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// on_rez() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// listen() ////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer chan, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string command=llToUpper(message);&lt;br /&gt;
        &lt;br /&gt;
        if (command == COMMAND_ON)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state Error&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state Error&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Error in SL Mail: not all component scripts found.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// End SL Mail V1.2.lsl&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Address Book V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Read and interpret the contents of the Address Book.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail AddressBook V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// &lt;br /&gt;
//  Read the Address Book from a notecard named &amp;quot;Address Book&amp;quot;.&lt;br /&gt;
//&lt;br /&gt;
//  The Address Book has the following format:&lt;br /&gt;
//  &lt;br /&gt;
//  [ADDRESS BOOK]&lt;br /&gt;
//  Name1=username@yourdomain.com&lt;br /&gt;
//  Name2=otheruser@otherdomain.com&lt;br /&gt;
//  ...&lt;br /&gt;
//  [GROUP]&lt;br /&gt;
//  group1=Name1, Name2&lt;br /&gt;
//  ...&lt;br /&gt;
//&lt;br /&gt;
//  Notes:&lt;br /&gt;
//  1. Group and Name share the same namespace, and must be unique.&lt;br /&gt;
//  2. It is allowed to have a name in the addressbook with multiple addresses, seperated by comma&#039;s.&lt;br /&gt;
// &lt;br /&gt;
/////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string  CurrentMailAddress = &amp;quot;&amp;quot;;&lt;br /&gt;
string  CurrentMailSubject = &amp;quot;&amp;quot;;&lt;br /&gt;
integer StatusOnline = FALSE;&lt;br /&gt;
&lt;br /&gt;
// Fetch or Send notecard&lt;br /&gt;
&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Names&lt;br /&gt;
&lt;br /&gt;
list    AddressBookList=[];&lt;br /&gt;
list    MailAddressList=[];&lt;br /&gt;
&lt;br /&gt;
string  STRING_HOME=&amp;quot;HOME&amp;quot;;&lt;br /&gt;
string  STRING_SELF=&amp;quot;SELF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Groups&lt;br /&gt;
&lt;br /&gt;
list   GroupList=[];&lt;br /&gt;
list   GroupNameList=[];&lt;br /&gt;
&lt;br /&gt;
string LSL_DOMAIN = &amp;quot;lsl.secondlife.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Read Address Book notecard&lt;br /&gt;
&lt;br /&gt;
string  ADDRESSBOOK_NOTECARD=&amp;quot;Address Book&amp;quot;;&lt;br /&gt;
integer Line=0;&lt;br /&gt;
key     reqAddressBook=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
integer Section=0;&lt;br /&gt;
integer SECTION_ADDRESS_BOOK=1;&lt;br /&gt;
integer SECTION_GROUP=2;&lt;br /&gt;
string  STRING_ADDRESS_BOOK=&amp;quot;ADDRESS BOOK&amp;quot;;&lt;br /&gt;
string  STRING_GROUP=&amp;quot;GROUP&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Links messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
integer MSG_MESSAGE_NOTIFY              = 90900;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED            = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR            = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// GetSelfAddress() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
string GetSelfAddress()&lt;br /&gt;
{&lt;br /&gt;
    return (string)llGetKey() + &amp;quot;@&amp;quot; + LSL_DOMAIN;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Info() /////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Info()&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;The mail address for this object is: &amp;quot; &lt;br /&gt;
                    + GetSelfAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// IsValidKeyFormat() //////////////////////&lt;br /&gt;
&lt;br /&gt;
integer IsValidKeyFormat(string str)&lt;br /&gt;
{&lt;br /&gt;
    string keychars = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    if (llStringLength(str) != 36)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    if( (llGetSubString( str, 8, 8 )   != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 13, 13 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 18, 18 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 23, 23 )  != &amp;quot;-&amp;quot; ) )&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 9; i &amp;lt; 13; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 14; i &amp;lt; 18; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 19; i &amp;lt; 23; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 24; i &amp;lt; 36; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// ValidMailAddress() ////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer ValidMailAddress(string arg)&lt;br /&gt;
{&lt;br /&gt;
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));&lt;br /&gt;
    &lt;br /&gt;
    if (adress == &amp;quot;&amp;quot;)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    list parse = llParseStringKeepNulls(adress, [ &amp;quot;@&amp;quot; ], []);&lt;br /&gt;
    string account = llList2String(parse,0);&lt;br /&gt;
    string domain  = llList2String(parse,1);&lt;br /&gt;
    &lt;br /&gt;
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    &lt;br /&gt;
    if (domain == LSL_DOMAIN)&lt;br /&gt;
    {&lt;br /&gt;
        return IsValidKeyFormat(account);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list parsedomain = llParseString2List(domain, [ &amp;quot;.&amp;quot; ], []);&lt;br /&gt;
    &lt;br /&gt;
        if (llGetListLength(parsedomain) &amp;lt; 2)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        &lt;br /&gt;
        integer num = llGetListLength(parsedomain);&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llStringLength(llList2String(parsedomain,i)) &amp;lt; 2)&lt;br /&gt;
            {&lt;br /&gt;
                return FALSE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetAddressStr() ///////////////////&lt;br /&gt;
&lt;br /&gt;
string GetAndCheckAddressStr(string address)&lt;br /&gt;
{&lt;br /&gt;
    list addresslist = llCSV2List(address);&lt;br /&gt;
    integer num=llGetListLength(addresslist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    string addressstr=&amp;quot;&amp;quot;;&lt;br /&gt;
    string curaddress=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        curaddress=llList2String(addresslist,i);&lt;br /&gt;
        &lt;br /&gt;
        if (ValidMailAddress(curaddress))&lt;br /&gt;
        {&lt;br /&gt;
            addressstr = (addressstr=&amp;quot;&amp;quot;) + addressstr + curaddress + &amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address string: &#039;&amp;quot; &lt;br /&gt;
                            + curaddress + &amp;quot;&#039;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return llGetSubString(addressstr, 0, -2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ProcessLine() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
ProcessLine(string rawline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(rawline,STRING_TRIM);&lt;br /&gt;
    string first=llGetSubString(line,0,0);&lt;br /&gt;
    string last=llGetSubString(line,-1,-1);&lt;br /&gt;
    &lt;br /&gt;
    // Ignore a blank line or comment line&lt;br /&gt;
    if (line == &amp;quot;&amp;quot; || first == &amp;quot;#&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // Check for the right section&lt;br /&gt;
    &lt;br /&gt;
    if (first == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; last == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        string sectionstr=llToUpper(llStringTrim(llGetSubString(line,1,-2),STRING_TRIM));&lt;br /&gt;
        &lt;br /&gt;
        if (sectionstr == STRING_ADDRESS_BOOK)&lt;br /&gt;
        {&lt;br /&gt;
            Section = SECTION_ADDRESS_BOOK;&lt;br /&gt;
        }&lt;br /&gt;
        else if (sectionstr == STRING_GROUP)&lt;br /&gt;
        {&lt;br /&gt;
            if (Section == 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                        + &amp;quot;. Group section defined before Address Book section.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Section = SECTION_GROUP;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid section header &#039;&amp;quot; + sectionstr &lt;br /&gt;
                        + &amp;quot;&#039; in &amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Must be in a section&lt;br /&gt;
    &lt;br /&gt;
    if (Section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;. No section header.&amp;quot;, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    list     parse=llParseString2List(line, [ &amp;quot;=&amp;quot; ], []);&lt;br /&gt;
    integer  num=llGetListLength(parse);&lt;br /&gt;
    &lt;br /&gt;
    // Format must be correct&lt;br /&gt;
    &lt;br /&gt;
    if (num != 2)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; +  (string)(Line+1) + &amp;quot;:\n&amp;quot; + rawline, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (Section == SECTION_ADDRESS_BOOK)&lt;br /&gt;
    {&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(name) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + name &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ name ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            string address=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
            string addressstr=GetAndCheckAddressStr(address);&lt;br /&gt;
            &lt;br /&gt;
            if (addressstr != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                AddressBookList     = (AddressBookList=[])     + AddressBookList     + [ name ];&lt;br /&gt;
                MailAddressList     = (MailAddressList=[])     + MailAddressList     + [ addressstr ];&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;No valid mail address for &#039;&amp;quot; + name &lt;br /&gt;
                    + &amp;quot;&#039;. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                    + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name &lt;br /&gt;
                + &amp;quot;&#039; already defined. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // Group&lt;br /&gt;
    {&lt;br /&gt;
        string group=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(group) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + group &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ group ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(GroupList, [ group ]) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                string names=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
                list   namelist=llCSV2List(names);&lt;br /&gt;
                integer num=llGetListLength(namelist);&lt;br /&gt;
                integer i;&lt;br /&gt;
                integer index;&lt;br /&gt;
                string  name;&lt;br /&gt;
                string  namestr=&amp;quot;&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
                for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                    name=llList2String(namelist,i);&lt;br /&gt;
                    index=llListFindList(AddressBookList, [ name ]);&lt;br /&gt;
            &lt;br /&gt;
                    if (index == -1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name + &amp;quot;&#039; defined in Group &#039;&amp;quot; &lt;br /&gt;
                                + group + &amp;quot;&#039; not found in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY); &lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        namestr = (namestr=&amp;quot;&amp;quot;) + namestr + name + &amp;quot;,&amp;quot;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (namestr != &amp;quot;&amp;quot;)&lt;br /&gt;
                {    &lt;br /&gt;
                    namestr=llGetSubString(namestr,0,-2);&lt;br /&gt;
                    GroupList         = (GroupList=[])         + GroupList     + [ group ];&lt;br /&gt;
                    GroupNameList     = (GroupNameList=[])    + GroupNameList + [ namestr ];&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                        + &amp;quot;&#039; has no valid names. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                        + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                    + &amp;quot;&#039; already defined in Group. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                    + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group&lt;br /&gt;
                + &amp;quot;&#039; already defined in Address Book. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// GetGroupAddressList ///////////////&lt;br /&gt;
&lt;br /&gt;
string GetGroupAddressList(string group)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(GroupList, [ group ]);&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(GroupList);&lt;br /&gt;
    string  grouplist=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        for (i = index; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2String(GroupList,i) == group)&lt;br /&gt;
            {&lt;br /&gt;
                grouplist = (grouplist=&amp;quot;&amp;quot;) + grouplist + llList2String(GroupNameList,i) + &amp;quot;,&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (grouplist != &amp;quot;&amp;quot;) grouplist=llGetSubString(grouplist,0,-2);   // remove last &amp;quot;,&amp;quot;&lt;br /&gt;
        return grouplist;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// SetMailAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetMailAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ address ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        index=llListFindList(GroupList, [ address ]);&lt;br /&gt;
        &lt;br /&gt;
        if (index == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llToUpper(address) == STRING_SELF)&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = GetSelfAddress();&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if(ValidMailAddress(address))&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = address;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Mail adress &amp;quot; + address &lt;br /&gt;
                            + &amp;quot; : not found in adress book or invalid format.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailAddress = GetGroupAddressList(address);&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        CurrentMailAddress = llList2String(MailAddressList,index);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                        + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string message)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No mail address defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No subject defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list mailaddresslist=llCSV2List(CurrentMailAddress);&lt;br /&gt;
        integer num=llGetListLength(mailaddresslist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(mailaddresslist,i);&lt;br /&gt;
            llEmail(address, CurrentMailSubject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMailHome() ////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMailHome(string message, string subject)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, STRING_HOME &lt;br /&gt;
                + &amp;quot; not set. Set your home adress with @HOME &amp;lt;address&amp;gt;.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        string homeaddress=llList2String(AddressBookList,index);&lt;br /&gt;
        list   homelist=llCSV2List(homeaddress);&lt;br /&gt;
        integer num=llGetListLength(homelist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(homelist,i);&lt;br /&gt;
            llEmail(address, subject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
string GetHomeAddress()&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;not set&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2String(MailAddressList,index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetHomeAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        AddressBookList     = (AddressBookList=[]) + [ STRING_HOME ] + AddressBookList;&lt;br /&gt;
        MailAddressList     = (MailAddressList=[]) + [ GetAndCheckAddressStr(address) ]  + MailAddressList;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MailAddressList = llListReplaceList(MailAddressList, [ GetAndCheckAddressStr(address) ], index, index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        Line=0;&lt;br /&gt;
        Section=0;&lt;br /&gt;
        llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// dataserver() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqAddressBook)&lt;br /&gt;
        {&lt;br /&gt;
            reqAddressBook = NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                ProcessLine(data);&lt;br /&gt;
                reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Address Book loaded.&amp;quot;, NULL_KEY);&lt;br /&gt;
                state running;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// timer() ///////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_ERROR, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Could not read Address Book: &amp;quot; &lt;br /&gt;
                            + ADDRESSBOOK_NOTECARD + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// link_message() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_MESSAGE_GETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is empty.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailSubject = message;&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is empty.&amp;quot;, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            SetMailAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Body of message to send is empty. &amp;quot; &lt;br /&gt;
                                +  &amp;quot;No mail is send.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SENDHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SendMailHome(message, (string)id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetInventoryType(message) == INVENTORY_NOTECARD)&lt;br /&gt;
            {&lt;br /&gt;
                Notecard2Fetch = message;                &lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_READ, message, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + message + &amp;quot; not found.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_NOTECARD_FETCHED)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + Notecard2Fetch &lt;br /&gt;
                            + &amp;quot; was empty or could not be read.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Home address is: &amp;quot; + GetHomeAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SetHomeAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_INFO)&lt;br /&gt;
        {&lt;br /&gt;
            Info();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
// End SL Mail AddressBook V1.2.lsl&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail FetchNotecard V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch the contents of a notecard and return it via link message as a string.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Notecard&lt;br /&gt;
&lt;br /&gt;
integer Line=0;&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
key     reqNotecard=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=10.0;&lt;br /&gt;
integer Fetched=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Lines&lt;br /&gt;
&lt;br /&gt;
list LineList=[];&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    /////////////////////// dataserver() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqNotecard)&lt;br /&gt;
        {&lt;br /&gt;
            reqNotecard=NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                LineList = (LineList=[]) + LineList + [ data ];&lt;br /&gt;
                reqNotecard = llGetNotecardLine(Notecard2Fetch, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Fetched=TRUE;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, llDumpList2String(LineList, &amp;quot;\n&amp;quot;), NULL_KEY);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /////////////////////// timer() ///////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        if (!Fetched)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            llSetTimerEvent(0.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer send, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_NOTECARD_READ)&lt;br /&gt;
        {&lt;br /&gt;
            Line=0;&lt;br /&gt;
            Notecard2Fetch=message;&lt;br /&gt;
            LineList=[];&lt;br /&gt;
            Fetched=FALSE;&lt;br /&gt;
            reqNotecard=llGetNotecardLine(Notecard2Fetch, Line);&lt;br /&gt;
            llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL OnlineStatus V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch online status of owner.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Online status&lt;br /&gt;
&lt;br /&gt;
key     reqOnlineStatus=NULL_KEY;&lt;br /&gt;
float   STATUS_INTERVAL=2.0;&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_STATUS_ONLINE       = 30000;&lt;br /&gt;
integer MS_STATUS_OFFLINE       = 30100;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus=llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
        llSetTimerEvent(STATUS_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// dataserver() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqOnlineStatus)&lt;br /&gt;
        {&lt;br /&gt;
            reqOnlineStatus = NULL_KEY;&lt;br /&gt;
        &lt;br /&gt;
            if (data==&amp;quot;1&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_STATUS_ONLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if (data==&amp;quot;0&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MS_STATUS_OFFLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus = llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Help V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Display help information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail Help V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP    = 10000;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Help() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Help()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;HELP for SL Mail V1.2.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;COMMANDS:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HELP               - displays help info.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@INFO               - display mailaddress of this object.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RECORD             - start recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CONTINUE           - continue recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@STOP               - stop recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@IGNORE             - ignore the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SHOW               - show what your recorded.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SEND               - send the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@MAIL &amp;lt;mailadress&amp;gt;  - set the mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SUBJECT subject    - set the mail subject.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LIST               - list messages in mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SELECT &amp;lt;message&amp;gt;   - select message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@READ               - read current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@NEXT               - read next message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@PREV               - read previous message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@FIRST              - read first message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LAST               - read last message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@DELETE             - delete current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CLEAR              - clear the mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@REPLY              - reply to current message.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RESET              - reset the script.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HOME               - set the home mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@OFF                - switch mailbox OFF.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@ON                 - switch mailbox ON.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_HELP)&lt;br /&gt;
        {&lt;br /&gt;
            Help();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail Help V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}&lt;/div&gt;</description>
			<pubDate>Wed, 09 Feb 2011 23:20:46 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:SL_Mail_V1.2</comments>
		</item>
		<item>
			<title>SL Mail V1.2</title>
			<link>https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=1133910</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=1133910</guid>
			<description>&lt;p&gt;Flennan Roffo: /* IMPORTANT NOTICE */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}} __NOTOC__&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=&#039;&#039;&#039;Second Life mail client&#039;&#039;&#039;=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Send and receive email from within Second Life from and to any address.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implemented with Address Book function (in a notecard named &#039;Address Book&#039;) to stores addresses by name  and to compile groups of named addresses. Current version is stand-alone (no server functionality) and uses chat commands only.&lt;br /&gt;
&lt;br /&gt;
[[Image:BannerSLMail.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.slmail.info slmail.info] &amp;lt;strike&amp;gt;(website coming soon!)&amp;lt;/strike&amp;gt; &amp;lt;b&amp;gt;url slmail.info no longer used for SL Mail, and was taken for some other purpose.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Release Notes V1.2=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 Release notes (edition 2, 4 sept 2007)&lt;br /&gt;
&lt;br /&gt;
===IMPORTANT NOTICE===&lt;br /&gt;
&lt;br /&gt;
Development of SL Mail was abandoned midyear 2008. The domain slmail.info was abandoned and is now taken by another domain holder (ISS) who has nothing to do with SL Mail.&lt;br /&gt;
&lt;br /&gt;
SL Mail is considered for redevelopment under the same terms, using a version of the &#039;&#039;Serverless Key Exchange&#039;&#039; script. This allows mail clients to exchange their key adresses to other rezzed mail clients in world, and send each other info about the public name they use, and other info that could be usefull. This protocol does not use a central server.&lt;br /&gt;
&lt;br /&gt;
See: [https://wiki.secondlife.com/wiki/Serverless_Key_Exchange Serverless Key Exchange]&lt;br /&gt;
&lt;br /&gt;
Future annoucements about SL Mail development will be made here.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;LICENCE INFO&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
This program is free software: you can redistribute it and/or modify&lt;br /&gt;
it under the terms of the GNU General Public License as published by&lt;br /&gt;
the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
(at your option) any later version.&lt;br /&gt;
&lt;br /&gt;
This program is distributed in the hope that it will be useful,&lt;br /&gt;
but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
GNU General Public License for more details.&lt;br /&gt;
&lt;br /&gt;
You should have received a copy of the GNU General Public License&lt;br /&gt;
along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;PRODUCTION &amp;amp; MAINTANENCE&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
by Logic Scripted Products and Script Services&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.logicscripts.org logicscripts.org] (website coming soon!)&lt;br /&gt;
&lt;br /&gt;
SLurl:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Contact: [[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
&lt;br /&gt;
Email: [mailto:info@slmail.info &#039;&#039;&#039;info&#039;&#039;&#039;] or [mailto:Flennan.Roffo@slmail.info &#039;&#039;&#039;Flennan Roffo&#039;&#039;&#039;]&lt;br /&gt;
&#039;&#039;&#039;* The slmail.info URL appears to not be registered and this information appears to be out of date. *&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;DESCRIPTION&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is a simple tool to send and receive mail from within SL.&lt;br /&gt;
You can either compose a message yourself using chat recording, or choose a notecard from inventory to send. The Address Book functionality allows you to use short names for mail recipients stored in a notecard. The current version does not have a persisent mail address. Watch out for the upcoming next release (V1.3) which will facilitate persisent in-world mail addresses and will be enhanced with many new features (See: Requests For Change (RFC).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;COMMANDS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Help&#039;&#039;&#039;&lt;br /&gt;
||Show Help about available commands&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Record&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording (for owner only).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Stop&#039;&#039;&#039;&lt;br /&gt;
||Stops the chat recording without sending&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Continue&#039;&#039;&#039;&lt;br /&gt;
||Continues a previously stopped chat recording. Lines will be appended to you recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Show&#039;&#039;&#039;&lt;br /&gt;
||Shows the content of the recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send&#039;&#039;&#039;&lt;br /&gt;
||If recording, stops the recording, and sends the mail (need to supply mail address and subject first!)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send &amp;lt;notecard&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Sends the content of the notecard, instead of the chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Ignore&#039;&#039;&#039;&lt;br /&gt;
||Ignores your current chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject &amp;lt;subject&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the subject of the mail.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail subject.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Set the HOME address of the owner (mail will be forwarder to this address when offline).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home&#039;&#039;&#039;&lt;br /&gt;
||Show the HOME address.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Info&#039;&#039;&#039;&lt;br /&gt;
||Shows the mail address the object this script is running in uses (e.g. &amp;lt;object-key&amp;gt;@lsl.secondlife.com).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Read&#039;&#039;&#039;&lt;br /&gt;
||Reads the current message from the mail buffer (the mail buffer gets filled with mail you receive)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Select &amp;lt;msg&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Select a message number from the availabe messages in the mail buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Next&#039;&#039;&#039;&lt;br /&gt;
||Make next message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Prev&#039;&#039;&#039;&lt;br /&gt;
||Make previous message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@First&#039;&#039;&#039;&lt;br /&gt;
||Make the first message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Last&#039;&#039;&#039;&lt;br /&gt;
||Make the last message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Clear&#039;&#039;&#039;&lt;br /&gt;
||Clear the mail buffer&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Delete&#039;&#039;&#039;&lt;br /&gt;
||Deletes only the current message&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Reply&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording to reply to the current message. Mail adress and subject are filled in automatically.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* Commands are case insensitive (&amp;quot;@read&amp;quot; == &amp;quot;@READ&amp;quot;). Arguments might not be case insensitive.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;ADDRESS BOOK FORMAT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
A notecard of the name &#039;Address Book&#039; is read during initialization which may contain Address Book items and Groups.&lt;br /&gt;
The notecard is split in two sections, which need to be defined in that particular order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[ADDRESS BOOK]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Defines the section in which you can put names for mail addresses,  like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name1=account@thisdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name2=user@otherdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[GROUP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define groups of previously defined names under a new name, like for instance:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyGroup=Name1, Name2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note that names of groups and individual mail adresses share the same namespace and must be unique.&lt;br /&gt;
&lt;br /&gt;
So when you filled in your mail adresses in the Address Book, you can now use:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail Name1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to  &amp;lt;account@thisdomain.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail MyGroup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to &amp;lt;account@thisdomain.com&amp;gt; and &amp;lt;user@otherdomain.com&amp;gt;&lt;br /&gt;
Mails will be sent one after another.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* Names for Addreses and Groups are case insensitive (e.g. &amp;quot;mary&amp;quot;  == &amp;quot;MARY&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* The special address &#039;Self&#039; can be used in commands where otherwise an address specification can be used. &#039;Self&#039; is case insensitive (e.g. &amp;quot;self&amp;quot; == &amp;quot;SELF&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LIMITATIONS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
The current version is limited by the following:&lt;br /&gt;
&lt;br /&gt;
* Chat recording lines are limited by the 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Output of lines from the mail buffer are also limited by this 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Incoming mail is limited to a 1000 (1024?) byte limit&lt;br /&gt;
&lt;br /&gt;
* Outgoing mai is limited by a 4096 byte limit, which includes the standard mail header (region/location info on the first two lines)&lt;br /&gt;
&lt;br /&gt;
We are making adjustments to this release to help overcome these limitations. At least the line lenght limit can be overcome by introducing a line continuation character (for example a hyphen &#039;-&#039;) that when used at the end of a line appends the next line, so lines longer then 255 bytes are possible then.&lt;br /&gt;
&lt;br /&gt;
To overcome the outgoing mail length limit, the mail can be broken textualy into parts, and each part can be send seperatedely, with an indication in the subject or in an introduced primary line of the mail body to indicate that the mail was split into parts.&lt;br /&gt;
For incoming mail and at least to receive mail from other SL Mail programs, a protocol will be introduced to receive mail in parts that are joined together after receiving them to form a single mail.&lt;br /&gt;
&lt;br /&gt;
These enhancements will be made available in the next release (V1.3) of SL Mail &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;BUGS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Report any bugs you find in this release to Logic (IM: Flennan Roffo).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;REQUEST FOR CHANGE (RFC)&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Do you have additional wishes for enhancement of this product?&lt;br /&gt;
Contact Flennan Roffo and we will see if they can be implemented in the next release.&lt;br /&gt;
&lt;br /&gt;
Existing RFC&#039;s are:&lt;br /&gt;
&lt;br /&gt;
* Menu support for commands.&lt;br /&gt;
&lt;br /&gt;
* Lines on incoming/outgoing mail longer than 255 bytes.&lt;br /&gt;
&lt;br /&gt;
* Send messages longer than 4096 (minus SL mail header) bytes.&lt;br /&gt;
&lt;br /&gt;
* Receive messages longer than 1024 bytes.&lt;br /&gt;
&lt;br /&gt;
* Permanent mail addresses for the SL Mail client (like: &amp;lt;Flennan.Roffo@somedomain.sl&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Add your RFC!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In-world join the group &amp;quot;SL Mail&amp;quot; for bug reports, feature requests, the latest SL Mail release, and notices about development issues.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scripts=&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==Script: SL Mail v1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail core module which scans for incoming mail messages and executes commands used by the owner.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail V1.2.lsl&lt;br /&gt;
// (c) 2007 Logic Scripted Products and Script Services&lt;br /&gt;
// Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
// VERSION&lt;br /&gt;
// Version: 1.2&lt;br /&gt;
&lt;br /&gt;
// HISTORY&lt;br /&gt;
// Date         Version     Author              Comment&lt;br /&gt;
// --------------------------------------------------------------------------------------&lt;br /&gt;
// 28 aug 2007  V 1.0       Flennan Roffo       Created&lt;br /&gt;
//&lt;br /&gt;
//  1 sep 2007  V 1.1       Flennan Roffo       @Reply empties the recording buffer.&lt;br /&gt;
//                                                @Send while recording ends recording&lt;br /&gt;
//                                                and sends the mail if a mail address&lt;br /&gt;
//                                                and subject are supplied.&lt;br /&gt;
//                                                Fixed incorrect date in Unix2DateTime.&lt;br /&gt;
//  3 sep 2007  V 1.2       Flennan Roffo       Notification options:&lt;br /&gt;
//                                              - When online, send an IM when mail is received.&lt;br /&gt;
//                                              - When offline, send to HOME mail adress.&lt;br /&gt;
//                                              Adressbook&lt;br /&gt;
//                                              - Read adress book from config notecard.&lt;br /&gt;
&lt;br /&gt;
// LICENCE&lt;br /&gt;
// This program is free software; you can redistribute it and/or&lt;br /&gt;
// modify it under the terms of the GNU General Public License&lt;br /&gt;
// as published by the Free Software Foundation; either version 2&lt;br /&gt;
// of the License, or (at your option) any later version.&lt;br /&gt;
// &lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
// &lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program; if not, write to the Free Software&lt;br /&gt;
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
// (Also available at http://www.gnu.org/copyleft/gpl.html) &lt;br /&gt;
&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// Let&#039;s you record a message and sent to email and get messages and reply to messages.&lt;br /&gt;
// Must supply a valid mail adress and non-empty subject using chat commands.&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
// 1) Check for the maximum length of an email message (including newline and header).&lt;br /&gt;
// 2) Read adress book from notecard.                                    *DONE*&lt;br /&gt;
// 3) Send incoming mail to personal mail adress when offline.            *DONE*&lt;br /&gt;
// 4) Alert with an IM when online upon receiving new mail.                *DONE*&lt;br /&gt;
&lt;br /&gt;
string   SL_MAIL_VERSION = &amp;quot;V 1.2&amp;quot;;&lt;br /&gt;
string   SL_MAIL_DATE    = &amp;quot; 2 sep 2007&amp;quot;;&lt;br /&gt;
integer  ErrorFlag         = FALSE;&lt;br /&gt;
list     ScriptList        = [ &amp;quot;SL Mail Help V1.2&amp;quot;, &amp;quot;SL Mail AddressBook V1.2&amp;quot;, &lt;br /&gt;
                                &amp;quot;SL Mail OnlineStatus V1.2&amp;quot;, &amp;quot;SL Mail FetchNotecard V1.2&amp;quot; ];    &lt;br /&gt;
string   LSL_DOMAIN=&amp;quot;lsl.secondlife.com&amp;quot;; &lt;br /&gt;
integer  StatusOnline=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Commands&lt;br /&gt;
&lt;br /&gt;
string  COMMAND_RECORD     = &amp;quot;@RECORD&amp;quot;;&lt;br /&gt;
string  COMMAND_CONTINUE   = &amp;quot;@CONTINUE&amp;quot;;&lt;br /&gt;
string  COMMAND_STOP       = &amp;quot;@STOP&amp;quot;;&lt;br /&gt;
string  COMMAND_MAIL       = &amp;quot;@MAIL&amp;quot;;&lt;br /&gt;
string  COMMAND_SUBJECT    = &amp;quot;@SUBJECT&amp;quot;;&lt;br /&gt;
string  COMMAND_SEND       = &amp;quot;@SEND&amp;quot;;&lt;br /&gt;
string  COMMAND_SEE        = &amp;quot;@SEE&amp;quot;;&lt;br /&gt;
string  COMMAND_IGNORE     = &amp;quot;@IGNORE&amp;quot;;&lt;br /&gt;
string  COMMAND_READ       = &amp;quot;@READ&amp;quot;;&lt;br /&gt;
string  COMMAND_DELETE     = &amp;quot;@DELETE&amp;quot;;&lt;br /&gt;
string  COMMAND_CLEAR      = &amp;quot;@CLEAR&amp;quot;;&lt;br /&gt;
string  COMMAND_REPLY      = &amp;quot;@REPLY&amp;quot;;&lt;br /&gt;
string  COMMAND_NEXT       = &amp;quot;@NEXT&amp;quot;;&lt;br /&gt;
string  COMMAND_PREV       = &amp;quot;@PREV&amp;quot;;&lt;br /&gt;
string  COMMAND_FIRST      = &amp;quot;@FIRST&amp;quot;;&lt;br /&gt;
string  COMMAND_LAST       = &amp;quot;@LAST&amp;quot;;&lt;br /&gt;
string  COMMAND_LIST       = &amp;quot;@LIST&amp;quot;;&lt;br /&gt;
string  COMMAND_SELECT     = &amp;quot;@SELECT&amp;quot;;&lt;br /&gt;
string  COMMAND_HELP       = &amp;quot;@HELP&amp;quot;;&lt;br /&gt;
string  COMMAND_INFO       = &amp;quot;@INFO&amp;quot;;&lt;br /&gt;
string  COMMAND_RESET      = &amp;quot;@RESET&amp;quot;;&lt;br /&gt;
string  COMMAND_SHOW       = &amp;quot;@SHOW&amp;quot;;&lt;br /&gt;
string  COMMAND_ON         = &amp;quot;@ON&amp;quot;;&lt;br /&gt;
string  COMMAND_OFF        = &amp;quot;@OFF&amp;quot;;&lt;br /&gt;
string  COMMAND_HOME       = &amp;quot;@HOME&amp;quot;;&lt;br /&gt;
string  COMMAND_LOAD       = &amp;quot;@LOAD&amp;quot;;&lt;br /&gt;
string  COMMAND_ADDRESS    = &amp;quot;@ADDRESS&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Recording&lt;br /&gt;
&lt;br /&gt;
integer Recording = FALSE;&lt;br /&gt;
&lt;br /&gt;
list    ChatRecording=[];&lt;br /&gt;
integer NumLines=0;&lt;br /&gt;
integer Length=0;&lt;br /&gt;
&lt;br /&gt;
list     TimeList=[];&lt;br /&gt;
list     AddressList=[];&lt;br /&gt;
list     SubjectList=[];&lt;br /&gt;
list     BodyList=[];&lt;br /&gt;
integer  NumMessages=0;&lt;br /&gt;
integer  CurrentMessage=-1;&lt;br /&gt;
&lt;br /&gt;
float    MAIL_FETCH_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
// Link Messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP                        = 10000;&lt;br /&gt;
integer MSG_STATUS_ONLINE               = 30000;&lt;br /&gt;
integer MSG_STATUS_OFFLINE              = 30100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED          = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR           = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Unix Time conversion //////////////////&lt;br /&gt;
&lt;br /&gt;
integer DAYS_PER_YEAR        = 365;                // Non leap year&lt;br /&gt;
integer SECONDS_PER_YEAR     = 31536000;          // Non leap year&lt;br /&gt;
integer SECONDS_PER_DAY      = 86400;&lt;br /&gt;
integer SECONDS_PER_HOUR     = 3600;&lt;br /&gt;
integer SECONDS_PER_MINUTE   = 60;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// LeapYear() /////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer LeapYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (year % 4 == 0)&lt;br /&gt;
    {&lt;br /&gt;
        if (year % 100 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (year % 400 == 0)&lt;br /&gt;
            {&lt;br /&gt;
                return 1;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// DaysPerMonth() ///////////////////////////////////////&lt;br /&gt;
                &lt;br /&gt;
integer DaysPerMonth(integer year,integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;lt; 8)&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (month == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if (LeapYear(year))&lt;br /&gt;
                {&lt;br /&gt;
                    return 29;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    return 28;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 30;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 30;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////// DaysPerYear() ////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DaysPerYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (LeapYear(year))&lt;br /&gt;
        return DAYS_PER_YEAR + 1;&lt;br /&gt;
    else&lt;br /&gt;
        return DAYS_PER_YEAR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Unix2DataTime() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list Unix2DateTime(integer unixtime)&lt;br /&gt;
{&lt;br /&gt;
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;&lt;br /&gt;
    integer day = days_since_1_1_1970 + 1;&lt;br /&gt;
    integer year  = 1970;&lt;br /&gt;
    integer days_per_year = DaysPerYear(year);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_year)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_year;&lt;br /&gt;
        ++year;&lt;br /&gt;
        days_per_year = DaysPerYear(year);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer month = 1;&lt;br /&gt;
    integer days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_month)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_month;&lt;br /&gt;
        &lt;br /&gt;
        if (++month &amp;gt; 12)&lt;br /&gt;
        {    &lt;br /&gt;
            ++year;&lt;br /&gt;
            month = 1;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;&lt;br /&gt;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;&lt;br /&gt;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;&lt;br /&gt;
    integer minute      = second / SECONDS_PER_MINUTE;&lt;br /&gt;
    second               = second % SECONDS_PER_MINUTE;&lt;br /&gt;
    &lt;br /&gt;
    return [ year, month, day, hour, minute, second ];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// MonthName() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list MonthNameList = [     &amp;quot;JAN&amp;quot;, &amp;quot;FEB&amp;quot;, &amp;quot;MAR&amp;quot;, &amp;quot;APR&amp;quot;, &amp;quot;MAY&amp;quot;, &amp;quot;JUN&amp;quot;, &lt;br /&gt;
                        &amp;quot;JUL&amp;quot;, &amp;quot;AUG&amp;quot;, &amp;quot;SEP&amp;quot;, &amp;quot;OCT&amp;quot; , &amp;quot;NOV&amp;quot;, &amp;quot;DEC&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
string MonthName(integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;gt;= 0 &amp;amp;&amp;amp; month &amp;lt; 12)&lt;br /&gt;
        return llList2String(MonthNameList, month);&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// DateString() ///////////////////////////&lt;br /&gt;
&lt;br /&gt;
string DateString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer year       = llList2Integer(timelist,0);&lt;br /&gt;
    integer month      = llList2Integer(timelist,1);&lt;br /&gt;
    integer day        = llList2Integer(timelist,2);&lt;br /&gt;
    &lt;br /&gt;
    return (string)day + &amp;quot;-&amp;quot; + MonthName(month - 1) + &amp;quot;-&amp;quot; + (string)year;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// TimeString() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string TimeString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer hour          = llList2Integer(timelist,3);&lt;br /&gt;
    integer minute         = llList2Integer(timelist,4);&lt;br /&gt;
    integer second         = llList2Integer(timelist,5);&lt;br /&gt;
    string  hourstr     = (string)hour;&lt;br /&gt;
    string  minutestr   = (string)minute;&lt;br /&gt;
    string  secondstr   = (string)second;&lt;br /&gt;
    &lt;br /&gt;
    if (hour &amp;lt; 10)         hourstr     = &amp;quot;0&amp;quot; + hourstr;&lt;br /&gt;
    if (minute &amp;lt; 10)     minutestr     = &amp;quot;0&amp;quot; + minutestr;&lt;br /&gt;
    if (second &amp;lt; 10)    secondstr    = &amp;quot;0&amp;quot; + secondstr;&lt;br /&gt;
    return hourstr + &amp;quot;:&amp;quot; + minutestr + &amp;quot;:&amp;quot; + secondstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() /////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string body)&lt;br /&gt;
{&lt;br /&gt;
    // llOwnerSay(&amp;quot;Sending message to &#039;&amp;quot; + address + &amp;quot;&#039; with subject &#039;&amp;quot; + subject +&amp;quot;&#039;.&amp;quot;);&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND, body, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// SendHome() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendHome(string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SENDHOME, body, (key)subject);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Show() ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Show()&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;Current chat recording is:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; NumLines; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(ChatRecording,i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;Lines is &amp;quot; + (string)NumLines);&lt;br /&gt;
    llOwnerSay(&amp;quot;Message length is &amp;quot; + (string)Length);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Read() /////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Read()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;Reading message &amp;quot; + (string)CurrentMessage + &amp;quot; from mail buffer.&amp;quot;);&lt;br /&gt;
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);&lt;br /&gt;
    list timelist=Unix2DateTime(time);&lt;br /&gt;
    string Address = llList2String(AddressList,CurrentMessage);&lt;br /&gt;
    string Subject = llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
    string Body    = llList2String(BodyList,CurrentMessage);&lt;br /&gt;
    llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Address: &amp;quot; + Address);&lt;br /&gt;
    llOwnerSay(&amp;quot;Subject: &amp;quot; + Subject);&lt;br /&gt;
    llOwnerSay(&amp;quot;Begin of message body:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    list bodylist=llParseStringKeepNulls(Body, [ &amp;quot;\n&amp;quot; ], []);&lt;br /&gt;
    integer num=llGetListLength(bodylist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(bodylist,i));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;End of message body.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////// List ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
List()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;The mail buffer contains the following messages:\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; NumMessages; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer time=llList2Integer(TimeList,i);&lt;br /&gt;
        list timelist=Unix2DateTime(time);&lt;br /&gt;
        if (i &amp;gt; 0) llOwnerSay(&amp;quot;+-+-+-+-+-+-+-+-+-+-+-+-&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Message: &amp;quot; + (string)i);&lt;br /&gt;
        llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;From:    &amp;quot; + llList2String(AddressList,i));&lt;br /&gt;
        llOwnerSay(&amp;quot;Subject: &amp;quot; + llList2String(SubjectList,i));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////// NotifyNewMail() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
NotifyNewMail(string time, string address, string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    list timelist=Unix2DateTime((integer)time);&lt;br /&gt;
&lt;br /&gt;
    if (StatusOnline)&lt;br /&gt;
    {&lt;br /&gt;
        llInstantMessage(llGetOwner(), &amp;quot;You received a new mail message on &amp;quot; &lt;br /&gt;
                                    + DateString(timelist) + &amp;quot; at &amp;quot; + TimeString(timelist)&lt;br /&gt;
                                    + &amp;quot; from &amp;quot; + address &lt;br /&gt;
                                    + &amp;quot; with the subject &amp;quot; + subject);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        SendHome(&amp;quot;FW: &amp;quot; + subject, &amp;quot;Received at: &amp;quot; + DateString(timelist) + &amp;quot; &amp;quot; + TimeString(timelist) + &amp;quot;\nFrom: &amp;quot; +  address &lt;br /&gt;
                    + &amp;quot;\nBegin message body:\n-------------------\n&amp;quot; + body + &amp;quot;\n-------------------\nEnd message body.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ResetOtherScripts() //////////////////////&lt;br /&gt;
&lt;br /&gt;
ResetOtherScripts()&lt;br /&gt;
{&lt;br /&gt;
    string     name;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(ScriptList);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        name = llList2String(ScriptList,i);&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(name) == INVENTORY_SCRIPT)&lt;br /&gt;
        {&lt;br /&gt;
            llResetOtherScript(name);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Error - script &#039;&amp;quot; + name + &amp;quot;&#039; not found.&amp;quot;);&lt;br /&gt;
            ErrorFlag = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
// default &lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ////////////////////// state_entry() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Welcome to SL Mail, released under GNU software licence.&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Version &amp;quot; + SL_MAIL_VERSION + &amp;quot; &amp;quot; + SL_MAIL_DATE);&lt;br /&gt;
        llOwnerSay(&amp;quot;Produced by Logic Scripted Products &amp;amp; Product Services&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Free memory: &amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
        ResetOtherScripts();&lt;br /&gt;
        &lt;br /&gt;
        if (ErrorFlag)&lt;br /&gt;
            state Error;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// on_rez() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// changed() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_LOADED)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_ERROR)&lt;br /&gt;
        {&lt;br /&gt;
            state Error;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() //////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(MAIL_FETCH_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //////////////////////// on_rez() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// listen() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string trimmessage=llStringTrim(message,STRING_TRIM);&lt;br /&gt;
        list   parse = llParseStringKeepNulls(trimmessage, [ &amp;quot; &amp;quot;], []);&lt;br /&gt;
        string command = llToUpper(llList2String(parse,0));&lt;br /&gt;
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        integer nargs  = llGetListLength(parse);&lt;br /&gt;
        string argstr=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (nargs &amp;gt; 1) argstr=llGetSubString(message, llSubStringIndex(message, &amp;quot; &amp;quot;) + 1, -1);&lt;br /&gt;
            &lt;br /&gt;
        if (Recording)&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Recording stopped. Type @SHOW to see the message you have entered,&amp;quot;&lt;br /&gt;
                            + &amp;quot; or @SEND to send it.&amp;quot;);&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                &lt;br /&gt;
                SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];&lt;br /&gt;
                ++NumLines;&lt;br /&gt;
                Length += llStringLength(message) + 2;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_RECORD)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Start recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                ChatRecording = [];&lt;br /&gt;
                NumLines=0;&lt;br /&gt;
                Length=0;&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CONTINUE)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Continue recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_REPLY)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    string address=llList2String(AddressList,CurrentMessage);&lt;br /&gt;
                    string subject=&amp;quot;Re: &amp;quot; + llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, address, NULL_KEY);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, subject, NULL_KEY);&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines=0;&lt;br /&gt;
                    Length=0;&lt;br /&gt;
                    Recording = TRUE;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_MAIL)&lt;br /&gt;
            {&lt;br /&gt;
                string mailaddress=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailaddress != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, mailaddress, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETADDRESS, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SUBJECT)&lt;br /&gt;
            {&lt;br /&gt;
                string mailsubject=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailsubject != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, mailsubject, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETSUBJECT, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Not recording.&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    if (NumLines == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND_NOTECARD, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_IGNORE)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines = 0;&lt;br /&gt;
                    Length = 0;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Show();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_READ)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumMessages == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Read();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        ++CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        --CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_FIRST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = 0;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LAST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LIST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    List();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SELECT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;Need to supply a message number.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    integer msgnum = (integer)arg;&lt;br /&gt;
                     &lt;br /&gt;
                    if (msgnum &amp;lt; 0 || msgnum &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Message number &amp;quot; + arg + &amp;quot; not in mail buffer.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = msgnum;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_DELETE)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    --NumMessages;&lt;br /&gt;
                     &lt;br /&gt;
                    if (NumMessages == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = -1;&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (CurrentMessage &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CLEAR)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList=[];&lt;br /&gt;
                    AddressList=[];&lt;br /&gt;
                    SubjectList=[];&lt;br /&gt;
                    BodyList=[];&lt;br /&gt;
                    NumMessages=0;&lt;br /&gt;
                    CurrentMessage=-1;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_HELP, arg, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_INFO)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                Show();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_RESET)&lt;br /&gt;
            {&lt;br /&gt;
                llResetScript();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                state not_running;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HOME)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs==1)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETHOME, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETHOME, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// email() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    email(string time, string address, string subject, string body, integer queued)&lt;br /&gt;
    {&lt;br /&gt;
        NotifyNewMail(time, address, subject, body);&lt;br /&gt;
        TimeList = (TimeList=[]) + TimeList + [time];&lt;br /&gt;
        AddressList = (AddressList=[]) + AddressList + [address];&lt;br /&gt;
        SubjectList = (SubjectList=[]) + SubjectList + [subject];&lt;br /&gt;
        BodyList = (BodyList=[]) + BodyList + [body];&lt;br /&gt;
        ++NumMessages;&lt;br /&gt;
        &lt;br /&gt;
        if (CurrentMessage == -1)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = NumMessages - 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_REPLY)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state not_running&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state not_running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;SL Mailbox switched OFF. Say @ON to switch it back on.&amp;quot;);&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// on_rez() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// listen() ////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer chan, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string command=llToUpper(message);&lt;br /&gt;
        &lt;br /&gt;
        if (command == COMMAND_ON)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state Error&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state Error&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Error in SL Mail: not all component scripts found.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// End SL Mail V1.2.lsl&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Address Book V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Read and interpret the contents of the Address Book.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail AddressBook V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// &lt;br /&gt;
//  Read the Address Book from a notecard named &amp;quot;Address Book&amp;quot;.&lt;br /&gt;
//&lt;br /&gt;
//  The Address Book has the following format:&lt;br /&gt;
//  &lt;br /&gt;
//  [ADDRESS BOOK]&lt;br /&gt;
//  Name1=username@yourdomain.com&lt;br /&gt;
//  Name2=otheruser@otherdomain.com&lt;br /&gt;
//  ...&lt;br /&gt;
//  [GROUP]&lt;br /&gt;
//  group1=Name1, Name2&lt;br /&gt;
//  ...&lt;br /&gt;
//&lt;br /&gt;
//  Notes:&lt;br /&gt;
//  1. Group and Name share the same namespace, and must be unique.&lt;br /&gt;
//  2. It is allowed to have a name in the addressbook with multiple addresses, seperated by comma&#039;s.&lt;br /&gt;
// &lt;br /&gt;
/////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string  CurrentMailAddress = &amp;quot;&amp;quot;;&lt;br /&gt;
string  CurrentMailSubject = &amp;quot;&amp;quot;;&lt;br /&gt;
integer StatusOnline = FALSE;&lt;br /&gt;
&lt;br /&gt;
// Fetch or Send notecard&lt;br /&gt;
&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Names&lt;br /&gt;
&lt;br /&gt;
list    AddressBookList=[];&lt;br /&gt;
list    MailAddressList=[];&lt;br /&gt;
&lt;br /&gt;
string  STRING_HOME=&amp;quot;HOME&amp;quot;;&lt;br /&gt;
string  STRING_SELF=&amp;quot;SELF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Groups&lt;br /&gt;
&lt;br /&gt;
list   GroupList=[];&lt;br /&gt;
list   GroupNameList=[];&lt;br /&gt;
&lt;br /&gt;
string LSL_DOMAIN = &amp;quot;lsl.secondlife.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Read Address Book notecard&lt;br /&gt;
&lt;br /&gt;
string  ADDRESSBOOK_NOTECARD=&amp;quot;Address Book&amp;quot;;&lt;br /&gt;
integer Line=0;&lt;br /&gt;
key     reqAddressBook=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
integer Section=0;&lt;br /&gt;
integer SECTION_ADDRESS_BOOK=1;&lt;br /&gt;
integer SECTION_GROUP=2;&lt;br /&gt;
string  STRING_ADDRESS_BOOK=&amp;quot;ADDRESS BOOK&amp;quot;;&lt;br /&gt;
string  STRING_GROUP=&amp;quot;GROUP&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Links messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
integer MSG_MESSAGE_NOTIFY              = 90900;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED            = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR            = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// GetSelfAddress() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
string GetSelfAddress()&lt;br /&gt;
{&lt;br /&gt;
    return (string)llGetKey() + &amp;quot;@&amp;quot; + LSL_DOMAIN;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Info() /////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Info()&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;The mail address for this object is: &amp;quot; &lt;br /&gt;
                    + GetSelfAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// IsValidKeyFormat() //////////////////////&lt;br /&gt;
&lt;br /&gt;
integer IsValidKeyFormat(string str)&lt;br /&gt;
{&lt;br /&gt;
    string keychars = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    if (llStringLength(str) != 36)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    if( (llGetSubString( str, 8, 8 )   != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 13, 13 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 18, 18 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 23, 23 )  != &amp;quot;-&amp;quot; ) )&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 9; i &amp;lt; 13; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 14; i &amp;lt; 18; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 19; i &amp;lt; 23; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 24; i &amp;lt; 36; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// ValidMailAddress() ////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer ValidMailAddress(string arg)&lt;br /&gt;
{&lt;br /&gt;
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));&lt;br /&gt;
    &lt;br /&gt;
    if (adress == &amp;quot;&amp;quot;)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    list parse = llParseStringKeepNulls(adress, [ &amp;quot;@&amp;quot; ], []);&lt;br /&gt;
    string account = llList2String(parse,0);&lt;br /&gt;
    string domain  = llList2String(parse,1);&lt;br /&gt;
    &lt;br /&gt;
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    &lt;br /&gt;
    if (domain == LSL_DOMAIN)&lt;br /&gt;
    {&lt;br /&gt;
        return IsValidKeyFormat(account);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list parsedomain = llParseString2List(domain, [ &amp;quot;.&amp;quot; ], []);&lt;br /&gt;
    &lt;br /&gt;
        if (llGetListLength(parsedomain) &amp;lt; 2)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        &lt;br /&gt;
        integer num = llGetListLength(parsedomain);&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llStringLength(llList2String(parsedomain,i)) &amp;lt; 2)&lt;br /&gt;
            {&lt;br /&gt;
                return FALSE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetAddressStr() ///////////////////&lt;br /&gt;
&lt;br /&gt;
string GetAndCheckAddressStr(string address)&lt;br /&gt;
{&lt;br /&gt;
    list addresslist = llCSV2List(address);&lt;br /&gt;
    integer num=llGetListLength(addresslist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    string addressstr=&amp;quot;&amp;quot;;&lt;br /&gt;
    string curaddress=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        curaddress=llList2String(addresslist,i);&lt;br /&gt;
        &lt;br /&gt;
        if (ValidMailAddress(curaddress))&lt;br /&gt;
        {&lt;br /&gt;
            addressstr = (addressstr=&amp;quot;&amp;quot;) + addressstr + curaddress + &amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address string: &#039;&amp;quot; &lt;br /&gt;
                            + curaddress + &amp;quot;&#039;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return llGetSubString(addressstr, 0, -2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ProcessLine() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
ProcessLine(string rawline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(rawline,STRING_TRIM);&lt;br /&gt;
    string first=llGetSubString(line,0,0);&lt;br /&gt;
    string last=llGetSubString(line,-1,-1);&lt;br /&gt;
    &lt;br /&gt;
    // Ignore a blank line or comment line&lt;br /&gt;
    if (line == &amp;quot;&amp;quot; || first == &amp;quot;#&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // Check for the right section&lt;br /&gt;
    &lt;br /&gt;
    if (first == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; last == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        string sectionstr=llToUpper(llStringTrim(llGetSubString(line,1,-2),STRING_TRIM));&lt;br /&gt;
        &lt;br /&gt;
        if (sectionstr == STRING_ADDRESS_BOOK)&lt;br /&gt;
        {&lt;br /&gt;
            Section = SECTION_ADDRESS_BOOK;&lt;br /&gt;
        }&lt;br /&gt;
        else if (sectionstr == STRING_GROUP)&lt;br /&gt;
        {&lt;br /&gt;
            if (Section == 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                        + &amp;quot;. Group section defined before Address Book section.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Section = SECTION_GROUP;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid section header &#039;&amp;quot; + sectionstr &lt;br /&gt;
                        + &amp;quot;&#039; in &amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Must be in a section&lt;br /&gt;
    &lt;br /&gt;
    if (Section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;. No section header.&amp;quot;, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    list     parse=llParseString2List(line, [ &amp;quot;=&amp;quot; ], []);&lt;br /&gt;
    integer  num=llGetListLength(parse);&lt;br /&gt;
    &lt;br /&gt;
    // Format must be correct&lt;br /&gt;
    &lt;br /&gt;
    if (num != 2)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; +  (string)(Line+1) + &amp;quot;:\n&amp;quot; + rawline, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (Section == SECTION_ADDRESS_BOOK)&lt;br /&gt;
    {&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(name) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + name &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ name ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            string address=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
            string addressstr=GetAndCheckAddressStr(address);&lt;br /&gt;
            &lt;br /&gt;
            if (addressstr != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                AddressBookList     = (AddressBookList=[])     + AddressBookList     + [ name ];&lt;br /&gt;
                MailAddressList     = (MailAddressList=[])     + MailAddressList     + [ addressstr ];&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;No valid mail address for &#039;&amp;quot; + name &lt;br /&gt;
                    + &amp;quot;&#039;. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                    + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name &lt;br /&gt;
                + &amp;quot;&#039; already defined. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // Group&lt;br /&gt;
    {&lt;br /&gt;
        string group=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(group) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + group &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ group ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(GroupList, [ group ]) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                string names=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
                list   namelist=llCSV2List(names);&lt;br /&gt;
                integer num=llGetListLength(namelist);&lt;br /&gt;
                integer i;&lt;br /&gt;
                integer index;&lt;br /&gt;
                string  name;&lt;br /&gt;
                string  namestr=&amp;quot;&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
                for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                    name=llList2String(namelist,i);&lt;br /&gt;
                    index=llListFindList(AddressBookList, [ name ]);&lt;br /&gt;
            &lt;br /&gt;
                    if (index == -1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name + &amp;quot;&#039; defined in Group &#039;&amp;quot; &lt;br /&gt;
                                + group + &amp;quot;&#039; not found in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY); &lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        namestr = (namestr=&amp;quot;&amp;quot;) + namestr + name + &amp;quot;,&amp;quot;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (namestr != &amp;quot;&amp;quot;)&lt;br /&gt;
                {    &lt;br /&gt;
                    namestr=llGetSubString(namestr,0,-2);&lt;br /&gt;
                    GroupList         = (GroupList=[])         + GroupList     + [ group ];&lt;br /&gt;
                    GroupNameList     = (GroupNameList=[])    + GroupNameList + [ namestr ];&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                        + &amp;quot;&#039; has no valid names. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                        + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                    + &amp;quot;&#039; already defined in Group. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                    + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group&lt;br /&gt;
                + &amp;quot;&#039; already defined in Address Book. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// GetGroupAddressList ///////////////&lt;br /&gt;
&lt;br /&gt;
string GetGroupAddressList(string group)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(GroupList, [ group ]);&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(GroupList);&lt;br /&gt;
    string  grouplist=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        for (i = index; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2String(GroupList,i) == group)&lt;br /&gt;
            {&lt;br /&gt;
                grouplist = (grouplist=&amp;quot;&amp;quot;) + grouplist + llList2String(GroupNameList,i) + &amp;quot;,&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (grouplist != &amp;quot;&amp;quot;) grouplist=llGetSubString(grouplist,0,-2);   // remove last &amp;quot;,&amp;quot;&lt;br /&gt;
        return grouplist;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// SetMailAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetMailAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ address ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        index=llListFindList(GroupList, [ address ]);&lt;br /&gt;
        &lt;br /&gt;
        if (index == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llToUpper(address) == STRING_SELF)&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = GetSelfAddress();&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if(ValidMailAddress(address))&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = address;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Mail adress &amp;quot; + address &lt;br /&gt;
                            + &amp;quot; : not found in adress book or invalid format.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailAddress = GetGroupAddressList(address);&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        CurrentMailAddress = llList2String(MailAddressList,index);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                        + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string message)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No mail address defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No subject defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list mailaddresslist=llCSV2List(CurrentMailAddress);&lt;br /&gt;
        integer num=llGetListLength(mailaddresslist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(mailaddresslist,i);&lt;br /&gt;
            llEmail(address, CurrentMailSubject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMailHome() ////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMailHome(string message, string subject)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, STRING_HOME &lt;br /&gt;
                + &amp;quot; not set. Set your home adress with @HOME &amp;lt;address&amp;gt;.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        string homeaddress=llList2String(AddressBookList,index);&lt;br /&gt;
        list   homelist=llCSV2List(homeaddress);&lt;br /&gt;
        integer num=llGetListLength(homelist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(homelist,i);&lt;br /&gt;
            llEmail(address, subject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
string GetHomeAddress()&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;not set&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2String(MailAddressList,index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetHomeAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        AddressBookList     = (AddressBookList=[]) + [ STRING_HOME ] + AddressBookList;&lt;br /&gt;
        MailAddressList     = (MailAddressList=[]) + [ GetAndCheckAddressStr(address) ]  + MailAddressList;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MailAddressList = llListReplaceList(MailAddressList, [ GetAndCheckAddressStr(address) ], index, index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        Line=0;&lt;br /&gt;
        Section=0;&lt;br /&gt;
        llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// dataserver() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqAddressBook)&lt;br /&gt;
        {&lt;br /&gt;
            reqAddressBook = NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                ProcessLine(data);&lt;br /&gt;
                reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Address Book loaded.&amp;quot;, NULL_KEY);&lt;br /&gt;
                state running;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// timer() ///////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_ERROR, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Could not read Address Book: &amp;quot; &lt;br /&gt;
                            + ADDRESSBOOK_NOTECARD + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// link_message() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_MESSAGE_GETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is empty.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailSubject = message;&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is empty.&amp;quot;, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            SetMailAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Body of message to send is empty. &amp;quot; &lt;br /&gt;
                                +  &amp;quot;No mail is send.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SENDHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SendMailHome(message, (string)id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetInventoryType(message) == INVENTORY_NOTECARD)&lt;br /&gt;
            {&lt;br /&gt;
                Notecard2Fetch = message;                &lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_READ, message, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + message + &amp;quot; not found.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_NOTECARD_FETCHED)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + Notecard2Fetch &lt;br /&gt;
                            + &amp;quot; was empty or could not be read.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Home address is: &amp;quot; + GetHomeAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SetHomeAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_INFO)&lt;br /&gt;
        {&lt;br /&gt;
            Info();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
// End SL Mail AddressBook V1.2.lsl&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail FetchNotecard V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch the contents of a notecard and return it via link message as a string.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Notecard&lt;br /&gt;
&lt;br /&gt;
integer Line=0;&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
key     reqNotecard=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=10.0;&lt;br /&gt;
integer Fetched=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Lines&lt;br /&gt;
&lt;br /&gt;
list LineList=[];&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    /////////////////////// dataserver() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqNotecard)&lt;br /&gt;
        {&lt;br /&gt;
            reqNotecard=NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                LineList = (LineList=[]) + LineList + [ data ];&lt;br /&gt;
                reqNotecard = llGetNotecardLine(Notecard2Fetch, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Fetched=TRUE;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, llDumpList2String(LineList, &amp;quot;\n&amp;quot;), NULL_KEY);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /////////////////////// timer() ///////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        if (!Fetched)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            llSetTimerEvent(0.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer send, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_NOTECARD_READ)&lt;br /&gt;
        {&lt;br /&gt;
            Line=0;&lt;br /&gt;
            Notecard2Fetch=message;&lt;br /&gt;
            LineList=[];&lt;br /&gt;
            Fetched=FALSE;&lt;br /&gt;
            reqNotecard=llGetNotecardLine(Notecard2Fetch, Line);&lt;br /&gt;
            llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL OnlineStatus V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch online status of owner.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Online status&lt;br /&gt;
&lt;br /&gt;
key     reqOnlineStatus=NULL_KEY;&lt;br /&gt;
float   STATUS_INTERVAL=2.0;&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_STATUS_ONLINE       = 30000;&lt;br /&gt;
integer MS_STATUS_OFFLINE       = 30100;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus=llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
        llSetTimerEvent(STATUS_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// dataserver() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqOnlineStatus)&lt;br /&gt;
        {&lt;br /&gt;
            reqOnlineStatus = NULL_KEY;&lt;br /&gt;
        &lt;br /&gt;
            if (data==&amp;quot;1&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_STATUS_ONLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if (data==&amp;quot;0&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MS_STATUS_OFFLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus = llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Help V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Display help information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail Help V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP    = 10000;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Help() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Help()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;HELP for SL Mail V1.2.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;COMMANDS:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HELP               - displays help info.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@INFO               - display mailaddress of this object.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RECORD             - start recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CONTINUE           - continue recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@STOP               - stop recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@IGNORE             - ignore the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SHOW               - show what your recorded.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SEND               - send the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@MAIL &amp;lt;mailadress&amp;gt;  - set the mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SUBJECT subject    - set the mail subject.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LIST               - list messages in mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SELECT &amp;lt;message&amp;gt;   - select message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@READ               - read current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@NEXT               - read next message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@PREV               - read previous message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@FIRST              - read first message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LAST               - read last message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@DELETE             - delete current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CLEAR              - clear the mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@REPLY              - reply to current message.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RESET              - reset the script.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HOME               - set the home mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@OFF                - switch mailbox OFF.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@ON                 - switch mailbox ON.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_HELP)&lt;br /&gt;
        {&lt;br /&gt;
            Help();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail Help V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}&lt;/div&gt;</description>
			<pubDate>Wed, 09 Feb 2011 23:19:22 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:SL_Mail_V1.2</comments>
		</item>
		<item>
			<title>SL Mail V1.2</title>
			<link>https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=1133909</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=1133909</guid>
			<description>&lt;p&gt;Flennan Roffo: /* Release Notes V1.2 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}} __NOTOC__&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=&#039;&#039;&#039;Second Life mail client&#039;&#039;&#039;=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Send and receive email from within Second Life from and to any address.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implemented with Address Book function (in a notecard named &#039;Address Book&#039;) to stores addresses by name  and to compile groups of named addresses. Current version is stand-alone (no server functionality) and uses chat commands only.&lt;br /&gt;
&lt;br /&gt;
[[Image:BannerSLMail.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.slmail.info slmail.info] &amp;lt;strike&amp;gt;(website coming soon!)&amp;lt;/strike&amp;gt; &amp;lt;b&amp;gt;url slmail.info no longer used for SL Mail, and was taken for some other purpose.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Release Notes V1.2=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 Release notes (edition 2, 4 sept 2007)&lt;br /&gt;
&lt;br /&gt;
===IMPORTANT NOTICE===&lt;br /&gt;
&lt;br /&gt;
Development of SL Mail was abandoned midyear 2008.&lt;br /&gt;
&lt;br /&gt;
SL Mail is considered for redevelopment under the same terms, using a version of the Serverless Key Exchange script.&lt;br /&gt;
See: [https://wiki.secondlife.com/wiki/Serverless_Key_Exchange Serverless Key Exchange]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LICENCE INFO&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
This program is free software: you can redistribute it and/or modify&lt;br /&gt;
it under the terms of the GNU General Public License as published by&lt;br /&gt;
the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
(at your option) any later version.&lt;br /&gt;
&lt;br /&gt;
This program is distributed in the hope that it will be useful,&lt;br /&gt;
but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
GNU General Public License for more details.&lt;br /&gt;
&lt;br /&gt;
You should have received a copy of the GNU General Public License&lt;br /&gt;
along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;PRODUCTION &amp;amp; MAINTANENCE&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
by Logic Scripted Products and Script Services&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.logicscripts.org logicscripts.org] (website coming soon!)&lt;br /&gt;
&lt;br /&gt;
SLurl:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Contact: [[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
&lt;br /&gt;
Email: [mailto:info@slmail.info &#039;&#039;&#039;info&#039;&#039;&#039;] or [mailto:Flennan.Roffo@slmail.info &#039;&#039;&#039;Flennan Roffo&#039;&#039;&#039;]&lt;br /&gt;
&#039;&#039;&#039;* The slmail.info URL appears to not be registered and this information appears to be out of date. *&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;DESCRIPTION&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is a simple tool to send and receive mail from within SL.&lt;br /&gt;
You can either compose a message yourself using chat recording, or choose a notecard from inventory to send. The Address Book functionality allows you to use short names for mail recipients stored in a notecard. The current version does not have a persisent mail address. Watch out for the upcoming next release (V1.3) which will facilitate persisent in-world mail addresses and will be enhanced with many new features (See: Requests For Change (RFC).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;COMMANDS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Help&#039;&#039;&#039;&lt;br /&gt;
||Show Help about available commands&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Record&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording (for owner only).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Stop&#039;&#039;&#039;&lt;br /&gt;
||Stops the chat recording without sending&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Continue&#039;&#039;&#039;&lt;br /&gt;
||Continues a previously stopped chat recording. Lines will be appended to you recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Show&#039;&#039;&#039;&lt;br /&gt;
||Shows the content of the recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send&#039;&#039;&#039;&lt;br /&gt;
||If recording, stops the recording, and sends the mail (need to supply mail address and subject first!)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send &amp;lt;notecard&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Sends the content of the notecard, instead of the chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Ignore&#039;&#039;&#039;&lt;br /&gt;
||Ignores your current chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject &amp;lt;subject&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the subject of the mail.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail subject.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Set the HOME address of the owner (mail will be forwarder to this address when offline).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home&#039;&#039;&#039;&lt;br /&gt;
||Show the HOME address.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Info&#039;&#039;&#039;&lt;br /&gt;
||Shows the mail address the object this script is running in uses (e.g. &amp;lt;object-key&amp;gt;@lsl.secondlife.com).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Read&#039;&#039;&#039;&lt;br /&gt;
||Reads the current message from the mail buffer (the mail buffer gets filled with mail you receive)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Select &amp;lt;msg&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Select a message number from the availabe messages in the mail buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Next&#039;&#039;&#039;&lt;br /&gt;
||Make next message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Prev&#039;&#039;&#039;&lt;br /&gt;
||Make previous message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@First&#039;&#039;&#039;&lt;br /&gt;
||Make the first message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Last&#039;&#039;&#039;&lt;br /&gt;
||Make the last message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Clear&#039;&#039;&#039;&lt;br /&gt;
||Clear the mail buffer&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Delete&#039;&#039;&#039;&lt;br /&gt;
||Deletes only the current message&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Reply&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording to reply to the current message. Mail adress and subject are filled in automatically.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* Commands are case insensitive (&amp;quot;@read&amp;quot; == &amp;quot;@READ&amp;quot;). Arguments might not be case insensitive.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;ADDRESS BOOK FORMAT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
A notecard of the name &#039;Address Book&#039; is read during initialization which may contain Address Book items and Groups.&lt;br /&gt;
The notecard is split in two sections, which need to be defined in that particular order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[ADDRESS BOOK]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Defines the section in which you can put names for mail addresses,  like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name1=account@thisdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name2=user@otherdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[GROUP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define groups of previously defined names under a new name, like for instance:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyGroup=Name1, Name2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note that names of groups and individual mail adresses share the same namespace and must be unique.&lt;br /&gt;
&lt;br /&gt;
So when you filled in your mail adresses in the Address Book, you can now use:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail Name1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to  &amp;lt;account@thisdomain.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail MyGroup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to &amp;lt;account@thisdomain.com&amp;gt; and &amp;lt;user@otherdomain.com&amp;gt;&lt;br /&gt;
Mails will be sent one after another.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* Names for Addreses and Groups are case insensitive (e.g. &amp;quot;mary&amp;quot;  == &amp;quot;MARY&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* The special address &#039;Self&#039; can be used in commands where otherwise an address specification can be used. &#039;Self&#039; is case insensitive (e.g. &amp;quot;self&amp;quot; == &amp;quot;SELF&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LIMITATIONS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
The current version is limited by the following:&lt;br /&gt;
&lt;br /&gt;
* Chat recording lines are limited by the 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Output of lines from the mail buffer are also limited by this 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Incoming mail is limited to a 1000 (1024?) byte limit&lt;br /&gt;
&lt;br /&gt;
* Outgoing mai is limited by a 4096 byte limit, which includes the standard mail header (region/location info on the first two lines)&lt;br /&gt;
&lt;br /&gt;
We are making adjustments to this release to help overcome these limitations. At least the line lenght limit can be overcome by introducing a line continuation character (for example a hyphen &#039;-&#039;) that when used at the end of a line appends the next line, so lines longer then 255 bytes are possible then.&lt;br /&gt;
&lt;br /&gt;
To overcome the outgoing mail length limit, the mail can be broken textualy into parts, and each part can be send seperatedely, with an indication in the subject or in an introduced primary line of the mail body to indicate that the mail was split into parts.&lt;br /&gt;
For incoming mail and at least to receive mail from other SL Mail programs, a protocol will be introduced to receive mail in parts that are joined together after receiving them to form a single mail.&lt;br /&gt;
&lt;br /&gt;
These enhancements will be made available in the next release (V1.3) of SL Mail &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;BUGS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Report any bugs you find in this release to Logic (IM: Flennan Roffo).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;REQUEST FOR CHANGE (RFC)&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Do you have additional wishes for enhancement of this product?&lt;br /&gt;
Contact Flennan Roffo and we will see if they can be implemented in the next release.&lt;br /&gt;
&lt;br /&gt;
Existing RFC&#039;s are:&lt;br /&gt;
&lt;br /&gt;
* Menu support for commands.&lt;br /&gt;
&lt;br /&gt;
* Lines on incoming/outgoing mail longer than 255 bytes.&lt;br /&gt;
&lt;br /&gt;
* Send messages longer than 4096 (minus SL mail header) bytes.&lt;br /&gt;
&lt;br /&gt;
* Receive messages longer than 1024 bytes.&lt;br /&gt;
&lt;br /&gt;
* Permanent mail addresses for the SL Mail client (like: &amp;lt;Flennan.Roffo@somedomain.sl&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Add your RFC!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In-world join the group &amp;quot;SL Mail&amp;quot; for bug reports, feature requests, the latest SL Mail release, and notices about development issues.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scripts=&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==Script: SL Mail v1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail core module which scans for incoming mail messages and executes commands used by the owner.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail V1.2.lsl&lt;br /&gt;
// (c) 2007 Logic Scripted Products and Script Services&lt;br /&gt;
// Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
// VERSION&lt;br /&gt;
// Version: 1.2&lt;br /&gt;
&lt;br /&gt;
// HISTORY&lt;br /&gt;
// Date         Version     Author              Comment&lt;br /&gt;
// --------------------------------------------------------------------------------------&lt;br /&gt;
// 28 aug 2007  V 1.0       Flennan Roffo       Created&lt;br /&gt;
//&lt;br /&gt;
//  1 sep 2007  V 1.1       Flennan Roffo       @Reply empties the recording buffer.&lt;br /&gt;
//                                                @Send while recording ends recording&lt;br /&gt;
//                                                and sends the mail if a mail address&lt;br /&gt;
//                                                and subject are supplied.&lt;br /&gt;
//                                                Fixed incorrect date in Unix2DateTime.&lt;br /&gt;
//  3 sep 2007  V 1.2       Flennan Roffo       Notification options:&lt;br /&gt;
//                                              - When online, send an IM when mail is received.&lt;br /&gt;
//                                              - When offline, send to HOME mail adress.&lt;br /&gt;
//                                              Adressbook&lt;br /&gt;
//                                              - Read adress book from config notecard.&lt;br /&gt;
&lt;br /&gt;
// LICENCE&lt;br /&gt;
// This program is free software; you can redistribute it and/or&lt;br /&gt;
// modify it under the terms of the GNU General Public License&lt;br /&gt;
// as published by the Free Software Foundation; either version 2&lt;br /&gt;
// of the License, or (at your option) any later version.&lt;br /&gt;
// &lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
// &lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program; if not, write to the Free Software&lt;br /&gt;
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
// (Also available at http://www.gnu.org/copyleft/gpl.html) &lt;br /&gt;
&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// Let&#039;s you record a message and sent to email and get messages and reply to messages.&lt;br /&gt;
// Must supply a valid mail adress and non-empty subject using chat commands.&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
// 1) Check for the maximum length of an email message (including newline and header).&lt;br /&gt;
// 2) Read adress book from notecard.                                    *DONE*&lt;br /&gt;
// 3) Send incoming mail to personal mail adress when offline.            *DONE*&lt;br /&gt;
// 4) Alert with an IM when online upon receiving new mail.                *DONE*&lt;br /&gt;
&lt;br /&gt;
string   SL_MAIL_VERSION = &amp;quot;V 1.2&amp;quot;;&lt;br /&gt;
string   SL_MAIL_DATE    = &amp;quot; 2 sep 2007&amp;quot;;&lt;br /&gt;
integer  ErrorFlag         = FALSE;&lt;br /&gt;
list     ScriptList        = [ &amp;quot;SL Mail Help V1.2&amp;quot;, &amp;quot;SL Mail AddressBook V1.2&amp;quot;, &lt;br /&gt;
                                &amp;quot;SL Mail OnlineStatus V1.2&amp;quot;, &amp;quot;SL Mail FetchNotecard V1.2&amp;quot; ];    &lt;br /&gt;
string   LSL_DOMAIN=&amp;quot;lsl.secondlife.com&amp;quot;; &lt;br /&gt;
integer  StatusOnline=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Commands&lt;br /&gt;
&lt;br /&gt;
string  COMMAND_RECORD     = &amp;quot;@RECORD&amp;quot;;&lt;br /&gt;
string  COMMAND_CONTINUE   = &amp;quot;@CONTINUE&amp;quot;;&lt;br /&gt;
string  COMMAND_STOP       = &amp;quot;@STOP&amp;quot;;&lt;br /&gt;
string  COMMAND_MAIL       = &amp;quot;@MAIL&amp;quot;;&lt;br /&gt;
string  COMMAND_SUBJECT    = &amp;quot;@SUBJECT&amp;quot;;&lt;br /&gt;
string  COMMAND_SEND       = &amp;quot;@SEND&amp;quot;;&lt;br /&gt;
string  COMMAND_SEE        = &amp;quot;@SEE&amp;quot;;&lt;br /&gt;
string  COMMAND_IGNORE     = &amp;quot;@IGNORE&amp;quot;;&lt;br /&gt;
string  COMMAND_READ       = &amp;quot;@READ&amp;quot;;&lt;br /&gt;
string  COMMAND_DELETE     = &amp;quot;@DELETE&amp;quot;;&lt;br /&gt;
string  COMMAND_CLEAR      = &amp;quot;@CLEAR&amp;quot;;&lt;br /&gt;
string  COMMAND_REPLY      = &amp;quot;@REPLY&amp;quot;;&lt;br /&gt;
string  COMMAND_NEXT       = &amp;quot;@NEXT&amp;quot;;&lt;br /&gt;
string  COMMAND_PREV       = &amp;quot;@PREV&amp;quot;;&lt;br /&gt;
string  COMMAND_FIRST      = &amp;quot;@FIRST&amp;quot;;&lt;br /&gt;
string  COMMAND_LAST       = &amp;quot;@LAST&amp;quot;;&lt;br /&gt;
string  COMMAND_LIST       = &amp;quot;@LIST&amp;quot;;&lt;br /&gt;
string  COMMAND_SELECT     = &amp;quot;@SELECT&amp;quot;;&lt;br /&gt;
string  COMMAND_HELP       = &amp;quot;@HELP&amp;quot;;&lt;br /&gt;
string  COMMAND_INFO       = &amp;quot;@INFO&amp;quot;;&lt;br /&gt;
string  COMMAND_RESET      = &amp;quot;@RESET&amp;quot;;&lt;br /&gt;
string  COMMAND_SHOW       = &amp;quot;@SHOW&amp;quot;;&lt;br /&gt;
string  COMMAND_ON         = &amp;quot;@ON&amp;quot;;&lt;br /&gt;
string  COMMAND_OFF        = &amp;quot;@OFF&amp;quot;;&lt;br /&gt;
string  COMMAND_HOME       = &amp;quot;@HOME&amp;quot;;&lt;br /&gt;
string  COMMAND_LOAD       = &amp;quot;@LOAD&amp;quot;;&lt;br /&gt;
string  COMMAND_ADDRESS    = &amp;quot;@ADDRESS&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Recording&lt;br /&gt;
&lt;br /&gt;
integer Recording = FALSE;&lt;br /&gt;
&lt;br /&gt;
list    ChatRecording=[];&lt;br /&gt;
integer NumLines=0;&lt;br /&gt;
integer Length=0;&lt;br /&gt;
&lt;br /&gt;
list     TimeList=[];&lt;br /&gt;
list     AddressList=[];&lt;br /&gt;
list     SubjectList=[];&lt;br /&gt;
list     BodyList=[];&lt;br /&gt;
integer  NumMessages=0;&lt;br /&gt;
integer  CurrentMessage=-1;&lt;br /&gt;
&lt;br /&gt;
float    MAIL_FETCH_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
// Link Messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP                        = 10000;&lt;br /&gt;
integer MSG_STATUS_ONLINE               = 30000;&lt;br /&gt;
integer MSG_STATUS_OFFLINE              = 30100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED          = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR           = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Unix Time conversion //////////////////&lt;br /&gt;
&lt;br /&gt;
integer DAYS_PER_YEAR        = 365;                // Non leap year&lt;br /&gt;
integer SECONDS_PER_YEAR     = 31536000;          // Non leap year&lt;br /&gt;
integer SECONDS_PER_DAY      = 86400;&lt;br /&gt;
integer SECONDS_PER_HOUR     = 3600;&lt;br /&gt;
integer SECONDS_PER_MINUTE   = 60;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// LeapYear() /////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer LeapYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (year % 4 == 0)&lt;br /&gt;
    {&lt;br /&gt;
        if (year % 100 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (year % 400 == 0)&lt;br /&gt;
            {&lt;br /&gt;
                return 1;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// DaysPerMonth() ///////////////////////////////////////&lt;br /&gt;
                &lt;br /&gt;
integer DaysPerMonth(integer year,integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;lt; 8)&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (month == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if (LeapYear(year))&lt;br /&gt;
                {&lt;br /&gt;
                    return 29;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    return 28;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 30;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 30;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////// DaysPerYear() ////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DaysPerYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (LeapYear(year))&lt;br /&gt;
        return DAYS_PER_YEAR + 1;&lt;br /&gt;
    else&lt;br /&gt;
        return DAYS_PER_YEAR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Unix2DataTime() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list Unix2DateTime(integer unixtime)&lt;br /&gt;
{&lt;br /&gt;
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;&lt;br /&gt;
    integer day = days_since_1_1_1970 + 1;&lt;br /&gt;
    integer year  = 1970;&lt;br /&gt;
    integer days_per_year = DaysPerYear(year);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_year)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_year;&lt;br /&gt;
        ++year;&lt;br /&gt;
        days_per_year = DaysPerYear(year);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer month = 1;&lt;br /&gt;
    integer days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_month)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_month;&lt;br /&gt;
        &lt;br /&gt;
        if (++month &amp;gt; 12)&lt;br /&gt;
        {    &lt;br /&gt;
            ++year;&lt;br /&gt;
            month = 1;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;&lt;br /&gt;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;&lt;br /&gt;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;&lt;br /&gt;
    integer minute      = second / SECONDS_PER_MINUTE;&lt;br /&gt;
    second               = second % SECONDS_PER_MINUTE;&lt;br /&gt;
    &lt;br /&gt;
    return [ year, month, day, hour, minute, second ];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// MonthName() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list MonthNameList = [     &amp;quot;JAN&amp;quot;, &amp;quot;FEB&amp;quot;, &amp;quot;MAR&amp;quot;, &amp;quot;APR&amp;quot;, &amp;quot;MAY&amp;quot;, &amp;quot;JUN&amp;quot;, &lt;br /&gt;
                        &amp;quot;JUL&amp;quot;, &amp;quot;AUG&amp;quot;, &amp;quot;SEP&amp;quot;, &amp;quot;OCT&amp;quot; , &amp;quot;NOV&amp;quot;, &amp;quot;DEC&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
string MonthName(integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;gt;= 0 &amp;amp;&amp;amp; month &amp;lt; 12)&lt;br /&gt;
        return llList2String(MonthNameList, month);&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// DateString() ///////////////////////////&lt;br /&gt;
&lt;br /&gt;
string DateString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer year       = llList2Integer(timelist,0);&lt;br /&gt;
    integer month      = llList2Integer(timelist,1);&lt;br /&gt;
    integer day        = llList2Integer(timelist,2);&lt;br /&gt;
    &lt;br /&gt;
    return (string)day + &amp;quot;-&amp;quot; + MonthName(month - 1) + &amp;quot;-&amp;quot; + (string)year;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// TimeString() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string TimeString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer hour          = llList2Integer(timelist,3);&lt;br /&gt;
    integer minute         = llList2Integer(timelist,4);&lt;br /&gt;
    integer second         = llList2Integer(timelist,5);&lt;br /&gt;
    string  hourstr     = (string)hour;&lt;br /&gt;
    string  minutestr   = (string)minute;&lt;br /&gt;
    string  secondstr   = (string)second;&lt;br /&gt;
    &lt;br /&gt;
    if (hour &amp;lt; 10)         hourstr     = &amp;quot;0&amp;quot; + hourstr;&lt;br /&gt;
    if (minute &amp;lt; 10)     minutestr     = &amp;quot;0&amp;quot; + minutestr;&lt;br /&gt;
    if (second &amp;lt; 10)    secondstr    = &amp;quot;0&amp;quot; + secondstr;&lt;br /&gt;
    return hourstr + &amp;quot;:&amp;quot; + minutestr + &amp;quot;:&amp;quot; + secondstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() /////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string body)&lt;br /&gt;
{&lt;br /&gt;
    // llOwnerSay(&amp;quot;Sending message to &#039;&amp;quot; + address + &amp;quot;&#039; with subject &#039;&amp;quot; + subject +&amp;quot;&#039;.&amp;quot;);&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND, body, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// SendHome() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendHome(string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SENDHOME, body, (key)subject);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Show() ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Show()&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;Current chat recording is:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; NumLines; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(ChatRecording,i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;Lines is &amp;quot; + (string)NumLines);&lt;br /&gt;
    llOwnerSay(&amp;quot;Message length is &amp;quot; + (string)Length);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Read() /////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Read()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;Reading message &amp;quot; + (string)CurrentMessage + &amp;quot; from mail buffer.&amp;quot;);&lt;br /&gt;
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);&lt;br /&gt;
    list timelist=Unix2DateTime(time);&lt;br /&gt;
    string Address = llList2String(AddressList,CurrentMessage);&lt;br /&gt;
    string Subject = llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
    string Body    = llList2String(BodyList,CurrentMessage);&lt;br /&gt;
    llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Address: &amp;quot; + Address);&lt;br /&gt;
    llOwnerSay(&amp;quot;Subject: &amp;quot; + Subject);&lt;br /&gt;
    llOwnerSay(&amp;quot;Begin of message body:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    list bodylist=llParseStringKeepNulls(Body, [ &amp;quot;\n&amp;quot; ], []);&lt;br /&gt;
    integer num=llGetListLength(bodylist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(bodylist,i));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;End of message body.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////// List ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
List()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;The mail buffer contains the following messages:\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; NumMessages; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer time=llList2Integer(TimeList,i);&lt;br /&gt;
        list timelist=Unix2DateTime(time);&lt;br /&gt;
        if (i &amp;gt; 0) llOwnerSay(&amp;quot;+-+-+-+-+-+-+-+-+-+-+-+-&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Message: &amp;quot; + (string)i);&lt;br /&gt;
        llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;From:    &amp;quot; + llList2String(AddressList,i));&lt;br /&gt;
        llOwnerSay(&amp;quot;Subject: &amp;quot; + llList2String(SubjectList,i));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////// NotifyNewMail() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
NotifyNewMail(string time, string address, string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    list timelist=Unix2DateTime((integer)time);&lt;br /&gt;
&lt;br /&gt;
    if (StatusOnline)&lt;br /&gt;
    {&lt;br /&gt;
        llInstantMessage(llGetOwner(), &amp;quot;You received a new mail message on &amp;quot; &lt;br /&gt;
                                    + DateString(timelist) + &amp;quot; at &amp;quot; + TimeString(timelist)&lt;br /&gt;
                                    + &amp;quot; from &amp;quot; + address &lt;br /&gt;
                                    + &amp;quot; with the subject &amp;quot; + subject);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        SendHome(&amp;quot;FW: &amp;quot; + subject, &amp;quot;Received at: &amp;quot; + DateString(timelist) + &amp;quot; &amp;quot; + TimeString(timelist) + &amp;quot;\nFrom: &amp;quot; +  address &lt;br /&gt;
                    + &amp;quot;\nBegin message body:\n-------------------\n&amp;quot; + body + &amp;quot;\n-------------------\nEnd message body.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ResetOtherScripts() //////////////////////&lt;br /&gt;
&lt;br /&gt;
ResetOtherScripts()&lt;br /&gt;
{&lt;br /&gt;
    string     name;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(ScriptList);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        name = llList2String(ScriptList,i);&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(name) == INVENTORY_SCRIPT)&lt;br /&gt;
        {&lt;br /&gt;
            llResetOtherScript(name);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Error - script &#039;&amp;quot; + name + &amp;quot;&#039; not found.&amp;quot;);&lt;br /&gt;
            ErrorFlag = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
// default &lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ////////////////////// state_entry() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Welcome to SL Mail, released under GNU software licence.&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Version &amp;quot; + SL_MAIL_VERSION + &amp;quot; &amp;quot; + SL_MAIL_DATE);&lt;br /&gt;
        llOwnerSay(&amp;quot;Produced by Logic Scripted Products &amp;amp; Product Services&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Free memory: &amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
        ResetOtherScripts();&lt;br /&gt;
        &lt;br /&gt;
        if (ErrorFlag)&lt;br /&gt;
            state Error;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// on_rez() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// changed() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_LOADED)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_ERROR)&lt;br /&gt;
        {&lt;br /&gt;
            state Error;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() //////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(MAIL_FETCH_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //////////////////////// on_rez() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// listen() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string trimmessage=llStringTrim(message,STRING_TRIM);&lt;br /&gt;
        list   parse = llParseStringKeepNulls(trimmessage, [ &amp;quot; &amp;quot;], []);&lt;br /&gt;
        string command = llToUpper(llList2String(parse,0));&lt;br /&gt;
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        integer nargs  = llGetListLength(parse);&lt;br /&gt;
        string argstr=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (nargs &amp;gt; 1) argstr=llGetSubString(message, llSubStringIndex(message, &amp;quot; &amp;quot;) + 1, -1);&lt;br /&gt;
            &lt;br /&gt;
        if (Recording)&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Recording stopped. Type @SHOW to see the message you have entered,&amp;quot;&lt;br /&gt;
                            + &amp;quot; or @SEND to send it.&amp;quot;);&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                &lt;br /&gt;
                SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];&lt;br /&gt;
                ++NumLines;&lt;br /&gt;
                Length += llStringLength(message) + 2;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_RECORD)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Start recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                ChatRecording = [];&lt;br /&gt;
                NumLines=0;&lt;br /&gt;
                Length=0;&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CONTINUE)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Continue recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_REPLY)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    string address=llList2String(AddressList,CurrentMessage);&lt;br /&gt;
                    string subject=&amp;quot;Re: &amp;quot; + llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, address, NULL_KEY);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, subject, NULL_KEY);&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines=0;&lt;br /&gt;
                    Length=0;&lt;br /&gt;
                    Recording = TRUE;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_MAIL)&lt;br /&gt;
            {&lt;br /&gt;
                string mailaddress=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailaddress != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, mailaddress, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETADDRESS, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SUBJECT)&lt;br /&gt;
            {&lt;br /&gt;
                string mailsubject=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailsubject != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, mailsubject, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETSUBJECT, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Not recording.&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    if (NumLines == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND_NOTECARD, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_IGNORE)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines = 0;&lt;br /&gt;
                    Length = 0;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Show();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_READ)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumMessages == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Read();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        ++CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        --CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_FIRST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = 0;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LAST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LIST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    List();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SELECT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;Need to supply a message number.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    integer msgnum = (integer)arg;&lt;br /&gt;
                     &lt;br /&gt;
                    if (msgnum &amp;lt; 0 || msgnum &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Message number &amp;quot; + arg + &amp;quot; not in mail buffer.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = msgnum;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_DELETE)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    --NumMessages;&lt;br /&gt;
                     &lt;br /&gt;
                    if (NumMessages == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = -1;&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (CurrentMessage &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CLEAR)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList=[];&lt;br /&gt;
                    AddressList=[];&lt;br /&gt;
                    SubjectList=[];&lt;br /&gt;
                    BodyList=[];&lt;br /&gt;
                    NumMessages=0;&lt;br /&gt;
                    CurrentMessage=-1;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_HELP, arg, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_INFO)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                Show();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_RESET)&lt;br /&gt;
            {&lt;br /&gt;
                llResetScript();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                state not_running;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HOME)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs==1)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETHOME, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETHOME, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// email() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    email(string time, string address, string subject, string body, integer queued)&lt;br /&gt;
    {&lt;br /&gt;
        NotifyNewMail(time, address, subject, body);&lt;br /&gt;
        TimeList = (TimeList=[]) + TimeList + [time];&lt;br /&gt;
        AddressList = (AddressList=[]) + AddressList + [address];&lt;br /&gt;
        SubjectList = (SubjectList=[]) + SubjectList + [subject];&lt;br /&gt;
        BodyList = (BodyList=[]) + BodyList + [body];&lt;br /&gt;
        ++NumMessages;&lt;br /&gt;
        &lt;br /&gt;
        if (CurrentMessage == -1)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = NumMessages - 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_REPLY)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state not_running&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state not_running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;SL Mailbox switched OFF. Say @ON to switch it back on.&amp;quot;);&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// on_rez() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// listen() ////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer chan, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string command=llToUpper(message);&lt;br /&gt;
        &lt;br /&gt;
        if (command == COMMAND_ON)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state Error&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state Error&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Error in SL Mail: not all component scripts found.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// End SL Mail V1.2.lsl&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Address Book V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Read and interpret the contents of the Address Book.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail AddressBook V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// &lt;br /&gt;
//  Read the Address Book from a notecard named &amp;quot;Address Book&amp;quot;.&lt;br /&gt;
//&lt;br /&gt;
//  The Address Book has the following format:&lt;br /&gt;
//  &lt;br /&gt;
//  [ADDRESS BOOK]&lt;br /&gt;
//  Name1=username@yourdomain.com&lt;br /&gt;
//  Name2=otheruser@otherdomain.com&lt;br /&gt;
//  ...&lt;br /&gt;
//  [GROUP]&lt;br /&gt;
//  group1=Name1, Name2&lt;br /&gt;
//  ...&lt;br /&gt;
//&lt;br /&gt;
//  Notes:&lt;br /&gt;
//  1. Group and Name share the same namespace, and must be unique.&lt;br /&gt;
//  2. It is allowed to have a name in the addressbook with multiple addresses, seperated by comma&#039;s.&lt;br /&gt;
// &lt;br /&gt;
/////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string  CurrentMailAddress = &amp;quot;&amp;quot;;&lt;br /&gt;
string  CurrentMailSubject = &amp;quot;&amp;quot;;&lt;br /&gt;
integer StatusOnline = FALSE;&lt;br /&gt;
&lt;br /&gt;
// Fetch or Send notecard&lt;br /&gt;
&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Names&lt;br /&gt;
&lt;br /&gt;
list    AddressBookList=[];&lt;br /&gt;
list    MailAddressList=[];&lt;br /&gt;
&lt;br /&gt;
string  STRING_HOME=&amp;quot;HOME&amp;quot;;&lt;br /&gt;
string  STRING_SELF=&amp;quot;SELF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Groups&lt;br /&gt;
&lt;br /&gt;
list   GroupList=[];&lt;br /&gt;
list   GroupNameList=[];&lt;br /&gt;
&lt;br /&gt;
string LSL_DOMAIN = &amp;quot;lsl.secondlife.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Read Address Book notecard&lt;br /&gt;
&lt;br /&gt;
string  ADDRESSBOOK_NOTECARD=&amp;quot;Address Book&amp;quot;;&lt;br /&gt;
integer Line=0;&lt;br /&gt;
key     reqAddressBook=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
integer Section=0;&lt;br /&gt;
integer SECTION_ADDRESS_BOOK=1;&lt;br /&gt;
integer SECTION_GROUP=2;&lt;br /&gt;
string  STRING_ADDRESS_BOOK=&amp;quot;ADDRESS BOOK&amp;quot;;&lt;br /&gt;
string  STRING_GROUP=&amp;quot;GROUP&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Links messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
integer MSG_MESSAGE_NOTIFY              = 90900;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED            = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR            = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// GetSelfAddress() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
string GetSelfAddress()&lt;br /&gt;
{&lt;br /&gt;
    return (string)llGetKey() + &amp;quot;@&amp;quot; + LSL_DOMAIN;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Info() /////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Info()&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;The mail address for this object is: &amp;quot; &lt;br /&gt;
                    + GetSelfAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// IsValidKeyFormat() //////////////////////&lt;br /&gt;
&lt;br /&gt;
integer IsValidKeyFormat(string str)&lt;br /&gt;
{&lt;br /&gt;
    string keychars = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    if (llStringLength(str) != 36)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    if( (llGetSubString( str, 8, 8 )   != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 13, 13 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 18, 18 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 23, 23 )  != &amp;quot;-&amp;quot; ) )&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 9; i &amp;lt; 13; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 14; i &amp;lt; 18; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 19; i &amp;lt; 23; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 24; i &amp;lt; 36; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// ValidMailAddress() ////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer ValidMailAddress(string arg)&lt;br /&gt;
{&lt;br /&gt;
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));&lt;br /&gt;
    &lt;br /&gt;
    if (adress == &amp;quot;&amp;quot;)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    list parse = llParseStringKeepNulls(adress, [ &amp;quot;@&amp;quot; ], []);&lt;br /&gt;
    string account = llList2String(parse,0);&lt;br /&gt;
    string domain  = llList2String(parse,1);&lt;br /&gt;
    &lt;br /&gt;
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    &lt;br /&gt;
    if (domain == LSL_DOMAIN)&lt;br /&gt;
    {&lt;br /&gt;
        return IsValidKeyFormat(account);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list parsedomain = llParseString2List(domain, [ &amp;quot;.&amp;quot; ], []);&lt;br /&gt;
    &lt;br /&gt;
        if (llGetListLength(parsedomain) &amp;lt; 2)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        &lt;br /&gt;
        integer num = llGetListLength(parsedomain);&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llStringLength(llList2String(parsedomain,i)) &amp;lt; 2)&lt;br /&gt;
            {&lt;br /&gt;
                return FALSE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetAddressStr() ///////////////////&lt;br /&gt;
&lt;br /&gt;
string GetAndCheckAddressStr(string address)&lt;br /&gt;
{&lt;br /&gt;
    list addresslist = llCSV2List(address);&lt;br /&gt;
    integer num=llGetListLength(addresslist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    string addressstr=&amp;quot;&amp;quot;;&lt;br /&gt;
    string curaddress=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        curaddress=llList2String(addresslist,i);&lt;br /&gt;
        &lt;br /&gt;
        if (ValidMailAddress(curaddress))&lt;br /&gt;
        {&lt;br /&gt;
            addressstr = (addressstr=&amp;quot;&amp;quot;) + addressstr + curaddress + &amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address string: &#039;&amp;quot; &lt;br /&gt;
                            + curaddress + &amp;quot;&#039;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return llGetSubString(addressstr, 0, -2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ProcessLine() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
ProcessLine(string rawline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(rawline,STRING_TRIM);&lt;br /&gt;
    string first=llGetSubString(line,0,0);&lt;br /&gt;
    string last=llGetSubString(line,-1,-1);&lt;br /&gt;
    &lt;br /&gt;
    // Ignore a blank line or comment line&lt;br /&gt;
    if (line == &amp;quot;&amp;quot; || first == &amp;quot;#&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // Check for the right section&lt;br /&gt;
    &lt;br /&gt;
    if (first == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; last == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        string sectionstr=llToUpper(llStringTrim(llGetSubString(line,1,-2),STRING_TRIM));&lt;br /&gt;
        &lt;br /&gt;
        if (sectionstr == STRING_ADDRESS_BOOK)&lt;br /&gt;
        {&lt;br /&gt;
            Section = SECTION_ADDRESS_BOOK;&lt;br /&gt;
        }&lt;br /&gt;
        else if (sectionstr == STRING_GROUP)&lt;br /&gt;
        {&lt;br /&gt;
            if (Section == 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                        + &amp;quot;. Group section defined before Address Book section.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Section = SECTION_GROUP;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid section header &#039;&amp;quot; + sectionstr &lt;br /&gt;
                        + &amp;quot;&#039; in &amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Must be in a section&lt;br /&gt;
    &lt;br /&gt;
    if (Section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;. No section header.&amp;quot;, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    list     parse=llParseString2List(line, [ &amp;quot;=&amp;quot; ], []);&lt;br /&gt;
    integer  num=llGetListLength(parse);&lt;br /&gt;
    &lt;br /&gt;
    // Format must be correct&lt;br /&gt;
    &lt;br /&gt;
    if (num != 2)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; +  (string)(Line+1) + &amp;quot;:\n&amp;quot; + rawline, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (Section == SECTION_ADDRESS_BOOK)&lt;br /&gt;
    {&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(name) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + name &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ name ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            string address=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
            string addressstr=GetAndCheckAddressStr(address);&lt;br /&gt;
            &lt;br /&gt;
            if (addressstr != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                AddressBookList     = (AddressBookList=[])     + AddressBookList     + [ name ];&lt;br /&gt;
                MailAddressList     = (MailAddressList=[])     + MailAddressList     + [ addressstr ];&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;No valid mail address for &#039;&amp;quot; + name &lt;br /&gt;
                    + &amp;quot;&#039;. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                    + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name &lt;br /&gt;
                + &amp;quot;&#039; already defined. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // Group&lt;br /&gt;
    {&lt;br /&gt;
        string group=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(group) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + group &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ group ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(GroupList, [ group ]) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                string names=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
                list   namelist=llCSV2List(names);&lt;br /&gt;
                integer num=llGetListLength(namelist);&lt;br /&gt;
                integer i;&lt;br /&gt;
                integer index;&lt;br /&gt;
                string  name;&lt;br /&gt;
                string  namestr=&amp;quot;&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
                for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                    name=llList2String(namelist,i);&lt;br /&gt;
                    index=llListFindList(AddressBookList, [ name ]);&lt;br /&gt;
            &lt;br /&gt;
                    if (index == -1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name + &amp;quot;&#039; defined in Group &#039;&amp;quot; &lt;br /&gt;
                                + group + &amp;quot;&#039; not found in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY); &lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        namestr = (namestr=&amp;quot;&amp;quot;) + namestr + name + &amp;quot;,&amp;quot;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (namestr != &amp;quot;&amp;quot;)&lt;br /&gt;
                {    &lt;br /&gt;
                    namestr=llGetSubString(namestr,0,-2);&lt;br /&gt;
                    GroupList         = (GroupList=[])         + GroupList     + [ group ];&lt;br /&gt;
                    GroupNameList     = (GroupNameList=[])    + GroupNameList + [ namestr ];&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                        + &amp;quot;&#039; has no valid names. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                        + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                    + &amp;quot;&#039; already defined in Group. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                    + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group&lt;br /&gt;
                + &amp;quot;&#039; already defined in Address Book. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// GetGroupAddressList ///////////////&lt;br /&gt;
&lt;br /&gt;
string GetGroupAddressList(string group)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(GroupList, [ group ]);&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(GroupList);&lt;br /&gt;
    string  grouplist=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        for (i = index; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2String(GroupList,i) == group)&lt;br /&gt;
            {&lt;br /&gt;
                grouplist = (grouplist=&amp;quot;&amp;quot;) + grouplist + llList2String(GroupNameList,i) + &amp;quot;,&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (grouplist != &amp;quot;&amp;quot;) grouplist=llGetSubString(grouplist,0,-2);   // remove last &amp;quot;,&amp;quot;&lt;br /&gt;
        return grouplist;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// SetMailAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetMailAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ address ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        index=llListFindList(GroupList, [ address ]);&lt;br /&gt;
        &lt;br /&gt;
        if (index == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llToUpper(address) == STRING_SELF)&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = GetSelfAddress();&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if(ValidMailAddress(address))&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = address;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Mail adress &amp;quot; + address &lt;br /&gt;
                            + &amp;quot; : not found in adress book or invalid format.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailAddress = GetGroupAddressList(address);&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        CurrentMailAddress = llList2String(MailAddressList,index);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                        + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string message)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No mail address defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No subject defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list mailaddresslist=llCSV2List(CurrentMailAddress);&lt;br /&gt;
        integer num=llGetListLength(mailaddresslist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(mailaddresslist,i);&lt;br /&gt;
            llEmail(address, CurrentMailSubject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMailHome() ////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMailHome(string message, string subject)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, STRING_HOME &lt;br /&gt;
                + &amp;quot; not set. Set your home adress with @HOME &amp;lt;address&amp;gt;.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        string homeaddress=llList2String(AddressBookList,index);&lt;br /&gt;
        list   homelist=llCSV2List(homeaddress);&lt;br /&gt;
        integer num=llGetListLength(homelist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(homelist,i);&lt;br /&gt;
            llEmail(address, subject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
string GetHomeAddress()&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;not set&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2String(MailAddressList,index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetHomeAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        AddressBookList     = (AddressBookList=[]) + [ STRING_HOME ] + AddressBookList;&lt;br /&gt;
        MailAddressList     = (MailAddressList=[]) + [ GetAndCheckAddressStr(address) ]  + MailAddressList;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MailAddressList = llListReplaceList(MailAddressList, [ GetAndCheckAddressStr(address) ], index, index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        Line=0;&lt;br /&gt;
        Section=0;&lt;br /&gt;
        llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// dataserver() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqAddressBook)&lt;br /&gt;
        {&lt;br /&gt;
            reqAddressBook = NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                ProcessLine(data);&lt;br /&gt;
                reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Address Book loaded.&amp;quot;, NULL_KEY);&lt;br /&gt;
                state running;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// timer() ///////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_ERROR, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Could not read Address Book: &amp;quot; &lt;br /&gt;
                            + ADDRESSBOOK_NOTECARD + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// link_message() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_MESSAGE_GETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is empty.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailSubject = message;&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is empty.&amp;quot;, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            SetMailAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Body of message to send is empty. &amp;quot; &lt;br /&gt;
                                +  &amp;quot;No mail is send.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SENDHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SendMailHome(message, (string)id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetInventoryType(message) == INVENTORY_NOTECARD)&lt;br /&gt;
            {&lt;br /&gt;
                Notecard2Fetch = message;                &lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_READ, message, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + message + &amp;quot; not found.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_NOTECARD_FETCHED)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + Notecard2Fetch &lt;br /&gt;
                            + &amp;quot; was empty or could not be read.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Home address is: &amp;quot; + GetHomeAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SetHomeAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_INFO)&lt;br /&gt;
        {&lt;br /&gt;
            Info();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
// End SL Mail AddressBook V1.2.lsl&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail FetchNotecard V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch the contents of a notecard and return it via link message as a string.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Notecard&lt;br /&gt;
&lt;br /&gt;
integer Line=0;&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
key     reqNotecard=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=10.0;&lt;br /&gt;
integer Fetched=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Lines&lt;br /&gt;
&lt;br /&gt;
list LineList=[];&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    /////////////////////// dataserver() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqNotecard)&lt;br /&gt;
        {&lt;br /&gt;
            reqNotecard=NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                LineList = (LineList=[]) + LineList + [ data ];&lt;br /&gt;
                reqNotecard = llGetNotecardLine(Notecard2Fetch, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Fetched=TRUE;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, llDumpList2String(LineList, &amp;quot;\n&amp;quot;), NULL_KEY);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /////////////////////// timer() ///////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        if (!Fetched)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            llSetTimerEvent(0.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer send, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_NOTECARD_READ)&lt;br /&gt;
        {&lt;br /&gt;
            Line=0;&lt;br /&gt;
            Notecard2Fetch=message;&lt;br /&gt;
            LineList=[];&lt;br /&gt;
            Fetched=FALSE;&lt;br /&gt;
            reqNotecard=llGetNotecardLine(Notecard2Fetch, Line);&lt;br /&gt;
            llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL OnlineStatus V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch online status of owner.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Online status&lt;br /&gt;
&lt;br /&gt;
key     reqOnlineStatus=NULL_KEY;&lt;br /&gt;
float   STATUS_INTERVAL=2.0;&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_STATUS_ONLINE       = 30000;&lt;br /&gt;
integer MS_STATUS_OFFLINE       = 30100;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus=llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
        llSetTimerEvent(STATUS_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// dataserver() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqOnlineStatus)&lt;br /&gt;
        {&lt;br /&gt;
            reqOnlineStatus = NULL_KEY;&lt;br /&gt;
        &lt;br /&gt;
            if (data==&amp;quot;1&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_STATUS_ONLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if (data==&amp;quot;0&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MS_STATUS_OFFLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus = llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Help V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Display help information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail Help V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP    = 10000;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Help() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Help()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;HELP for SL Mail V1.2.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;COMMANDS:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HELP               - displays help info.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@INFO               - display mailaddress of this object.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RECORD             - start recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CONTINUE           - continue recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@STOP               - stop recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@IGNORE             - ignore the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SHOW               - show what your recorded.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SEND               - send the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@MAIL &amp;lt;mailadress&amp;gt;  - set the mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SUBJECT subject    - set the mail subject.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LIST               - list messages in mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SELECT &amp;lt;message&amp;gt;   - select message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@READ               - read current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@NEXT               - read next message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@PREV               - read previous message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@FIRST              - read first message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LAST               - read last message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@DELETE             - delete current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CLEAR              - clear the mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@REPLY              - reply to current message.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RESET              - reset the script.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HOME               - set the home mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@OFF                - switch mailbox OFF.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@ON                 - switch mailbox ON.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_HELP)&lt;br /&gt;
        {&lt;br /&gt;
            Help();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail Help V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}&lt;/div&gt;</description>
			<pubDate>Wed, 09 Feb 2011 23:16:24 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:SL_Mail_V1.2</comments>
		</item>
		<item>
			<title>SL Mail V1.2</title>
			<link>https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=1133908</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=1133908</guid>
			<description>&lt;p&gt;Flennan Roffo: /* LICENCE INFO */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}} __NOTOC__&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=&#039;&#039;&#039;Second Life mail client&#039;&#039;&#039;=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Send and receive email from within Second Life from and to any address.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implemented with Address Book function (in a notecard named &#039;Address Book&#039;) to stores addresses by name  and to compile groups of named addresses. Current version is stand-alone (no server functionality) and uses chat commands only.&lt;br /&gt;
&lt;br /&gt;
[[Image:BannerSLMail.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.slmail.info slmail.info] &amp;lt;strike&amp;gt;(website coming soon!)&amp;lt;/strike&amp;gt; &amp;lt;b&amp;gt;url slmail.info no longer used for SL Mail, and was taken for some other purpose.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Release Notes V1.2=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 Release notes (edition 2, 4 sept 2007)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LICENCE INFO&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
This program is free software: you can redistribute it and/or modify&lt;br /&gt;
it under the terms of the GNU General Public License as published by&lt;br /&gt;
the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
(at your option) any later version.&lt;br /&gt;
&lt;br /&gt;
This program is distributed in the hope that it will be useful,&lt;br /&gt;
but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
GNU General Public License for more details.&lt;br /&gt;
&lt;br /&gt;
You should have received a copy of the GNU General Public License&lt;br /&gt;
along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;PRODUCTION &amp;amp; MAINTANENCE&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
by Logic Scripted Products and Script Services&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.logicscripts.org logicscripts.org] (website coming soon!)&lt;br /&gt;
&lt;br /&gt;
SLurl:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Contact: [[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
&lt;br /&gt;
Email: [mailto:info@slmail.info &#039;&#039;&#039;info&#039;&#039;&#039;] or [mailto:Flennan.Roffo@slmail.info &#039;&#039;&#039;Flennan Roffo&#039;&#039;&#039;]&lt;br /&gt;
&#039;&#039;&#039;* The slmail.info URL appears to not be registered and this information appears to be out of date. *&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;DESCRIPTION&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is a simple tool to send and receive mail from within SL.&lt;br /&gt;
You can either compose a message yourself using chat recording, or choose a notecard from inventory to send. The Address Book functionality allows you to use short names for mail recipients stored in a notecard. The current version does not have a persisent mail address. Watch out for the upcoming next release (V1.3) which will facilitate persisent in-world mail addresses and will be enhanced with many new features (See: Requests For Change (RFC).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;COMMANDS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Help&#039;&#039;&#039;&lt;br /&gt;
||Show Help about available commands&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Record&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording (for owner only).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Stop&#039;&#039;&#039;&lt;br /&gt;
||Stops the chat recording without sending&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Continue&#039;&#039;&#039;&lt;br /&gt;
||Continues a previously stopped chat recording. Lines will be appended to you recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Show&#039;&#039;&#039;&lt;br /&gt;
||Shows the content of the recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send&#039;&#039;&#039;&lt;br /&gt;
||If recording, stops the recording, and sends the mail (need to supply mail address and subject first!)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send &amp;lt;notecard&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Sends the content of the notecard, instead of the chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Ignore&#039;&#039;&#039;&lt;br /&gt;
||Ignores your current chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject &amp;lt;subject&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the subject of the mail.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail subject.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Set the HOME address of the owner (mail will be forwarder to this address when offline).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home&#039;&#039;&#039;&lt;br /&gt;
||Show the HOME address.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Info&#039;&#039;&#039;&lt;br /&gt;
||Shows the mail address the object this script is running in uses (e.g. &amp;lt;object-key&amp;gt;@lsl.secondlife.com).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Read&#039;&#039;&#039;&lt;br /&gt;
||Reads the current message from the mail buffer (the mail buffer gets filled with mail you receive)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Select &amp;lt;msg&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Select a message number from the availabe messages in the mail buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Next&#039;&#039;&#039;&lt;br /&gt;
||Make next message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Prev&#039;&#039;&#039;&lt;br /&gt;
||Make previous message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@First&#039;&#039;&#039;&lt;br /&gt;
||Make the first message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Last&#039;&#039;&#039;&lt;br /&gt;
||Make the last message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Clear&#039;&#039;&#039;&lt;br /&gt;
||Clear the mail buffer&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Delete&#039;&#039;&#039;&lt;br /&gt;
||Deletes only the current message&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Reply&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording to reply to the current message. Mail adress and subject are filled in automatically.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* Commands are case insensitive (&amp;quot;@read&amp;quot; == &amp;quot;@READ&amp;quot;). Arguments might not be case insensitive.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;ADDRESS BOOK FORMAT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
A notecard of the name &#039;Address Book&#039; is read during initialization which may contain Address Book items and Groups.&lt;br /&gt;
The notecard is split in two sections, which need to be defined in that particular order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[ADDRESS BOOK]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Defines the section in which you can put names for mail addresses,  like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name1=account@thisdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name2=user@otherdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[GROUP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define groups of previously defined names under a new name, like for instance:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyGroup=Name1, Name2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note that names of groups and individual mail adresses share the same namespace and must be unique.&lt;br /&gt;
&lt;br /&gt;
So when you filled in your mail adresses in the Address Book, you can now use:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail Name1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to  &amp;lt;account@thisdomain.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail MyGroup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to &amp;lt;account@thisdomain.com&amp;gt; and &amp;lt;user@otherdomain.com&amp;gt;&lt;br /&gt;
Mails will be sent one after another.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* Names for Addreses and Groups are case insensitive (e.g. &amp;quot;mary&amp;quot;  == &amp;quot;MARY&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* The special address &#039;Self&#039; can be used in commands where otherwise an address specification can be used. &#039;Self&#039; is case insensitive (e.g. &amp;quot;self&amp;quot; == &amp;quot;SELF&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LIMITATIONS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
The current version is limited by the following:&lt;br /&gt;
&lt;br /&gt;
* Chat recording lines are limited by the 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Output of lines from the mail buffer are also limited by this 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Incoming mail is limited to a 1000 (1024?) byte limit&lt;br /&gt;
&lt;br /&gt;
* Outgoing mai is limited by a 4096 byte limit, which includes the standard mail header (region/location info on the first two lines)&lt;br /&gt;
&lt;br /&gt;
We are making adjustments to this release to help overcome these limitations. At least the line lenght limit can be overcome by introducing a line continuation character (for example a hyphen &#039;-&#039;) that when used at the end of a line appends the next line, so lines longer then 255 bytes are possible then.&lt;br /&gt;
&lt;br /&gt;
To overcome the outgoing mail length limit, the mail can be broken textualy into parts, and each part can be send seperatedely, with an indication in the subject or in an introduced primary line of the mail body to indicate that the mail was split into parts.&lt;br /&gt;
For incoming mail and at least to receive mail from other SL Mail programs, a protocol will be introduced to receive mail in parts that are joined together after receiving them to form a single mail.&lt;br /&gt;
&lt;br /&gt;
These enhancements will be made available in the next release (V1.3) of SL Mail &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;BUGS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Report any bugs you find in this release to Logic (IM: Flennan Roffo).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;REQUEST FOR CHANGE (RFC)&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Do you have additional wishes for enhancement of this product?&lt;br /&gt;
Contact Flennan Roffo and we will see if they can be implemented in the next release.&lt;br /&gt;
&lt;br /&gt;
Existing RFC&#039;s are:&lt;br /&gt;
&lt;br /&gt;
* Menu support for commands.&lt;br /&gt;
&lt;br /&gt;
* Lines on incoming/outgoing mail longer than 255 bytes.&lt;br /&gt;
&lt;br /&gt;
* Send messages longer than 4096 (minus SL mail header) bytes.&lt;br /&gt;
&lt;br /&gt;
* Receive messages longer than 1024 bytes.&lt;br /&gt;
&lt;br /&gt;
* Permanent mail addresses for the SL Mail client (like: &amp;lt;Flennan.Roffo@somedomain.sl&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Add your RFC!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In-world join the group &amp;quot;SL Mail&amp;quot; for bug reports, feature requests, the latest SL Mail release, and notices about development issues.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scripts=&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==Script: SL Mail v1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail core module which scans for incoming mail messages and executes commands used by the owner.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail V1.2.lsl&lt;br /&gt;
// (c) 2007 Logic Scripted Products and Script Services&lt;br /&gt;
// Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
// VERSION&lt;br /&gt;
// Version: 1.2&lt;br /&gt;
&lt;br /&gt;
// HISTORY&lt;br /&gt;
// Date         Version     Author              Comment&lt;br /&gt;
// --------------------------------------------------------------------------------------&lt;br /&gt;
// 28 aug 2007  V 1.0       Flennan Roffo       Created&lt;br /&gt;
//&lt;br /&gt;
//  1 sep 2007  V 1.1       Flennan Roffo       @Reply empties the recording buffer.&lt;br /&gt;
//                                                @Send while recording ends recording&lt;br /&gt;
//                                                and sends the mail if a mail address&lt;br /&gt;
//                                                and subject are supplied.&lt;br /&gt;
//                                                Fixed incorrect date in Unix2DateTime.&lt;br /&gt;
//  3 sep 2007  V 1.2       Flennan Roffo       Notification options:&lt;br /&gt;
//                                              - When online, send an IM when mail is received.&lt;br /&gt;
//                                              - When offline, send to HOME mail adress.&lt;br /&gt;
//                                              Adressbook&lt;br /&gt;
//                                              - Read adress book from config notecard.&lt;br /&gt;
&lt;br /&gt;
// LICENCE&lt;br /&gt;
// This program is free software; you can redistribute it and/or&lt;br /&gt;
// modify it under the terms of the GNU General Public License&lt;br /&gt;
// as published by the Free Software Foundation; either version 2&lt;br /&gt;
// of the License, or (at your option) any later version.&lt;br /&gt;
// &lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
// &lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program; if not, write to the Free Software&lt;br /&gt;
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
// (Also available at http://www.gnu.org/copyleft/gpl.html) &lt;br /&gt;
&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// Let&#039;s you record a message and sent to email and get messages and reply to messages.&lt;br /&gt;
// Must supply a valid mail adress and non-empty subject using chat commands.&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
// 1) Check for the maximum length of an email message (including newline and header).&lt;br /&gt;
// 2) Read adress book from notecard.                                    *DONE*&lt;br /&gt;
// 3) Send incoming mail to personal mail adress when offline.            *DONE*&lt;br /&gt;
// 4) Alert with an IM when online upon receiving new mail.                *DONE*&lt;br /&gt;
&lt;br /&gt;
string   SL_MAIL_VERSION = &amp;quot;V 1.2&amp;quot;;&lt;br /&gt;
string   SL_MAIL_DATE    = &amp;quot; 2 sep 2007&amp;quot;;&lt;br /&gt;
integer  ErrorFlag         = FALSE;&lt;br /&gt;
list     ScriptList        = [ &amp;quot;SL Mail Help V1.2&amp;quot;, &amp;quot;SL Mail AddressBook V1.2&amp;quot;, &lt;br /&gt;
                                &amp;quot;SL Mail OnlineStatus V1.2&amp;quot;, &amp;quot;SL Mail FetchNotecard V1.2&amp;quot; ];    &lt;br /&gt;
string   LSL_DOMAIN=&amp;quot;lsl.secondlife.com&amp;quot;; &lt;br /&gt;
integer  StatusOnline=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Commands&lt;br /&gt;
&lt;br /&gt;
string  COMMAND_RECORD     = &amp;quot;@RECORD&amp;quot;;&lt;br /&gt;
string  COMMAND_CONTINUE   = &amp;quot;@CONTINUE&amp;quot;;&lt;br /&gt;
string  COMMAND_STOP       = &amp;quot;@STOP&amp;quot;;&lt;br /&gt;
string  COMMAND_MAIL       = &amp;quot;@MAIL&amp;quot;;&lt;br /&gt;
string  COMMAND_SUBJECT    = &amp;quot;@SUBJECT&amp;quot;;&lt;br /&gt;
string  COMMAND_SEND       = &amp;quot;@SEND&amp;quot;;&lt;br /&gt;
string  COMMAND_SEE        = &amp;quot;@SEE&amp;quot;;&lt;br /&gt;
string  COMMAND_IGNORE     = &amp;quot;@IGNORE&amp;quot;;&lt;br /&gt;
string  COMMAND_READ       = &amp;quot;@READ&amp;quot;;&lt;br /&gt;
string  COMMAND_DELETE     = &amp;quot;@DELETE&amp;quot;;&lt;br /&gt;
string  COMMAND_CLEAR      = &amp;quot;@CLEAR&amp;quot;;&lt;br /&gt;
string  COMMAND_REPLY      = &amp;quot;@REPLY&amp;quot;;&lt;br /&gt;
string  COMMAND_NEXT       = &amp;quot;@NEXT&amp;quot;;&lt;br /&gt;
string  COMMAND_PREV       = &amp;quot;@PREV&amp;quot;;&lt;br /&gt;
string  COMMAND_FIRST      = &amp;quot;@FIRST&amp;quot;;&lt;br /&gt;
string  COMMAND_LAST       = &amp;quot;@LAST&amp;quot;;&lt;br /&gt;
string  COMMAND_LIST       = &amp;quot;@LIST&amp;quot;;&lt;br /&gt;
string  COMMAND_SELECT     = &amp;quot;@SELECT&amp;quot;;&lt;br /&gt;
string  COMMAND_HELP       = &amp;quot;@HELP&amp;quot;;&lt;br /&gt;
string  COMMAND_INFO       = &amp;quot;@INFO&amp;quot;;&lt;br /&gt;
string  COMMAND_RESET      = &amp;quot;@RESET&amp;quot;;&lt;br /&gt;
string  COMMAND_SHOW       = &amp;quot;@SHOW&amp;quot;;&lt;br /&gt;
string  COMMAND_ON         = &amp;quot;@ON&amp;quot;;&lt;br /&gt;
string  COMMAND_OFF        = &amp;quot;@OFF&amp;quot;;&lt;br /&gt;
string  COMMAND_HOME       = &amp;quot;@HOME&amp;quot;;&lt;br /&gt;
string  COMMAND_LOAD       = &amp;quot;@LOAD&amp;quot;;&lt;br /&gt;
string  COMMAND_ADDRESS    = &amp;quot;@ADDRESS&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Recording&lt;br /&gt;
&lt;br /&gt;
integer Recording = FALSE;&lt;br /&gt;
&lt;br /&gt;
list    ChatRecording=[];&lt;br /&gt;
integer NumLines=0;&lt;br /&gt;
integer Length=0;&lt;br /&gt;
&lt;br /&gt;
list     TimeList=[];&lt;br /&gt;
list     AddressList=[];&lt;br /&gt;
list     SubjectList=[];&lt;br /&gt;
list     BodyList=[];&lt;br /&gt;
integer  NumMessages=0;&lt;br /&gt;
integer  CurrentMessage=-1;&lt;br /&gt;
&lt;br /&gt;
float    MAIL_FETCH_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
// Link Messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP                        = 10000;&lt;br /&gt;
integer MSG_STATUS_ONLINE               = 30000;&lt;br /&gt;
integer MSG_STATUS_OFFLINE              = 30100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED          = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR           = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Unix Time conversion //////////////////&lt;br /&gt;
&lt;br /&gt;
integer DAYS_PER_YEAR        = 365;                // Non leap year&lt;br /&gt;
integer SECONDS_PER_YEAR     = 31536000;          // Non leap year&lt;br /&gt;
integer SECONDS_PER_DAY      = 86400;&lt;br /&gt;
integer SECONDS_PER_HOUR     = 3600;&lt;br /&gt;
integer SECONDS_PER_MINUTE   = 60;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// LeapYear() /////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer LeapYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (year % 4 == 0)&lt;br /&gt;
    {&lt;br /&gt;
        if (year % 100 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (year % 400 == 0)&lt;br /&gt;
            {&lt;br /&gt;
                return 1;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// DaysPerMonth() ///////////////////////////////////////&lt;br /&gt;
                &lt;br /&gt;
integer DaysPerMonth(integer year,integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;lt; 8)&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (month == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if (LeapYear(year))&lt;br /&gt;
                {&lt;br /&gt;
                    return 29;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    return 28;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 30;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 30;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////// DaysPerYear() ////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DaysPerYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (LeapYear(year))&lt;br /&gt;
        return DAYS_PER_YEAR + 1;&lt;br /&gt;
    else&lt;br /&gt;
        return DAYS_PER_YEAR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Unix2DataTime() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list Unix2DateTime(integer unixtime)&lt;br /&gt;
{&lt;br /&gt;
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;&lt;br /&gt;
    integer day = days_since_1_1_1970 + 1;&lt;br /&gt;
    integer year  = 1970;&lt;br /&gt;
    integer days_per_year = DaysPerYear(year);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_year)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_year;&lt;br /&gt;
        ++year;&lt;br /&gt;
        days_per_year = DaysPerYear(year);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer month = 1;&lt;br /&gt;
    integer days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_month)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_month;&lt;br /&gt;
        &lt;br /&gt;
        if (++month &amp;gt; 12)&lt;br /&gt;
        {    &lt;br /&gt;
            ++year;&lt;br /&gt;
            month = 1;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;&lt;br /&gt;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;&lt;br /&gt;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;&lt;br /&gt;
    integer minute      = second / SECONDS_PER_MINUTE;&lt;br /&gt;
    second               = second % SECONDS_PER_MINUTE;&lt;br /&gt;
    &lt;br /&gt;
    return [ year, month, day, hour, minute, second ];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// MonthName() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list MonthNameList = [     &amp;quot;JAN&amp;quot;, &amp;quot;FEB&amp;quot;, &amp;quot;MAR&amp;quot;, &amp;quot;APR&amp;quot;, &amp;quot;MAY&amp;quot;, &amp;quot;JUN&amp;quot;, &lt;br /&gt;
                        &amp;quot;JUL&amp;quot;, &amp;quot;AUG&amp;quot;, &amp;quot;SEP&amp;quot;, &amp;quot;OCT&amp;quot; , &amp;quot;NOV&amp;quot;, &amp;quot;DEC&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
string MonthName(integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;gt;= 0 &amp;amp;&amp;amp; month &amp;lt; 12)&lt;br /&gt;
        return llList2String(MonthNameList, month);&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// DateString() ///////////////////////////&lt;br /&gt;
&lt;br /&gt;
string DateString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer year       = llList2Integer(timelist,0);&lt;br /&gt;
    integer month      = llList2Integer(timelist,1);&lt;br /&gt;
    integer day        = llList2Integer(timelist,2);&lt;br /&gt;
    &lt;br /&gt;
    return (string)day + &amp;quot;-&amp;quot; + MonthName(month - 1) + &amp;quot;-&amp;quot; + (string)year;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// TimeString() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string TimeString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer hour          = llList2Integer(timelist,3);&lt;br /&gt;
    integer minute         = llList2Integer(timelist,4);&lt;br /&gt;
    integer second         = llList2Integer(timelist,5);&lt;br /&gt;
    string  hourstr     = (string)hour;&lt;br /&gt;
    string  minutestr   = (string)minute;&lt;br /&gt;
    string  secondstr   = (string)second;&lt;br /&gt;
    &lt;br /&gt;
    if (hour &amp;lt; 10)         hourstr     = &amp;quot;0&amp;quot; + hourstr;&lt;br /&gt;
    if (minute &amp;lt; 10)     minutestr     = &amp;quot;0&amp;quot; + minutestr;&lt;br /&gt;
    if (second &amp;lt; 10)    secondstr    = &amp;quot;0&amp;quot; + secondstr;&lt;br /&gt;
    return hourstr + &amp;quot;:&amp;quot; + minutestr + &amp;quot;:&amp;quot; + secondstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() /////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string body)&lt;br /&gt;
{&lt;br /&gt;
    // llOwnerSay(&amp;quot;Sending message to &#039;&amp;quot; + address + &amp;quot;&#039; with subject &#039;&amp;quot; + subject +&amp;quot;&#039;.&amp;quot;);&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND, body, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// SendHome() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendHome(string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SENDHOME, body, (key)subject);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Show() ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Show()&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;Current chat recording is:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; NumLines; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(ChatRecording,i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;Lines is &amp;quot; + (string)NumLines);&lt;br /&gt;
    llOwnerSay(&amp;quot;Message length is &amp;quot; + (string)Length);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Read() /////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Read()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;Reading message &amp;quot; + (string)CurrentMessage + &amp;quot; from mail buffer.&amp;quot;);&lt;br /&gt;
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);&lt;br /&gt;
    list timelist=Unix2DateTime(time);&lt;br /&gt;
    string Address = llList2String(AddressList,CurrentMessage);&lt;br /&gt;
    string Subject = llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
    string Body    = llList2String(BodyList,CurrentMessage);&lt;br /&gt;
    llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Address: &amp;quot; + Address);&lt;br /&gt;
    llOwnerSay(&amp;quot;Subject: &amp;quot; + Subject);&lt;br /&gt;
    llOwnerSay(&amp;quot;Begin of message body:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    list bodylist=llParseStringKeepNulls(Body, [ &amp;quot;\n&amp;quot; ], []);&lt;br /&gt;
    integer num=llGetListLength(bodylist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(bodylist,i));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;End of message body.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////// List ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
List()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;The mail buffer contains the following messages:\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; NumMessages; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer time=llList2Integer(TimeList,i);&lt;br /&gt;
        list timelist=Unix2DateTime(time);&lt;br /&gt;
        if (i &amp;gt; 0) llOwnerSay(&amp;quot;+-+-+-+-+-+-+-+-+-+-+-+-&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Message: &amp;quot; + (string)i);&lt;br /&gt;
        llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;From:    &amp;quot; + llList2String(AddressList,i));&lt;br /&gt;
        llOwnerSay(&amp;quot;Subject: &amp;quot; + llList2String(SubjectList,i));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////// NotifyNewMail() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
NotifyNewMail(string time, string address, string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    list timelist=Unix2DateTime((integer)time);&lt;br /&gt;
&lt;br /&gt;
    if (StatusOnline)&lt;br /&gt;
    {&lt;br /&gt;
        llInstantMessage(llGetOwner(), &amp;quot;You received a new mail message on &amp;quot; &lt;br /&gt;
                                    + DateString(timelist) + &amp;quot; at &amp;quot; + TimeString(timelist)&lt;br /&gt;
                                    + &amp;quot; from &amp;quot; + address &lt;br /&gt;
                                    + &amp;quot; with the subject &amp;quot; + subject);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        SendHome(&amp;quot;FW: &amp;quot; + subject, &amp;quot;Received at: &amp;quot; + DateString(timelist) + &amp;quot; &amp;quot; + TimeString(timelist) + &amp;quot;\nFrom: &amp;quot; +  address &lt;br /&gt;
                    + &amp;quot;\nBegin message body:\n-------------------\n&amp;quot; + body + &amp;quot;\n-------------------\nEnd message body.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ResetOtherScripts() //////////////////////&lt;br /&gt;
&lt;br /&gt;
ResetOtherScripts()&lt;br /&gt;
{&lt;br /&gt;
    string     name;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(ScriptList);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        name = llList2String(ScriptList,i);&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(name) == INVENTORY_SCRIPT)&lt;br /&gt;
        {&lt;br /&gt;
            llResetOtherScript(name);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Error - script &#039;&amp;quot; + name + &amp;quot;&#039; not found.&amp;quot;);&lt;br /&gt;
            ErrorFlag = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
// default &lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ////////////////////// state_entry() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Welcome to SL Mail, released under GNU software licence.&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Version &amp;quot; + SL_MAIL_VERSION + &amp;quot; &amp;quot; + SL_MAIL_DATE);&lt;br /&gt;
        llOwnerSay(&amp;quot;Produced by Logic Scripted Products &amp;amp; Product Services&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Free memory: &amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
        ResetOtherScripts();&lt;br /&gt;
        &lt;br /&gt;
        if (ErrorFlag)&lt;br /&gt;
            state Error;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// on_rez() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// changed() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_LOADED)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_ERROR)&lt;br /&gt;
        {&lt;br /&gt;
            state Error;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() //////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(MAIL_FETCH_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //////////////////////// on_rez() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// listen() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string trimmessage=llStringTrim(message,STRING_TRIM);&lt;br /&gt;
        list   parse = llParseStringKeepNulls(trimmessage, [ &amp;quot; &amp;quot;], []);&lt;br /&gt;
        string command = llToUpper(llList2String(parse,0));&lt;br /&gt;
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        integer nargs  = llGetListLength(parse);&lt;br /&gt;
        string argstr=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (nargs &amp;gt; 1) argstr=llGetSubString(message, llSubStringIndex(message, &amp;quot; &amp;quot;) + 1, -1);&lt;br /&gt;
            &lt;br /&gt;
        if (Recording)&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Recording stopped. Type @SHOW to see the message you have entered,&amp;quot;&lt;br /&gt;
                            + &amp;quot; or @SEND to send it.&amp;quot;);&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                &lt;br /&gt;
                SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];&lt;br /&gt;
                ++NumLines;&lt;br /&gt;
                Length += llStringLength(message) + 2;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_RECORD)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Start recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                ChatRecording = [];&lt;br /&gt;
                NumLines=0;&lt;br /&gt;
                Length=0;&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CONTINUE)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Continue recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_REPLY)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    string address=llList2String(AddressList,CurrentMessage);&lt;br /&gt;
                    string subject=&amp;quot;Re: &amp;quot; + llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, address, NULL_KEY);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, subject, NULL_KEY);&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines=0;&lt;br /&gt;
                    Length=0;&lt;br /&gt;
                    Recording = TRUE;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_MAIL)&lt;br /&gt;
            {&lt;br /&gt;
                string mailaddress=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailaddress != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, mailaddress, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETADDRESS, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SUBJECT)&lt;br /&gt;
            {&lt;br /&gt;
                string mailsubject=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailsubject != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, mailsubject, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETSUBJECT, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Not recording.&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    if (NumLines == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND_NOTECARD, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_IGNORE)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines = 0;&lt;br /&gt;
                    Length = 0;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Show();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_READ)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumMessages == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Read();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        ++CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        --CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_FIRST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = 0;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LAST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LIST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    List();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SELECT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;Need to supply a message number.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    integer msgnum = (integer)arg;&lt;br /&gt;
                     &lt;br /&gt;
                    if (msgnum &amp;lt; 0 || msgnum &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Message number &amp;quot; + arg + &amp;quot; not in mail buffer.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = msgnum;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_DELETE)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    --NumMessages;&lt;br /&gt;
                     &lt;br /&gt;
                    if (NumMessages == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = -1;&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (CurrentMessage &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CLEAR)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList=[];&lt;br /&gt;
                    AddressList=[];&lt;br /&gt;
                    SubjectList=[];&lt;br /&gt;
                    BodyList=[];&lt;br /&gt;
                    NumMessages=0;&lt;br /&gt;
                    CurrentMessage=-1;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_HELP, arg, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_INFO)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                Show();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_RESET)&lt;br /&gt;
            {&lt;br /&gt;
                llResetScript();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                state not_running;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HOME)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs==1)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETHOME, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETHOME, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// email() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    email(string time, string address, string subject, string body, integer queued)&lt;br /&gt;
    {&lt;br /&gt;
        NotifyNewMail(time, address, subject, body);&lt;br /&gt;
        TimeList = (TimeList=[]) + TimeList + [time];&lt;br /&gt;
        AddressList = (AddressList=[]) + AddressList + [address];&lt;br /&gt;
        SubjectList = (SubjectList=[]) + SubjectList + [subject];&lt;br /&gt;
        BodyList = (BodyList=[]) + BodyList + [body];&lt;br /&gt;
        ++NumMessages;&lt;br /&gt;
        &lt;br /&gt;
        if (CurrentMessage == -1)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = NumMessages - 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_REPLY)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state not_running&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state not_running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;SL Mailbox switched OFF. Say @ON to switch it back on.&amp;quot;);&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// on_rez() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// listen() ////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer chan, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string command=llToUpper(message);&lt;br /&gt;
        &lt;br /&gt;
        if (command == COMMAND_ON)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state Error&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state Error&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Error in SL Mail: not all component scripts found.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// End SL Mail V1.2.lsl&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Address Book V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Read and interpret the contents of the Address Book.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail AddressBook V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// &lt;br /&gt;
//  Read the Address Book from a notecard named &amp;quot;Address Book&amp;quot;.&lt;br /&gt;
//&lt;br /&gt;
//  The Address Book has the following format:&lt;br /&gt;
//  &lt;br /&gt;
//  [ADDRESS BOOK]&lt;br /&gt;
//  Name1=username@yourdomain.com&lt;br /&gt;
//  Name2=otheruser@otherdomain.com&lt;br /&gt;
//  ...&lt;br /&gt;
//  [GROUP]&lt;br /&gt;
//  group1=Name1, Name2&lt;br /&gt;
//  ...&lt;br /&gt;
//&lt;br /&gt;
//  Notes:&lt;br /&gt;
//  1. Group and Name share the same namespace, and must be unique.&lt;br /&gt;
//  2. It is allowed to have a name in the addressbook with multiple addresses, seperated by comma&#039;s.&lt;br /&gt;
// &lt;br /&gt;
/////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string  CurrentMailAddress = &amp;quot;&amp;quot;;&lt;br /&gt;
string  CurrentMailSubject = &amp;quot;&amp;quot;;&lt;br /&gt;
integer StatusOnline = FALSE;&lt;br /&gt;
&lt;br /&gt;
// Fetch or Send notecard&lt;br /&gt;
&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Names&lt;br /&gt;
&lt;br /&gt;
list    AddressBookList=[];&lt;br /&gt;
list    MailAddressList=[];&lt;br /&gt;
&lt;br /&gt;
string  STRING_HOME=&amp;quot;HOME&amp;quot;;&lt;br /&gt;
string  STRING_SELF=&amp;quot;SELF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Groups&lt;br /&gt;
&lt;br /&gt;
list   GroupList=[];&lt;br /&gt;
list   GroupNameList=[];&lt;br /&gt;
&lt;br /&gt;
string LSL_DOMAIN = &amp;quot;lsl.secondlife.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Read Address Book notecard&lt;br /&gt;
&lt;br /&gt;
string  ADDRESSBOOK_NOTECARD=&amp;quot;Address Book&amp;quot;;&lt;br /&gt;
integer Line=0;&lt;br /&gt;
key     reqAddressBook=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
integer Section=0;&lt;br /&gt;
integer SECTION_ADDRESS_BOOK=1;&lt;br /&gt;
integer SECTION_GROUP=2;&lt;br /&gt;
string  STRING_ADDRESS_BOOK=&amp;quot;ADDRESS BOOK&amp;quot;;&lt;br /&gt;
string  STRING_GROUP=&amp;quot;GROUP&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Links messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
integer MSG_MESSAGE_NOTIFY              = 90900;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED            = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR            = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// GetSelfAddress() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
string GetSelfAddress()&lt;br /&gt;
{&lt;br /&gt;
    return (string)llGetKey() + &amp;quot;@&amp;quot; + LSL_DOMAIN;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Info() /////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Info()&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;The mail address for this object is: &amp;quot; &lt;br /&gt;
                    + GetSelfAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// IsValidKeyFormat() //////////////////////&lt;br /&gt;
&lt;br /&gt;
integer IsValidKeyFormat(string str)&lt;br /&gt;
{&lt;br /&gt;
    string keychars = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    if (llStringLength(str) != 36)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    if( (llGetSubString( str, 8, 8 )   != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 13, 13 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 18, 18 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 23, 23 )  != &amp;quot;-&amp;quot; ) )&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 9; i &amp;lt; 13; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 14; i &amp;lt; 18; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 19; i &amp;lt; 23; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 24; i &amp;lt; 36; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// ValidMailAddress() ////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer ValidMailAddress(string arg)&lt;br /&gt;
{&lt;br /&gt;
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));&lt;br /&gt;
    &lt;br /&gt;
    if (adress == &amp;quot;&amp;quot;)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    list parse = llParseStringKeepNulls(adress, [ &amp;quot;@&amp;quot; ], []);&lt;br /&gt;
    string account = llList2String(parse,0);&lt;br /&gt;
    string domain  = llList2String(parse,1);&lt;br /&gt;
    &lt;br /&gt;
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    &lt;br /&gt;
    if (domain == LSL_DOMAIN)&lt;br /&gt;
    {&lt;br /&gt;
        return IsValidKeyFormat(account);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list parsedomain = llParseString2List(domain, [ &amp;quot;.&amp;quot; ], []);&lt;br /&gt;
    &lt;br /&gt;
        if (llGetListLength(parsedomain) &amp;lt; 2)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        &lt;br /&gt;
        integer num = llGetListLength(parsedomain);&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llStringLength(llList2String(parsedomain,i)) &amp;lt; 2)&lt;br /&gt;
            {&lt;br /&gt;
                return FALSE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetAddressStr() ///////////////////&lt;br /&gt;
&lt;br /&gt;
string GetAndCheckAddressStr(string address)&lt;br /&gt;
{&lt;br /&gt;
    list addresslist = llCSV2List(address);&lt;br /&gt;
    integer num=llGetListLength(addresslist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    string addressstr=&amp;quot;&amp;quot;;&lt;br /&gt;
    string curaddress=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        curaddress=llList2String(addresslist,i);&lt;br /&gt;
        &lt;br /&gt;
        if (ValidMailAddress(curaddress))&lt;br /&gt;
        {&lt;br /&gt;
            addressstr = (addressstr=&amp;quot;&amp;quot;) + addressstr + curaddress + &amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address string: &#039;&amp;quot; &lt;br /&gt;
                            + curaddress + &amp;quot;&#039;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return llGetSubString(addressstr, 0, -2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ProcessLine() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
ProcessLine(string rawline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(rawline,STRING_TRIM);&lt;br /&gt;
    string first=llGetSubString(line,0,0);&lt;br /&gt;
    string last=llGetSubString(line,-1,-1);&lt;br /&gt;
    &lt;br /&gt;
    // Ignore a blank line or comment line&lt;br /&gt;
    if (line == &amp;quot;&amp;quot; || first == &amp;quot;#&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // Check for the right section&lt;br /&gt;
    &lt;br /&gt;
    if (first == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; last == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        string sectionstr=llToUpper(llStringTrim(llGetSubString(line,1,-2),STRING_TRIM));&lt;br /&gt;
        &lt;br /&gt;
        if (sectionstr == STRING_ADDRESS_BOOK)&lt;br /&gt;
        {&lt;br /&gt;
            Section = SECTION_ADDRESS_BOOK;&lt;br /&gt;
        }&lt;br /&gt;
        else if (sectionstr == STRING_GROUP)&lt;br /&gt;
        {&lt;br /&gt;
            if (Section == 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                        + &amp;quot;. Group section defined before Address Book section.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Section = SECTION_GROUP;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid section header &#039;&amp;quot; + sectionstr &lt;br /&gt;
                        + &amp;quot;&#039; in &amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Must be in a section&lt;br /&gt;
    &lt;br /&gt;
    if (Section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;. No section header.&amp;quot;, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    list     parse=llParseString2List(line, [ &amp;quot;=&amp;quot; ], []);&lt;br /&gt;
    integer  num=llGetListLength(parse);&lt;br /&gt;
    &lt;br /&gt;
    // Format must be correct&lt;br /&gt;
    &lt;br /&gt;
    if (num != 2)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; +  (string)(Line+1) + &amp;quot;:\n&amp;quot; + rawline, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (Section == SECTION_ADDRESS_BOOK)&lt;br /&gt;
    {&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(name) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + name &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ name ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            string address=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
            string addressstr=GetAndCheckAddressStr(address);&lt;br /&gt;
            &lt;br /&gt;
            if (addressstr != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                AddressBookList     = (AddressBookList=[])     + AddressBookList     + [ name ];&lt;br /&gt;
                MailAddressList     = (MailAddressList=[])     + MailAddressList     + [ addressstr ];&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;No valid mail address for &#039;&amp;quot; + name &lt;br /&gt;
                    + &amp;quot;&#039;. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                    + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name &lt;br /&gt;
                + &amp;quot;&#039; already defined. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // Group&lt;br /&gt;
    {&lt;br /&gt;
        string group=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(group) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + group &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ group ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(GroupList, [ group ]) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                string names=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
                list   namelist=llCSV2List(names);&lt;br /&gt;
                integer num=llGetListLength(namelist);&lt;br /&gt;
                integer i;&lt;br /&gt;
                integer index;&lt;br /&gt;
                string  name;&lt;br /&gt;
                string  namestr=&amp;quot;&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
                for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                    name=llList2String(namelist,i);&lt;br /&gt;
                    index=llListFindList(AddressBookList, [ name ]);&lt;br /&gt;
            &lt;br /&gt;
                    if (index == -1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name + &amp;quot;&#039; defined in Group &#039;&amp;quot; &lt;br /&gt;
                                + group + &amp;quot;&#039; not found in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY); &lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        namestr = (namestr=&amp;quot;&amp;quot;) + namestr + name + &amp;quot;,&amp;quot;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (namestr != &amp;quot;&amp;quot;)&lt;br /&gt;
                {    &lt;br /&gt;
                    namestr=llGetSubString(namestr,0,-2);&lt;br /&gt;
                    GroupList         = (GroupList=[])         + GroupList     + [ group ];&lt;br /&gt;
                    GroupNameList     = (GroupNameList=[])    + GroupNameList + [ namestr ];&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                        + &amp;quot;&#039; has no valid names. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                        + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                    + &amp;quot;&#039; already defined in Group. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                    + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group&lt;br /&gt;
                + &amp;quot;&#039; already defined in Address Book. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// GetGroupAddressList ///////////////&lt;br /&gt;
&lt;br /&gt;
string GetGroupAddressList(string group)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(GroupList, [ group ]);&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(GroupList);&lt;br /&gt;
    string  grouplist=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        for (i = index; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2String(GroupList,i) == group)&lt;br /&gt;
            {&lt;br /&gt;
                grouplist = (grouplist=&amp;quot;&amp;quot;) + grouplist + llList2String(GroupNameList,i) + &amp;quot;,&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (grouplist != &amp;quot;&amp;quot;) grouplist=llGetSubString(grouplist,0,-2);   // remove last &amp;quot;,&amp;quot;&lt;br /&gt;
        return grouplist;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// SetMailAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetMailAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ address ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        index=llListFindList(GroupList, [ address ]);&lt;br /&gt;
        &lt;br /&gt;
        if (index == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llToUpper(address) == STRING_SELF)&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = GetSelfAddress();&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if(ValidMailAddress(address))&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = address;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Mail adress &amp;quot; + address &lt;br /&gt;
                            + &amp;quot; : not found in adress book or invalid format.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailAddress = GetGroupAddressList(address);&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        CurrentMailAddress = llList2String(MailAddressList,index);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                        + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string message)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No mail address defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No subject defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list mailaddresslist=llCSV2List(CurrentMailAddress);&lt;br /&gt;
        integer num=llGetListLength(mailaddresslist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(mailaddresslist,i);&lt;br /&gt;
            llEmail(address, CurrentMailSubject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMailHome() ////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMailHome(string message, string subject)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, STRING_HOME &lt;br /&gt;
                + &amp;quot; not set. Set your home adress with @HOME &amp;lt;address&amp;gt;.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        string homeaddress=llList2String(AddressBookList,index);&lt;br /&gt;
        list   homelist=llCSV2List(homeaddress);&lt;br /&gt;
        integer num=llGetListLength(homelist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(homelist,i);&lt;br /&gt;
            llEmail(address, subject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
string GetHomeAddress()&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;not set&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2String(MailAddressList,index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetHomeAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        AddressBookList     = (AddressBookList=[]) + [ STRING_HOME ] + AddressBookList;&lt;br /&gt;
        MailAddressList     = (MailAddressList=[]) + [ GetAndCheckAddressStr(address) ]  + MailAddressList;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MailAddressList = llListReplaceList(MailAddressList, [ GetAndCheckAddressStr(address) ], index, index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        Line=0;&lt;br /&gt;
        Section=0;&lt;br /&gt;
        llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// dataserver() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqAddressBook)&lt;br /&gt;
        {&lt;br /&gt;
            reqAddressBook = NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                ProcessLine(data);&lt;br /&gt;
                reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Address Book loaded.&amp;quot;, NULL_KEY);&lt;br /&gt;
                state running;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// timer() ///////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_ERROR, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Could not read Address Book: &amp;quot; &lt;br /&gt;
                            + ADDRESSBOOK_NOTECARD + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// link_message() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_MESSAGE_GETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is empty.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailSubject = message;&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is empty.&amp;quot;, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            SetMailAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Body of message to send is empty. &amp;quot; &lt;br /&gt;
                                +  &amp;quot;No mail is send.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SENDHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SendMailHome(message, (string)id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetInventoryType(message) == INVENTORY_NOTECARD)&lt;br /&gt;
            {&lt;br /&gt;
                Notecard2Fetch = message;                &lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_READ, message, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + message + &amp;quot; not found.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_NOTECARD_FETCHED)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + Notecard2Fetch &lt;br /&gt;
                            + &amp;quot; was empty or could not be read.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Home address is: &amp;quot; + GetHomeAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SetHomeAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_INFO)&lt;br /&gt;
        {&lt;br /&gt;
            Info();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
// End SL Mail AddressBook V1.2.lsl&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail FetchNotecard V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch the contents of a notecard and return it via link message as a string.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Notecard&lt;br /&gt;
&lt;br /&gt;
integer Line=0;&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
key     reqNotecard=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=10.0;&lt;br /&gt;
integer Fetched=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Lines&lt;br /&gt;
&lt;br /&gt;
list LineList=[];&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    /////////////////////// dataserver() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqNotecard)&lt;br /&gt;
        {&lt;br /&gt;
            reqNotecard=NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                LineList = (LineList=[]) + LineList + [ data ];&lt;br /&gt;
                reqNotecard = llGetNotecardLine(Notecard2Fetch, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Fetched=TRUE;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, llDumpList2String(LineList, &amp;quot;\n&amp;quot;), NULL_KEY);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /////////////////////// timer() ///////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        if (!Fetched)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            llSetTimerEvent(0.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer send, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_NOTECARD_READ)&lt;br /&gt;
        {&lt;br /&gt;
            Line=0;&lt;br /&gt;
            Notecard2Fetch=message;&lt;br /&gt;
            LineList=[];&lt;br /&gt;
            Fetched=FALSE;&lt;br /&gt;
            reqNotecard=llGetNotecardLine(Notecard2Fetch, Line);&lt;br /&gt;
            llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL OnlineStatus V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch online status of owner.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Online status&lt;br /&gt;
&lt;br /&gt;
key     reqOnlineStatus=NULL_KEY;&lt;br /&gt;
float   STATUS_INTERVAL=2.0;&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_STATUS_ONLINE       = 30000;&lt;br /&gt;
integer MS_STATUS_OFFLINE       = 30100;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus=llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
        llSetTimerEvent(STATUS_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// dataserver() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqOnlineStatus)&lt;br /&gt;
        {&lt;br /&gt;
            reqOnlineStatus = NULL_KEY;&lt;br /&gt;
        &lt;br /&gt;
            if (data==&amp;quot;1&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_STATUS_ONLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if (data==&amp;quot;0&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MS_STATUS_OFFLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus = llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Help V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Display help information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail Help V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP    = 10000;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Help() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Help()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;HELP for SL Mail V1.2.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;COMMANDS:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HELP               - displays help info.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@INFO               - display mailaddress of this object.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RECORD             - start recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CONTINUE           - continue recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@STOP               - stop recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@IGNORE             - ignore the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SHOW               - show what your recorded.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SEND               - send the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@MAIL &amp;lt;mailadress&amp;gt;  - set the mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SUBJECT subject    - set the mail subject.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LIST               - list messages in mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SELECT &amp;lt;message&amp;gt;   - select message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@READ               - read current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@NEXT               - read next message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@PREV               - read previous message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@FIRST              - read first message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LAST               - read last message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@DELETE             - delete current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CLEAR              - clear the mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@REPLY              - reply to current message.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RESET              - reset the script.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HOME               - set the home mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@OFF                - switch mailbox OFF.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@ON                 - switch mailbox ON.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_HELP)&lt;br /&gt;
        {&lt;br /&gt;
            Help();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail Help V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}&lt;/div&gt;</description>
			<pubDate>Wed, 09 Feb 2011 23:12:43 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:SL_Mail_V1.2</comments>
		</item>
		<item>
			<title>User:Flennan Roffo</title>
			<link>https://wiki.secondlife.com/w/index.php?title=User:Flennan_Roffo&amp;diff=1133907</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=User:Flennan_Roffo&amp;diff=1133907</guid>
			<description>&lt;p&gt;Flennan Roffo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
=About Flennan Roffo=&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
||[[Image:FlennanRoffo80x80.jpg|frameless|100px|Flennan Roffo]]&lt;br /&gt;
||Second Life resident since 11 July 2007. Scripter and owner of Logic Scripts. You can visit me at my office in Beeratron (57, 168, 75)&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Beeratron&lt;br /&gt;
|x=57&lt;br /&gt;
|y=168&lt;br /&gt;
|z=75&lt;br /&gt;
|title=Logic Scripts&lt;br /&gt;
|}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logic Scripts=&lt;br /&gt;
[[Image:Logicscripts.org.jpg]]&lt;br /&gt;
&lt;br /&gt;
==ABOUT LOGIC==&lt;br /&gt;
Logic Scripts provides script services. Most of my scripts is free software published under the GNU GPL licence.&lt;br /&gt;
&lt;br /&gt;
==PRODUCTS==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Logic Mailbox Basic V 1.0&#039;&#039;&#039;&lt;br /&gt;
Basic model for a mailbox that allows anyone to drop you a notecard. Comes with a standard skin. For skin customization, contact Mad Maddy Studio.&lt;br /&gt;
&lt;br /&gt;
[[Image:Slmailbox.jpg]]&lt;br /&gt;
&lt;br /&gt;
See the demo at Logic office: &lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Beeratron&lt;br /&gt;
|x=57&lt;br /&gt;
|y=168&lt;br /&gt;
|z=75&lt;br /&gt;
|title=Logic Scripts&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Logic Vendor V 1.0&#039;&#039;&#039;&lt;br /&gt;
Vendor that allows you to display many sellable items (objects) and per item you can give a customer a notecard. The sell price is split amongst multiple authors. Set up is easy, since you have to enter the key of each author only once, and can reference any author by nick.&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicvendorv10.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
See the demo at Logic office:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Beeratron&lt;br /&gt;
|x=57&lt;br /&gt;
|y=168&lt;br /&gt;
|z=75&lt;br /&gt;
|title=Logic Scripts&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;SL Mail V 1.2&#039;&#039;&#039;&lt;br /&gt;
SecondLife mail client, released under GNU GPL licence. You can send and receive mail from within SecondLife both from and to other mail clients or external mail adresses. Has many command options and comes with an adjustable address book that allows to enter addresses and address groups.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Get a free copy at logic office:&#039;&#039;&#039;&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Beeratron&lt;br /&gt;
|x=57&lt;br /&gt;
|y=168&lt;br /&gt;
|z=75&lt;br /&gt;
|title=Logic Scripts&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Or, alternatively, get it from the Second Life wiki [[SL Mail V1.2|here]]&lt;br /&gt;
&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
==SERVICE CHARGING POLICY==&lt;br /&gt;
&lt;br /&gt;
The charging policy for script services depends on a number of factors:&lt;br /&gt;
* The usuability of the script. Simply stated, if the script does not provide what it is supposed to do no charge will be applied.&lt;br /&gt;
* The amount of work needed to create, adapt and test the script.&lt;br /&gt;
* The custumor. As a rule, the richer the customer, the higher the price, and the more the script or service I provide enhances business profits, the more is charged.&lt;br /&gt;
* The pricing will be based on the length of the service time-period.&lt;br /&gt;
* Prices are within reason.&lt;br /&gt;
* Part or whole price can be refunded if you have a well grounded complaint (script not behaving as specified or a large delay in delivering the scripts).&lt;br /&gt;
* Payment in advance for small projects are not necessary. For larger projects in which significant amount of time is invested advanced payment is asked for in the order of 10%-50% of the agreed price.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Donate for free scripts/services&lt;br /&gt;
&lt;br /&gt;
If you found my scripts and/or other services quite usefull and got them free of charge, you might consider giving a donation.&lt;br /&gt;
&lt;br /&gt;
==HIRING==&lt;br /&gt;
&lt;br /&gt;
Logic can be hired for diverse script projects.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Logic Scripts&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Flennan Roffo&lt;/div&gt;</description>
			<pubDate>Wed, 09 Feb 2011 23:09:16 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/User_talk:Flennan_Roffo</comments>
		</item>
		<item>
			<title>Shoutcast - radio controller v0.3 (remake of similar scripts)</title>
			<link>https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133906</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133906</guid>
			<description>&lt;p&gt;Flennan Roffo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}}&lt;br /&gt;
===Shoutcast - radio controller v0.3===&lt;br /&gt;
This script controls a shoutcast radio receiver and lets you select the stations that you configured on a notecard. Menu driven. Output of station description, genre and current song title using Xy text.&lt;br /&gt;
===Main script===&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// Shoutcast - radio controller v0.3&lt;br /&gt;
// Logic Scripts (Flennan Roffo)&lt;br /&gt;
// (c) 2010 - Flennan Roffo (Logic Scripts)&lt;br /&gt;
// &lt;br /&gt;
// Remake of similar script:&lt;br /&gt;
// + LandOwnersRadio V2.0 by Scripter Coba  (( menu driven / notecard config script to select the radio station and sets parcel music url ))&lt;br /&gt;
// + Raven radio infoboard by Jamie Otis    (( worked at the basis of sis service [sis.slserver.com/sis.php] used Xy text display         ))&lt;br /&gt;
// + currentPlaying by Darkie Minotaur      (( used the /7.html info to fetch current song title info, displayed as float text            ))&lt;br /&gt;
//&lt;br /&gt;
// Purpose:&lt;br /&gt;
// * Sets the parcel audio URL and displays the channel info&lt;br /&gt;
// * Uses Xytext to display the info.&lt;br /&gt;
// * Fetches song title info from the shoutcast url&lt;br /&gt;
// Extra Features -- 0.1 release&lt;br /&gt;
// * On/Off option&lt;br /&gt;
// * Allows multiple menus (if options per menu &amp;gt; 12) using a prev/next button&lt;br /&gt;
// * Checks if your url is well-formatted&lt;br /&gt;
// * Will delete genres for which no stations exist&lt;br /&gt;
// * Will skip stations that have same url and same genre (you can however have an identical station url under different genres).&lt;br /&gt;
// * New notecard format&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.2 release&lt;br /&gt;
// * Configurable button text&lt;br /&gt;
// * Gets parcel URL and automatically sets the genre/station and on/off status accordingly (&amp;lt;-- doesn&#039;t work)&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Update -- 0.3 release&lt;br /&gt;
// * Fixed bug (only first station in genre displayed in menu)&lt;br /&gt;
// * Auto reset script when config card updated&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
//&lt;br /&gt;
// This program is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string info_notecard=&amp;quot;Radio Control info&amp;quot;;              ///////    EDITABLE  \\\\\\&lt;br /&gt;
string config_notecard=&amp;quot;Radio Control config&amp;quot;;          ///////    EDITABLE  \\\\\\&lt;br /&gt;
string comment_char=&amp;quot;#&amp;quot;;                                ///////    EDITABLE  \\\\\\&lt;br /&gt;
list sep_char_list= [&amp;quot;|&amp;quot;];                              ///////    EDITABLE  \\\\\\&lt;br /&gt;
float update_time=5.0;                                  ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string no_title_info=&amp;quot;(no title info available)&amp;quot;;       ///////    EDITABLE  \\\\\\&lt;br /&gt;
&lt;br /&gt;
// not used currently - for showing info on current song title elsewhere in the region&lt;br /&gt;
integer broadcast_channel=-1234;                        ///////    EDITABLE  \\\\\\ &lt;br /&gt;
&lt;br /&gt;
// Buttons&lt;br /&gt;
&lt;br /&gt;
string button_MAIN = &amp;quot;MAIN&amp;quot;;&lt;br /&gt;
string button_HELP = &amp;quot;HELP&amp;quot;;&lt;br /&gt;
string button_NEXT = &amp;quot;&amp;gt;&amp;gt;&amp;quot;;&lt;br /&gt;
string button_PREV = &amp;quot;&amp;lt;&amp;lt;&amp;quot;;&lt;br /&gt;
string button_ON   = &amp;quot;ON&amp;quot;;&lt;br /&gt;
string button_OFF  = &amp;quot;OFF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Lists&lt;br /&gt;
&lt;br /&gt;
list category_list=[];&lt;br /&gt;
&lt;br /&gt;
list station_category=[];&lt;br /&gt;
list station_name=[];&lt;br /&gt;
list station_desc=[];&lt;br /&gt;
list station_url=[];&lt;br /&gt;
&lt;br /&gt;
string last_title_info=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
integer radio_status=0;&lt;br /&gt;
string parcel_url=&amp;quot;&amp;quot;;&lt;br /&gt;
integer lineno=0;&lt;br /&gt;
key reqid=NULL_KEY;&lt;br /&gt;
key httpreq_id=NULL_KEY;&lt;br /&gt;
integer config_error=FALSE;&lt;br /&gt;
integer flag;&lt;br /&gt;
integer section=0;&lt;br /&gt;
integer owner_access=TRUE;&lt;br /&gt;
integer group_access=FALSE;&lt;br /&gt;
integer public_access=TRUE;&lt;br /&gt;
list banned_keys=[];&lt;br /&gt;
&lt;br /&gt;
integer menu_channel;&lt;br /&gt;
integer listen_handle;&lt;br /&gt;
integer menu_type=0;&lt;br /&gt;
integer menu_num=0;&lt;br /&gt;
integer category_index=0;&lt;br /&gt;
integer station_index=0;&lt;br /&gt;
&lt;br /&gt;
integer num_categories=0;&lt;br /&gt;
integer num_stations=0;&lt;br /&gt;
&lt;br /&gt;
retrieve_titelinfo()&lt;br /&gt;
{&lt;br /&gt;
    string url=llList2String(station_url,station_index);&lt;br /&gt;
    httpreq_id=llHTTPRequest(url + &amp;quot;/7.html  HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n&amp;quot;,[],&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
display_line(string line, string message)&lt;br /&gt;
{&lt;br /&gt;
    // Setup XYtext Variables&lt;br /&gt;
    integer DISPLAY_STRING      = 204000; &lt;br /&gt;
    integer DISPLAY_EXTENDED    = 204001; &lt;br /&gt;
    integer REMAP_INDICES       = 204002; &lt;br /&gt;
    integer RESET_INDICES       = 204003; &lt;br /&gt;
    integer SET_CELL_INFO       = 204004; &lt;br /&gt;
    integer SET_FONT_TEXTURE    = 204005; &lt;br /&gt;
    integer SET_THICKNESS       = 204006; &lt;br /&gt;
    integer SET_COLOR           = 204007; &lt;br /&gt;
&lt;br /&gt;
    llMessageLinked(LINK_SET,DISPLAY_STRING,message,line);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
clear_display() &lt;br /&gt;
{&lt;br /&gt;
    // Clears the display&lt;br /&gt;
    display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio Station ID&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;2&amp;quot;,&amp;quot;Music Genre....&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;3&amp;quot;,&amp;quot;Now Playing....&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
make_menu(key id)&lt;br /&gt;
{&lt;br /&gt;
     menu_channel=random_channel();&lt;br /&gt;
&lt;br /&gt;
    if (radio_status == 0)&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        llDialog(id,&amp;quot;Menu: Status\n\nRadio is OFF&amp;quot;, [ &amp;quot;ON&amp;quot;, &amp;quot;HELP&amp;quot; ],menu_channel);&lt;br /&gt;
    }&lt;br /&gt;
    else &lt;br /&gt;
    {&lt;br /&gt;
        if (menu_type ==0)&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Genres&amp;quot;, category_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Stations\nGenre: &amp;quot; + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (listen_handle != 0)    llListenRemove(listen_handle);&lt;br /&gt;
    listen_handle=llListen(menu_channel,&amp;quot;&amp;quot;,id,&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
list category_menu(integer num)&lt;br /&gt;
{   // compile menu list of category list&lt;br /&gt;
    // if there are more catagories then can be displayed in the menu&lt;br /&gt;
    // compile a submenu, including options for main menu and more and a blank item.&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
&lt;br /&gt;
    if (len &amp;gt; 9)&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;   // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc. &lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt; last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
&lt;br /&gt;
             while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_HELP;&lt;br /&gt;
             else&lt;br /&gt;
                 menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_OFF;&lt;br /&gt;
             else&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num != last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;       &lt;br /&gt;
        }            &lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
        menu+=(list)button_OFF;&lt;br /&gt;
        menu+=(list)button_HELP;&lt;br /&gt;
    }        &lt;br /&gt;
    &lt;br /&gt;
    return menu;    // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer stations_in_category(integer cat)&lt;br /&gt;
{&lt;br /&gt;
    integer count=0;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
    string category=llList2String(category_list,cat);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (category == llList2String(category_list,i))&lt;br /&gt;
            count++;&lt;br /&gt;
&lt;br /&gt;
    return count;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
list order_buttons(list buttons)&lt;br /&gt;
{&lt;br /&gt;
    integer offset;&lt;br /&gt;
    list fixt;&lt;br /&gt;
    integer flag=0;&lt;br /&gt;
&lt;br /&gt;
    while((offset = llGetListLength(buttons)))&lt;br /&gt;
    {&lt;br /&gt;
        if (offset &amp;gt; 3)&lt;br /&gt;
            flag=1;&lt;br /&gt;
        else&lt;br /&gt;
            flag=0;&lt;br /&gt;
&lt;br /&gt;
        fixt += llList2List(buttons, offset = -3 * flag, -1);&lt;br /&gt;
        buttons = llDeleteSubList(buttons, offset, -1);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return fixt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
list station_list(integer category)&lt;br /&gt;
{&lt;br /&gt;
    list s=[];&lt;br /&gt;
    integer i;&lt;br /&gt;
    string cname=llList2String(category_list,category_index);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; llGetListLength(station_name); i++)&lt;br /&gt;
        if (llList2String(station_category,i) == cname)&lt;br /&gt;
            s+=(list)llList2String(station_name,i);&lt;br /&gt;
&lt;br /&gt;
    return s;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
list station_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
   // compile menu list of station names&lt;br /&gt;
    // if there are more stations then can be displayed in the menu&lt;br /&gt;
    // compile a submenu, including options for main menu and more and a blank item.&lt;br /&gt;
&lt;br /&gt;
    list stations=station_list(category_index);&lt;br /&gt;
    integer len=llGetListLength(stations);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
&lt;br /&gt;
    llSay(0,&amp;quot;Category: &amp;quot; + llList2String(category_list,category_index));&lt;br /&gt;
    llSay(0,&amp;quot;Stations: &amp;quot; + llDumpList2String(stations,&amp;quot;,&amp;quot;));&lt;br /&gt;
        &lt;br /&gt;
    if (len &amp;gt; 11)&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;&lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt;= last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
             integer last=9*num+8;&lt;br /&gt;
&lt;br /&gt;
             menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;gt; 0)&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;lt; last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;                      &lt;br /&gt;
&lt;br /&gt;
            if (len &amp;gt; last)&lt;br /&gt;
                len =last;&lt;br /&gt;
                &lt;br /&gt;
            while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(stations,len);&lt;br /&gt;
        }&lt;br /&gt;
    }            &lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(stations,len);&lt;br /&gt;
    }        &lt;br /&gt;
&lt;br /&gt;
    return menu; // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer has_access(key id)&lt;br /&gt;
{&lt;br /&gt;
    if (llListFindList(banned_keys,(list)id) != -1)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    if (owner_access &amp;amp;&amp;amp; id == llGetOwner())&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (group_access &amp;amp;&amp;amp; llSameGroup(id))&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (public_access)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer random_channel()&lt;br /&gt;
{&lt;br /&gt;
    integer min=-2147483647;&lt;br /&gt;
    integer max=-1000;&lt;br /&gt;
&lt;br /&gt;
    return (integer) (min + llFrand(max-min));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer check_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    integer pos=0;&lt;br /&gt;
&lt;br /&gt;
    if (llGetSubString(url,0,6) == &amp;quot;http://&amp;quot;)&lt;br /&gt;
        pos=7;        &lt;br /&gt;
    if (llGetSubString(url,0,7) == &amp;quot;https://&amp;quot;)&lt;br /&gt;
        pos=8;&lt;br /&gt;
&lt;br /&gt;
    if (pos==0)   return FALSE;&lt;br /&gt;
&lt;br /&gt;
    string str_ip_port=llGetSubString(url,pos,-1);&lt;br /&gt;
    list list_ip_port=llParseString2List(str_ip_port,[&amp;quot;:&amp;quot;],[]);                    // split in ip-adress and port&lt;br /&gt;
    list list_ip=llParseString2List(llList2String(list_ip_port,0),[&amp;quot;.&amp;quot;],[]);    // split ip-adress elements&lt;br /&gt;
&lt;br /&gt;
    if (llGetListLength(list_ip_port) != 2 || llGetListLength(list_ip) != 4)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer test;&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;4;i++)&lt;br /&gt;
    {&lt;br /&gt;
        test=llList2Integer(list_ip,i);&lt;br /&gt;
        if (llList2String(list_ip,i) != (string)test)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        if (test &amp;lt; 0 || test &amp;gt; 255)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    test=llList2Integer(list_ip_port,1);&lt;br /&gt;
    if (llList2String(list_ip_port,1) != (string)test)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer true_value(string input)&lt;br /&gt;
{&lt;br /&gt;
    string value=llToLower(llGetSubString(input,0,0));&lt;br /&gt;
&lt;br /&gt;
    if (value == &amp;quot;y&amp;quot; || value == &amp;quot;t&amp;quot; || value ==&amp;quot;1&amp;quot;)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer process_line(string dataline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(dataline,STRING_TRIM);&lt;br /&gt;
    integer index=llSubStringIndex(line,comment_char);&lt;br /&gt;
    &lt;br /&gt;
    if (index==0)       // line starts with comment - ignore line&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (index!=-1)&lt;br /&gt;
        line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL);   // skip everything after comment_char and trim tail&lt;br /&gt;
&lt;br /&gt;
    if (line==&amp;quot;&amp;quot;)       // Ignore blank lines&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (llToLower(line) == &amp;quot;[access]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 1;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[banned]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 2;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[genre]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 3;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[station]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 4;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llGetSubString(line,0,0) == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; llGetSubString(line,-1,-1) == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: malformed section found at line &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
        config_error=TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: no section found on line: &amp;quot; + (string) lineno);&lt;br /&gt;
        config_error = TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    list breakup=llParseString2List(line,[&amp;quot;=&amp;quot;],[]);&lt;br /&gt;
    string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);&lt;br /&gt;
    string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);&lt;br /&gt;
&lt;br /&gt;
    if (section == 1)            // access&lt;br /&gt;
    {&lt;br /&gt;
        field=llToLower(field);&lt;br /&gt;
&lt;br /&gt;
        if (field==&amp;quot;owner&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            owner_access=true_value(values);                       &lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;group&amp;quot;)&lt;br /&gt;
        {    &lt;br /&gt;
            group_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;public&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            public_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: invalid option on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 2)         // ban list&lt;br /&gt;
    {&lt;br /&gt;
        key try=(key) field;&lt;br /&gt;
&lt;br /&gt;
        if (try)&lt;br /&gt;
        {&lt;br /&gt;
            banned_keys+=(list)((key) field);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 3)           // categories&lt;br /&gt;
    {&lt;br /&gt;
        if (llListFindList(category_list,(list)field) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            category_list+=(list)field;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;genre: &#039;&amp;quot; + field + &amp;quot;&#039; already entered; double entry skipped.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 4)            // stations&lt;br /&gt;
    {&lt;br /&gt;
        list parse=llParseString2List(line,sep_char_list, []);&lt;br /&gt;
        string category=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);&lt;br /&gt;
        string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);&lt;br /&gt;
    &lt;br /&gt;
        if (!available_category(category))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: unknown genre on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (check_url(url))&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                num_stations++;&lt;br /&gt;
                station_category+=(list)category;&lt;br /&gt;
                station_name+=(list)name;&lt;br /&gt;
                station_desc+=(list)desc;&lt;br /&gt;
                station_url+=(list)url;&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llWhisper(0,&amp;quot;This station is already entered under the same genre and same url and is skipped.\nStation: &amp;quot; + name + &amp;quot;\nGenre: &#039;&amp;quot; + category + &amp;quot;&#039;\nURL: &amp;quot; + url);&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: malformed url on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
     &lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
set_parcel_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    parcel_url=url;&lt;br /&gt;
    llSetParcelMusicURL(parcel_url);&lt;br /&gt;
&lt;br /&gt;
    if (parcel_url==&amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        clear_display();&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is OFF&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;station now set to &amp;quot; + llList2String(station_desc,station_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Station: &amp;quot; + llList2String(station_desc,station_index));&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;Genre  : &amp;quot; + llList2String(category_list,category_index));&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;Now playing.....&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer available_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;len;i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(category_list,i)))&lt;br /&gt;
            return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer empty_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(station_category,i)))&lt;br /&gt;
            return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
skip_empty_categories()&lt;br /&gt;
{&lt;br /&gt;
    integer i=0;&lt;br /&gt;
&lt;br /&gt;
    while (i&amp;lt;llGetListLength(category_list))&lt;br /&gt;
    {&lt;br /&gt;
        if (empty_category(llList2String(category_list,i)))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;Warning: Genre &#039;&amp;quot; + llList2String(category_list,i) + &amp;quot;&#039; contains no stations and is deleted.&amp;quot;);&lt;br /&gt;
            category_list=llDeleteSubList(category_list,i,i);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            i++;&lt;br /&gt;
    }&lt;br /&gt;
            &lt;br /&gt;
    num_categories=llGetListLength(category_list);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state default&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        flag=FALSE;&lt;br /&gt;
        lineno=0;&lt;br /&gt;
        config_error=FALSE;&lt;br /&gt;
        num_stations=0;&lt;br /&gt;
        num_categories=0;&lt;br /&gt;
        radio_status=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(config_notecard) != INVENTORY_NONE)&lt;br /&gt;
        {&lt;br /&gt;
           reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
           llWhisper(0, &amp;quot;Reading config notecard...&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;1&amp;quot;,&amp;quot;Reading configuration.&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;2&amp;quot;,&amp;quot;Wait....&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;No config notecard &#039;&amp;quot; +  config_notecard + &amp;quot;&#039; present.&amp;quot;);&lt;br /&gt;
            state offline;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (reqid==id)&lt;br /&gt;
        {        &lt;br /&gt;
            if (data==EOF)&lt;br /&gt;
            {&lt;br /&gt;
                skip_empty_categories();&lt;br /&gt;
                llWhisper(0,&amp;quot;Configuration ok.\n&amp;quot; + (string)num_categories + &amp;quot; genres and &amp;quot; + (string)num_stations + &amp;quot; stations.&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Configuration OK&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;2&amp;quot;,&amp;quot;Genres  : &amp;quot; + (string)num_categories);&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Stations: &amp;quot; + (string)num_stations);&lt;br /&gt;
                state menu;&lt;br /&gt;
            }&lt;br /&gt;
            else &lt;br /&gt;
            {&lt;br /&gt;
                if (process_line(data))&lt;br /&gt;
                    reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
                else if (config_error)&lt;br /&gt;
                {&lt;br /&gt;
                    llWhisper(0,&amp;quot;errors found in configuration. please correct them.&amp;quot;);&lt;br /&gt;
                    state offline;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY &amp;amp;&amp;amp; flag)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state offline&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state offline&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;Reset on owner touch.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    touch_start(integer t)&lt;br /&gt;
   {&lt;br /&gt;
        if (llDetectedKey(0)==llGetOwner())&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state menu&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state menu&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        listen_handle=0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        if (param &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
        key toucher=llDetectedKey(0);&lt;br /&gt;
&lt;br /&gt;
        if (has_access(toucher))&lt;br /&gt;
        {&lt;br /&gt;
            make_menu(toucher);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;sorry, no access.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    listen(integer chan, string name,key id,string msg)&lt;br /&gt;
    {&lt;br /&gt;
        integer index;&lt;br /&gt;
&lt;br /&gt;
        if (menu_type == 0)          // main menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_ON)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=1;&lt;br /&gt;
                set_parcel_url(parcel_url);               &lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is ON&amp;quot;);&lt;br /&gt;
                menu_num=0;&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned on.&amp;quot;);&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=0;&lt;br /&gt;
                set_parcel_url(&amp;quot;&amp;quot;);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned off.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
                {&lt;br /&gt;
                    llGiveInventory(id,info_notecard);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                    llWhisper(0,&amp;quot;sorry, help not available.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (radio_status == 1)&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(category_list, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: genre not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    category_index=index;&lt;br /&gt;
                    llWhisper(0,&amp;quot;Genre now set to &amp;quot; + llList2String(category_list,category_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
                    menu_type=1;&lt;br /&gt;
                    menu_num=0;&lt;br /&gt;
                    make_menu(id);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (menu_type == 1 &amp;amp;&amp;amp; radio_status == 1)     // station menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(station_name, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: station not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    station_index=index;&lt;br /&gt;
                    string new_url=llList2String(station_url,station_index);&lt;br /&gt;
&lt;br /&gt;
                    if (new_url != parcel_url)&lt;br /&gt;
                    {&lt;br /&gt;
                        set_parcel_url(new_url);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        retrieve_titelinfo();&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_response(key id, integer status, list meta, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == httpreq_id)&lt;br /&gt;
        {&lt;br /&gt;
            if (status == 200)&lt;br /&gt;
            {&lt;br /&gt;
                string feed = llGetSubString(body,llSubStringIndex(body, &amp;quot;&amp;lt;body&amp;gt;&amp;quot;) + llStringLength(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;), llSubStringIndex(body,&amp;quot;&amp;lt;/body&amp;gt;&amp;quot;) - 1);&lt;br /&gt;
                list feed_list = llParseString2List(feed,[&amp;quot;,&amp;quot;],[]);&lt;br /&gt;
                string current_title_info= llList2String(feed_list,6);&lt;br /&gt;
                integer length = llGetListLength(feed_list);&lt;br /&gt;
        &lt;br /&gt;
                if(llList2String(feed_list,7))&lt;br /&gt;
                {&lt;br /&gt;
                    integer a = 7;&lt;br /&gt;
                    for(; a&amp;lt;length; ++a)&lt;br /&gt;
                    {&lt;br /&gt;
                        current_title_info += &amp;quot;, &amp;quot; + llList2String(feed_list,a);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
         &lt;br /&gt;
                if (current_title_info != last_title_info)&lt;br /&gt;
                {&lt;br /&gt;
                    last_title_info = current_title_info;&lt;br /&gt;
                    display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + current_title_info);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + no_title_info);&lt;br /&gt;
            }&lt;br /&gt;
        }    &lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
// end of script&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
===Notecard format===&lt;br /&gt;
Example notecard&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# New format Shoutcast - radio controller config notecard&lt;br /&gt;
# The format is divided in 4 sections:&lt;br /&gt;
# 1 - Access configuration&lt;br /&gt;
# 2 - Ban list (keys)&lt;br /&gt;
# 3 - Categories  (same as genres)&lt;br /&gt;
# 4 - Station info (category, name, desc, url)&lt;br /&gt;
# The &#039;#&#039; character defines the start of a comment and can be anywhere on a line. &lt;br /&gt;
# Everything after the &#039;#&#039; incuding the &#039;#&#039; itself is ignored.&lt;br /&gt;
# Case is not important (but information on display will show as entered)&lt;br /&gt;
# Spaces before and/or after fields are trimmed.&lt;br /&gt;
# Empty lines are ignored.&lt;br /&gt;
&lt;br /&gt;
[ACCESS]&lt;br /&gt;
owner=yes       # yes, true,1      means owner has access. everything else not.&lt;br /&gt;
group=yes       #  ,,  ,,  ,,      means group has acess.    ,,        ,,   ,,&lt;br /&gt;
public=yes      #  ,,  ,,  ,,      means public has access.  ,,        ,,   ,, &lt;br /&gt;
&lt;br /&gt;
[BANNED]&lt;br /&gt;
# keys of banned residents&lt;br /&gt;
&lt;br /&gt;
[GENRE]&lt;br /&gt;
# genre name&lt;br /&gt;
Hard Rock&lt;br /&gt;
Classic Rock&lt;br /&gt;
Oldies&lt;br /&gt;
Rap/Urban&lt;br /&gt;
Comedy&lt;br /&gt;
News&lt;br /&gt;
Dance&lt;br /&gt;
Country&lt;br /&gt;
Gothic&lt;br /&gt;
# etc.&lt;br /&gt;
[STATION]&lt;br /&gt;
# Shoutcast radio stations&lt;br /&gt;
# Use a &#039;|&#039; between each field - don&#039;t mind spaces before and after fields, they will be trimmed&lt;br /&gt;
# field1:genre, field2:station name, field3: station description, field4: station url+port&lt;br /&gt;
# Note that genre must match case-insensitive a value in [GENRE] &lt;br /&gt;
Classic Rock    | Absolute         |    Absolute Radio                  | http://205.188.215.226:8018&lt;br /&gt;
# etc.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===TODO===&lt;br /&gt;
&lt;br /&gt;
* Add a llRegionSay to broadcast the station/genre/current songtitle to the region and write a script that displays that info on an Xytext board.&lt;/div&gt;</description>
			<pubDate>Wed, 09 Feb 2011 22:16:17 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)</comments>
		</item>
		<item>
			<title>Shoutcast - radio controller v0.3 (remake of similar scripts)</title>
			<link>https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133905</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133905</guid>
			<description>&lt;p&gt;Flennan Roffo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}}&lt;br /&gt;
This script controls a shoutcast radio receiver and lets you select the stations that you configured on a notecard. Menu driven. Output of station description, genre and current song title using Xy text.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// Shoutcast - radio controller v0.3&lt;br /&gt;
// Logic Scripts (Flennan Roffo)&lt;br /&gt;
// (c) 2010 - Flennan Roffo (Logic Scripts)&lt;br /&gt;
// &lt;br /&gt;
// Remake of similar script:&lt;br /&gt;
// + LandOwnersRadio V2.0 by Scripter Coba  (( menu driven / notecard config script to select the radio station and sets parcel music url ))&lt;br /&gt;
// + Raven radio infoboard by Jamie Otis    (( worked at the basis of sis service [sis.slserver.com/sis.php] used Xy text display         ))&lt;br /&gt;
// + currentPlaying by Darkie Minotaur      (( used the /7.html info to fetch current song title info, displayed as float text            ))&lt;br /&gt;
//&lt;br /&gt;
// Purpose:&lt;br /&gt;
// * Sets the parcel audio URL and displays the channel info&lt;br /&gt;
// * Uses Xytext to display the info.&lt;br /&gt;
// * Fetches song title info from the shoutcast url&lt;br /&gt;
// Extra Features -- 0.1 release&lt;br /&gt;
// * On/Off option&lt;br /&gt;
// * Allows multiple menus (if options per menu &amp;gt; 12) using a prev/next button&lt;br /&gt;
// * Checks if your url is well-formatted&lt;br /&gt;
// * Will delete genres for which no stations exist&lt;br /&gt;
// * Will skip stations that have same url and same genre (you can however have an identical station url under different genres).&lt;br /&gt;
// * New notecard format&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.2 release&lt;br /&gt;
// * Configurable button text&lt;br /&gt;
// * Gets parcel URL and automatically sets the genre/station and on/off status accordingly (&amp;lt;-- doesn&#039;t work)&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Update -- 0.3 release&lt;br /&gt;
// * Fixed bug (only first station in genre displayed in menu)&lt;br /&gt;
// * Auto reset script when config card updated&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
//&lt;br /&gt;
// This program is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string info_notecard=&amp;quot;Radio Control info&amp;quot;;              ///////    EDITABLE  \\\\\\&lt;br /&gt;
string config_notecard=&amp;quot;Radio Control config&amp;quot;;          ///////    EDITABLE  \\\\\\&lt;br /&gt;
string comment_char=&amp;quot;#&amp;quot;;                                ///////    EDITABLE  \\\\\\&lt;br /&gt;
list sep_char_list= [&amp;quot;|&amp;quot;];                              ///////    EDITABLE  \\\\\\&lt;br /&gt;
float update_time=5.0;                                  ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string no_title_info=&amp;quot;(no title info available)&amp;quot;;       ///////    EDITABLE  \\\\\\&lt;br /&gt;
&lt;br /&gt;
// not used currently - for showing info on current song title elsewhere in the region&lt;br /&gt;
integer broadcast_channel=-1234;                        ///////    EDITABLE  \\\\\\ &lt;br /&gt;
&lt;br /&gt;
// Buttons&lt;br /&gt;
&lt;br /&gt;
string button_MAIN = &amp;quot;MAIN&amp;quot;;&lt;br /&gt;
string button_HELP = &amp;quot;HELP&amp;quot;;&lt;br /&gt;
string button_NEXT = &amp;quot;&amp;gt;&amp;gt;&amp;quot;;&lt;br /&gt;
string button_PREV = &amp;quot;&amp;lt;&amp;lt;&amp;quot;;&lt;br /&gt;
string button_ON   = &amp;quot;ON&amp;quot;;&lt;br /&gt;
string button_OFF  = &amp;quot;OFF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Lists&lt;br /&gt;
&lt;br /&gt;
list category_list=[];&lt;br /&gt;
&lt;br /&gt;
list station_category=[];&lt;br /&gt;
list station_name=[];&lt;br /&gt;
list station_desc=[];&lt;br /&gt;
list station_url=[];&lt;br /&gt;
&lt;br /&gt;
string last_title_info=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
integer radio_status=0;&lt;br /&gt;
string parcel_url=&amp;quot;&amp;quot;;&lt;br /&gt;
integer lineno=0;&lt;br /&gt;
key reqid=NULL_KEY;&lt;br /&gt;
key httpreq_id=NULL_KEY;&lt;br /&gt;
integer config_error=FALSE;&lt;br /&gt;
integer flag;&lt;br /&gt;
integer section=0;&lt;br /&gt;
integer owner_access=TRUE;&lt;br /&gt;
integer group_access=FALSE;&lt;br /&gt;
integer public_access=TRUE;&lt;br /&gt;
list banned_keys=[];&lt;br /&gt;
&lt;br /&gt;
integer menu_channel;&lt;br /&gt;
integer listen_handle;&lt;br /&gt;
integer menu_type=0;&lt;br /&gt;
integer menu_num=0;&lt;br /&gt;
integer category_index=0;&lt;br /&gt;
integer station_index=0;&lt;br /&gt;
&lt;br /&gt;
integer num_categories=0;&lt;br /&gt;
integer num_stations=0;&lt;br /&gt;
&lt;br /&gt;
retrieve_titelinfo()&lt;br /&gt;
{&lt;br /&gt;
    string url=llList2String(station_url,station_index);&lt;br /&gt;
    httpreq_id=llHTTPRequest(url + &amp;quot;/7.html  HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n&amp;quot;,[],&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
display_line(string line, string message)&lt;br /&gt;
{&lt;br /&gt;
    // Setup XYtext Variables&lt;br /&gt;
    integer DISPLAY_STRING      = 204000; &lt;br /&gt;
    integer DISPLAY_EXTENDED    = 204001; &lt;br /&gt;
    integer REMAP_INDICES       = 204002; &lt;br /&gt;
    integer RESET_INDICES       = 204003; &lt;br /&gt;
    integer SET_CELL_INFO       = 204004; &lt;br /&gt;
    integer SET_FONT_TEXTURE    = 204005; &lt;br /&gt;
    integer SET_THICKNESS       = 204006; &lt;br /&gt;
    integer SET_COLOR           = 204007; &lt;br /&gt;
&lt;br /&gt;
    llMessageLinked(LINK_SET,DISPLAY_STRING,message,line);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
clear_display() &lt;br /&gt;
{&lt;br /&gt;
    // Clears the display&lt;br /&gt;
    display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio Station ID&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;2&amp;quot;,&amp;quot;Music Genre....&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;3&amp;quot;,&amp;quot;Now Playing....&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
make_menu(key id)&lt;br /&gt;
{&lt;br /&gt;
     menu_channel=random_channel();&lt;br /&gt;
&lt;br /&gt;
    if (radio_status == 0)&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        llDialog(id,&amp;quot;Menu: Status\n\nRadio is OFF&amp;quot;, [ &amp;quot;ON&amp;quot;, &amp;quot;HELP&amp;quot; ],menu_channel);&lt;br /&gt;
    }&lt;br /&gt;
    else &lt;br /&gt;
    {&lt;br /&gt;
        if (menu_type ==0)&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Genres&amp;quot;, category_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Stations\nGenre: &amp;quot; + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (listen_handle != 0)    llListenRemove(listen_handle);&lt;br /&gt;
    listen_handle=llListen(menu_channel,&amp;quot;&amp;quot;,id,&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
list category_menu(integer num)&lt;br /&gt;
{   // compile menu list of category list&lt;br /&gt;
    // if there are more catagories then can be displayed in the menu&lt;br /&gt;
    // compile a submenu, including options for main menu and more and a blank item.&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
&lt;br /&gt;
    if (len &amp;gt; 9)&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;   // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc. &lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt; last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
&lt;br /&gt;
             while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_HELP;&lt;br /&gt;
             else&lt;br /&gt;
                 menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_OFF;&lt;br /&gt;
             else&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num != last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;       &lt;br /&gt;
        }            &lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
        menu+=(list)button_OFF;&lt;br /&gt;
        menu+=(list)button_HELP;&lt;br /&gt;
    }        &lt;br /&gt;
    &lt;br /&gt;
    return menu;    // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer stations_in_category(integer cat)&lt;br /&gt;
{&lt;br /&gt;
    integer count=0;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
    string category=llList2String(category_list,cat);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (category == llList2String(category_list,i))&lt;br /&gt;
            count++;&lt;br /&gt;
&lt;br /&gt;
    return count;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
list order_buttons(list buttons)&lt;br /&gt;
{&lt;br /&gt;
    integer offset;&lt;br /&gt;
    list fixt;&lt;br /&gt;
    integer flag=0;&lt;br /&gt;
&lt;br /&gt;
    while((offset = llGetListLength(buttons)))&lt;br /&gt;
    {&lt;br /&gt;
        if (offset &amp;gt; 3)&lt;br /&gt;
            flag=1;&lt;br /&gt;
        else&lt;br /&gt;
            flag=0;&lt;br /&gt;
&lt;br /&gt;
        fixt += llList2List(buttons, offset = -3 * flag, -1);&lt;br /&gt;
        buttons = llDeleteSubList(buttons, offset, -1);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return fixt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
list station_list(integer category)&lt;br /&gt;
{&lt;br /&gt;
    list s=[];&lt;br /&gt;
    integer i;&lt;br /&gt;
    string cname=llList2String(category_list,category_index);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; llGetListLength(station_name); i++)&lt;br /&gt;
        if (llList2String(station_category,i) == cname)&lt;br /&gt;
            s+=(list)llList2String(station_name,i);&lt;br /&gt;
&lt;br /&gt;
    return s;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
list station_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
   // compile menu list of station names&lt;br /&gt;
    // if there are more stations then can be displayed in the menu&lt;br /&gt;
    // compile a submenu, including options for main menu and more and a blank item.&lt;br /&gt;
&lt;br /&gt;
    list stations=station_list(category_index);&lt;br /&gt;
    integer len=llGetListLength(stations);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
&lt;br /&gt;
    llSay(0,&amp;quot;Category: &amp;quot; + llList2String(category_list,category_index));&lt;br /&gt;
    llSay(0,&amp;quot;Stations: &amp;quot; + llDumpList2String(stations,&amp;quot;,&amp;quot;));&lt;br /&gt;
        &lt;br /&gt;
    if (len &amp;gt; 11)&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;&lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt;= last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
             integer last=9*num+8;&lt;br /&gt;
&lt;br /&gt;
             menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;gt; 0)&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;lt; last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;                      &lt;br /&gt;
&lt;br /&gt;
            if (len &amp;gt; last)&lt;br /&gt;
                len =last;&lt;br /&gt;
                &lt;br /&gt;
            while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(stations,len);&lt;br /&gt;
        }&lt;br /&gt;
    }            &lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(stations,len);&lt;br /&gt;
    }        &lt;br /&gt;
&lt;br /&gt;
    return menu; // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer has_access(key id)&lt;br /&gt;
{&lt;br /&gt;
    if (llListFindList(banned_keys,(list)id) != -1)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    if (owner_access &amp;amp;&amp;amp; id == llGetOwner())&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (group_access &amp;amp;&amp;amp; llSameGroup(id))&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (public_access)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer random_channel()&lt;br /&gt;
{&lt;br /&gt;
    integer min=-2147483647;&lt;br /&gt;
    integer max=-1000;&lt;br /&gt;
&lt;br /&gt;
    return (integer) (min + llFrand(max-min));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer check_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    integer pos=0;&lt;br /&gt;
&lt;br /&gt;
    if (llGetSubString(url,0,6) == &amp;quot;http://&amp;quot;)&lt;br /&gt;
        pos=7;        &lt;br /&gt;
    if (llGetSubString(url,0,7) == &amp;quot;https://&amp;quot;)&lt;br /&gt;
        pos=8;&lt;br /&gt;
&lt;br /&gt;
    if (pos==0)   return FALSE;&lt;br /&gt;
&lt;br /&gt;
    string str_ip_port=llGetSubString(url,pos,-1);&lt;br /&gt;
    list list_ip_port=llParseString2List(str_ip_port,[&amp;quot;:&amp;quot;],[]);                    // split in ip-adress and port&lt;br /&gt;
    list list_ip=llParseString2List(llList2String(list_ip_port,0),[&amp;quot;.&amp;quot;],[]);    // split ip-adress elements&lt;br /&gt;
&lt;br /&gt;
    if (llGetListLength(list_ip_port) != 2 || llGetListLength(list_ip) != 4)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer test;&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;4;i++)&lt;br /&gt;
    {&lt;br /&gt;
        test=llList2Integer(list_ip,i);&lt;br /&gt;
        if (llList2String(list_ip,i) != (string)test)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        if (test &amp;lt; 0 || test &amp;gt; 255)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    test=llList2Integer(list_ip_port,1);&lt;br /&gt;
    if (llList2String(list_ip_port,1) != (string)test)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer true_value(string input)&lt;br /&gt;
{&lt;br /&gt;
    string value=llToLower(llGetSubString(input,0,0));&lt;br /&gt;
&lt;br /&gt;
    if (value == &amp;quot;y&amp;quot; || value == &amp;quot;t&amp;quot; || value ==&amp;quot;1&amp;quot;)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer process_line(string dataline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(dataline,STRING_TRIM);&lt;br /&gt;
    integer index=llSubStringIndex(line,comment_char);&lt;br /&gt;
    &lt;br /&gt;
    if (index==0)       // line starts with comment - ignore line&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (index!=-1)&lt;br /&gt;
        line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL);   // skip everything after comment_char and trim tail&lt;br /&gt;
&lt;br /&gt;
    if (line==&amp;quot;&amp;quot;)       // Ignore blank lines&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (llToLower(line) == &amp;quot;[access]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 1;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[banned]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 2;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[genre]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 3;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[station]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 4;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llGetSubString(line,0,0) == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; llGetSubString(line,-1,-1) == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: malformed section found at line &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
        config_error=TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: no section found on line: &amp;quot; + (string) lineno);&lt;br /&gt;
        config_error = TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    list breakup=llParseString2List(line,[&amp;quot;=&amp;quot;],[]);&lt;br /&gt;
    string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);&lt;br /&gt;
    string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);&lt;br /&gt;
&lt;br /&gt;
    if (section == 1)            // access&lt;br /&gt;
    {&lt;br /&gt;
        field=llToLower(field);&lt;br /&gt;
&lt;br /&gt;
        if (field==&amp;quot;owner&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            owner_access=true_value(values);                       &lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;group&amp;quot;)&lt;br /&gt;
        {    &lt;br /&gt;
            group_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;public&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            public_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: invalid option on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 2)         // ban list&lt;br /&gt;
    {&lt;br /&gt;
        key try=(key) field;&lt;br /&gt;
&lt;br /&gt;
        if (try)&lt;br /&gt;
        {&lt;br /&gt;
            banned_keys+=(list)((key) field);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 3)           // categories&lt;br /&gt;
    {&lt;br /&gt;
        if (llListFindList(category_list,(list)field) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            category_list+=(list)field;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;genre: &#039;&amp;quot; + field + &amp;quot;&#039; already entered; double entry skipped.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 4)            // stations&lt;br /&gt;
    {&lt;br /&gt;
        list parse=llParseString2List(line,sep_char_list, []);&lt;br /&gt;
        string category=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);&lt;br /&gt;
        string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);&lt;br /&gt;
    &lt;br /&gt;
        if (!available_category(category))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: unknown genre on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (check_url(url))&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                num_stations++;&lt;br /&gt;
                station_category+=(list)category;&lt;br /&gt;
                station_name+=(list)name;&lt;br /&gt;
                station_desc+=(list)desc;&lt;br /&gt;
                station_url+=(list)url;&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llWhisper(0,&amp;quot;This station is already entered under the same genre and same url and is skipped.\nStation: &amp;quot; + name + &amp;quot;\nGenre: &#039;&amp;quot; + category + &amp;quot;&#039;\nURL: &amp;quot; + url);&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: malformed url on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
     &lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
set_parcel_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    parcel_url=url;&lt;br /&gt;
    llSetParcelMusicURL(parcel_url);&lt;br /&gt;
&lt;br /&gt;
    if (parcel_url==&amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        clear_display();&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is OFF&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;station now set to &amp;quot; + llList2String(station_desc,station_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Station: &amp;quot; + llList2String(station_desc,station_index));&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;Genre  : &amp;quot; + llList2String(category_list,category_index));&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;Now playing.....&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer available_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;len;i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(category_list,i)))&lt;br /&gt;
            return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer empty_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(station_category,i)))&lt;br /&gt;
            return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
skip_empty_categories()&lt;br /&gt;
{&lt;br /&gt;
    integer i=0;&lt;br /&gt;
&lt;br /&gt;
    while (i&amp;lt;llGetListLength(category_list))&lt;br /&gt;
    {&lt;br /&gt;
        if (empty_category(llList2String(category_list,i)))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;Warning: Genre &#039;&amp;quot; + llList2String(category_list,i) + &amp;quot;&#039; contains no stations and is deleted.&amp;quot;);&lt;br /&gt;
            category_list=llDeleteSubList(category_list,i,i);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            i++;&lt;br /&gt;
    }&lt;br /&gt;
            &lt;br /&gt;
    num_categories=llGetListLength(category_list);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state default&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        flag=FALSE;&lt;br /&gt;
        lineno=0;&lt;br /&gt;
        config_error=FALSE;&lt;br /&gt;
        num_stations=0;&lt;br /&gt;
        num_categories=0;&lt;br /&gt;
        radio_status=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(config_notecard) != INVENTORY_NONE)&lt;br /&gt;
        {&lt;br /&gt;
           reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
           llWhisper(0, &amp;quot;Reading config notecard...&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;1&amp;quot;,&amp;quot;Reading configuration.&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;2&amp;quot;,&amp;quot;Wait....&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;No config notecard &#039;&amp;quot; +  config_notecard + &amp;quot;&#039; present.&amp;quot;);&lt;br /&gt;
            state offline;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (reqid==id)&lt;br /&gt;
        {        &lt;br /&gt;
            if (data==EOF)&lt;br /&gt;
            {&lt;br /&gt;
                skip_empty_categories();&lt;br /&gt;
                llWhisper(0,&amp;quot;Configuration ok.\n&amp;quot; + (string)num_categories + &amp;quot; genres and &amp;quot; + (string)num_stations + &amp;quot; stations.&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Configuration OK&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;2&amp;quot;,&amp;quot;Genres  : &amp;quot; + (string)num_categories);&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Stations: &amp;quot; + (string)num_stations);&lt;br /&gt;
                state menu;&lt;br /&gt;
            }&lt;br /&gt;
            else &lt;br /&gt;
            {&lt;br /&gt;
                if (process_line(data))&lt;br /&gt;
                    reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
                else if (config_error)&lt;br /&gt;
                {&lt;br /&gt;
                    llWhisper(0,&amp;quot;errors found in configuration. please correct them.&amp;quot;);&lt;br /&gt;
                    state offline;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY &amp;amp;&amp;amp; flag)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state offline&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state offline&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;Reset on owner touch.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    touch_start(integer t)&lt;br /&gt;
   {&lt;br /&gt;
        if (llDetectedKey(0)==llGetOwner())&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state menu&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state menu&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        listen_handle=0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        if (param &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
        key toucher=llDetectedKey(0);&lt;br /&gt;
&lt;br /&gt;
        if (has_access(toucher))&lt;br /&gt;
        {&lt;br /&gt;
            make_menu(toucher);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;sorry, no access.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    listen(integer chan, string name,key id,string msg)&lt;br /&gt;
    {&lt;br /&gt;
        integer index;&lt;br /&gt;
&lt;br /&gt;
        if (menu_type == 0)          // main menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_ON)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=1;&lt;br /&gt;
                set_parcel_url(parcel_url);               &lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is ON&amp;quot;);&lt;br /&gt;
                menu_num=0;&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned on.&amp;quot;);&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=0;&lt;br /&gt;
                set_parcel_url(&amp;quot;&amp;quot;);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned off.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
                {&lt;br /&gt;
                    llGiveInventory(id,info_notecard);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                    llWhisper(0,&amp;quot;sorry, help not available.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (radio_status == 1)&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(category_list, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: genre not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    category_index=index;&lt;br /&gt;
                    llWhisper(0,&amp;quot;Genre now set to &amp;quot; + llList2String(category_list,category_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
                    menu_type=1;&lt;br /&gt;
                    menu_num=0;&lt;br /&gt;
                    make_menu(id);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (menu_type == 1 &amp;amp;&amp;amp; radio_status == 1)     // station menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(station_name, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: station not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    station_index=index;&lt;br /&gt;
                    string new_url=llList2String(station_url,station_index);&lt;br /&gt;
&lt;br /&gt;
                    if (new_url != parcel_url)&lt;br /&gt;
                    {&lt;br /&gt;
                        set_parcel_url(new_url);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        retrieve_titelinfo();&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_response(key id, integer status, list meta, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == httpreq_id)&lt;br /&gt;
        {&lt;br /&gt;
            if (status == 200)&lt;br /&gt;
            {&lt;br /&gt;
                string feed = llGetSubString(body,llSubStringIndex(body, &amp;quot;&amp;lt;body&amp;gt;&amp;quot;) + llStringLength(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;), llSubStringIndex(body,&amp;quot;&amp;lt;/body&amp;gt;&amp;quot;) - 1);&lt;br /&gt;
                list feed_list = llParseString2List(feed,[&amp;quot;,&amp;quot;],[]);&lt;br /&gt;
                string current_title_info= llList2String(feed_list,6);&lt;br /&gt;
                integer length = llGetListLength(feed_list);&lt;br /&gt;
        &lt;br /&gt;
                if(llList2String(feed_list,7))&lt;br /&gt;
                {&lt;br /&gt;
                    integer a = 7;&lt;br /&gt;
                    for(; a&amp;lt;length; ++a)&lt;br /&gt;
                    {&lt;br /&gt;
                        current_title_info += &amp;quot;, &amp;quot; + llList2String(feed_list,a);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
         &lt;br /&gt;
                if (current_title_info != last_title_info)&lt;br /&gt;
                {&lt;br /&gt;
                    last_title_info = current_title_info;&lt;br /&gt;
                    display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + current_title_info);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + no_title_info);&lt;br /&gt;
            }&lt;br /&gt;
        }    &lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
// end of script&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example notecard&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# New format Shoutcast - radio controller config notecard&lt;br /&gt;
# The format is divided in 4 sections:&lt;br /&gt;
# 1 - Access configuration&lt;br /&gt;
# 2 - Ban list (keys)&lt;br /&gt;
# 3 - Categories  (same as genres)&lt;br /&gt;
# 4 - Station info (category, name, desc, url)&lt;br /&gt;
# The &#039;#&#039; character defines the start of a comment and can be anywhere on a line. &lt;br /&gt;
# Everything after the &#039;#&#039; incuding the &#039;#&#039; itself is ignored.&lt;br /&gt;
# Case is not important (but information on display will show as entered)&lt;br /&gt;
# Spaces before and/or after fields are trimmed.&lt;br /&gt;
# Empty lines are ignored.&lt;br /&gt;
&lt;br /&gt;
[ACCESS]&lt;br /&gt;
owner=yes       # yes, true,1      means owner has access. everything else not.&lt;br /&gt;
group=yes       #  ,,  ,,  ,,      means group has acess.    ,,        ,,   ,,&lt;br /&gt;
public=yes      #  ,,  ,,  ,,      means public has access.  ,,        ,,   ,, &lt;br /&gt;
&lt;br /&gt;
[BANNED]&lt;br /&gt;
# keys of banned residents&lt;br /&gt;
&lt;br /&gt;
[GENRE]&lt;br /&gt;
# genre name&lt;br /&gt;
Hard Rock&lt;br /&gt;
Classic Rock&lt;br /&gt;
Oldies&lt;br /&gt;
Rap/Urban&lt;br /&gt;
Comedy&lt;br /&gt;
News&lt;br /&gt;
Dance&lt;br /&gt;
Country&lt;br /&gt;
Gothic&lt;br /&gt;
# etc.&lt;br /&gt;
[STATION]&lt;br /&gt;
# Shoutcast radio stations&lt;br /&gt;
# Use a &#039;|&#039; between each field - don&#039;t mind spaces before and after fields, they will be trimmed&lt;br /&gt;
# field1:genre, field2:station name, field3: station description, field4: station url+port&lt;br /&gt;
# Note that genre must match case-insensitive a value in [GENRE] &lt;br /&gt;
Classic Rock    | Absolute         |    Absolute Radio                  | http://205.188.215.226:8018&lt;br /&gt;
# etc.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===TODO===&lt;br /&gt;
&lt;br /&gt;
* Add a llRegionSay to broadcast the station/genre/current songtitle to the region and write a script that displays that info on an Xytext board.&lt;/div&gt;</description>
			<pubDate>Wed, 09 Feb 2011 22:08:59 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)</comments>
		</item>
		<item>
			<title>Shoutcast - radio controller v0.3 (remake of similar scripts)</title>
			<link>https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133904</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133904</guid>
			<description>&lt;p&gt;Flennan Roffo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}}&lt;br /&gt;
This script controls a shoutcast radio receiver and lets you select the stations that you configured on a notecard. Menu driven. Output of station description, genre and current song title using Xy text.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// Shoutcast - radio controller v0.3&lt;br /&gt;
// Logic Scripts (Flennan Roffo)&lt;br /&gt;
// (c) 2010 - Flennan Roffo (Logic Scripts)&lt;br /&gt;
// &lt;br /&gt;
// Remake of similar script:&lt;br /&gt;
// + LandOwnersRadio V2.0 by Scripter Coba  (( menu driven / notecard config script to select the radio station and sets parcel music url ))&lt;br /&gt;
// + Raven radio infoboard by Jamie Otis    (( worked at the basis of sis service [sis.slserver.com/sis.php] used Xy text display         ))&lt;br /&gt;
// + currentPlaying by Darkie Minotaur      (( used the /7.html info to fetch current song title info, displayed as float text            ))&lt;br /&gt;
//&lt;br /&gt;
// Purpose:&lt;br /&gt;
// * Sets the parcel audio URL and displays the channel info&lt;br /&gt;
// * Uses Xytext to display the info.&lt;br /&gt;
// * Fetches song title info from the shoutcast url&lt;br /&gt;
// Extra Features -- 0.1 release&lt;br /&gt;
// * On/Off option&lt;br /&gt;
// * Allows multiple menus (if options per menu &amp;gt; 12) using a prev/next button&lt;br /&gt;
// * Checks if your url is well-formatted&lt;br /&gt;
// * Will delete genres for which no stations exist&lt;br /&gt;
// * Will skip stations that have same url and same genre (you can however have an identical station url under different genres).&lt;br /&gt;
// * New notecard format&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.2 release&lt;br /&gt;
// * Configurable button text&lt;br /&gt;
// * Gets parcel URL and automatically sets the genre/station and on/off status accordingly (&amp;lt;-- doesn&#039;t work)&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Update -- 0.3 release&lt;br /&gt;
// * Fixed bug (only first station in genre displayed in menu)&lt;br /&gt;
// * Auto reset script when config card updated&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
//&lt;br /&gt;
// This program is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string info_notecard=&amp;quot;Radio Control info&amp;quot;;              ///////    EDITABLE  \\\\\\&lt;br /&gt;
string config_notecard=&amp;quot;Radio Control config&amp;quot;;          ///////    EDITABLE  \\\\\\&lt;br /&gt;
string comment_char=&amp;quot;#&amp;quot;;                                ///////    EDITABLE  \\\\\\&lt;br /&gt;
list sep_char_list= [&amp;quot;|&amp;quot;];                              ///////    EDITABLE  \\\\\\&lt;br /&gt;
float update_time=5.0;                                  ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string no_title_info=&amp;quot;(no title info available)&amp;quot;;       ///////    EDITABLE  \\\\\\&lt;br /&gt;
&lt;br /&gt;
// not used currently - for showing info on current song title elsewhere in the region&lt;br /&gt;
integer broadcast_channel=-1234;                        ///////    EDITABLE  \\\\\\ &lt;br /&gt;
&lt;br /&gt;
// Buttons&lt;br /&gt;
&lt;br /&gt;
string button_MAIN = &amp;quot;MAIN&amp;quot;;&lt;br /&gt;
string button_HELP = &amp;quot;HELP&amp;quot;;&lt;br /&gt;
string button_NEXT = &amp;quot;&amp;gt;&amp;gt;&amp;quot;;&lt;br /&gt;
string button_PREV = &amp;quot;&amp;lt;&amp;lt;&amp;quot;;&lt;br /&gt;
string button_ON   = &amp;quot;ON&amp;quot;;&lt;br /&gt;
string button_OFF  = &amp;quot;OFF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Lists&lt;br /&gt;
&lt;br /&gt;
list category_list=[];&lt;br /&gt;
&lt;br /&gt;
list station_category=[];&lt;br /&gt;
list station_name=[];&lt;br /&gt;
list station_desc=[];&lt;br /&gt;
list station_url=[];&lt;br /&gt;
&lt;br /&gt;
string last_title_info=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
integer radio_status=0;&lt;br /&gt;
string parcel_url=&amp;quot;&amp;quot;;&lt;br /&gt;
integer lineno=0;&lt;br /&gt;
key reqid=NULL_KEY;&lt;br /&gt;
key httpreq_id=NULL_KEY;&lt;br /&gt;
integer config_error=FALSE;&lt;br /&gt;
integer flag;&lt;br /&gt;
integer section=0;&lt;br /&gt;
integer owner_access=TRUE;&lt;br /&gt;
integer group_access=FALSE;&lt;br /&gt;
integer public_access=TRUE;&lt;br /&gt;
list banned_keys=[];&lt;br /&gt;
&lt;br /&gt;
integer menu_channel;&lt;br /&gt;
integer listen_handle;&lt;br /&gt;
integer menu_type=0;&lt;br /&gt;
integer menu_num=0;&lt;br /&gt;
integer category_index=0;&lt;br /&gt;
integer station_index=0;&lt;br /&gt;
&lt;br /&gt;
integer num_categories=0;&lt;br /&gt;
integer num_stations=0;&lt;br /&gt;
&lt;br /&gt;
retrieve_titelinfo()&lt;br /&gt;
{&lt;br /&gt;
    string url=llList2String(station_url,station_index);&lt;br /&gt;
    httpreq_id=llHTTPRequest(url + &amp;quot;/7.html  HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n&amp;quot;,[],&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
display_line(string line, string message)&lt;br /&gt;
{&lt;br /&gt;
    // Setup XYtext Variables&lt;br /&gt;
    integer DISPLAY_STRING      = 204000; &lt;br /&gt;
    integer DISPLAY_EXTENDED    = 204001; &lt;br /&gt;
    integer REMAP_INDICES       = 204002; &lt;br /&gt;
    integer RESET_INDICES       = 204003; &lt;br /&gt;
    integer SET_CELL_INFO       = 204004; &lt;br /&gt;
    integer SET_FONT_TEXTURE    = 204005; &lt;br /&gt;
    integer SET_THICKNESS       = 204006; &lt;br /&gt;
    integer SET_COLOR           = 204007; &lt;br /&gt;
&lt;br /&gt;
    llMessageLinked(LINK_SET,DISPLAY_STRING,message,line);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
clear_display() &lt;br /&gt;
{&lt;br /&gt;
    // Clears the display&lt;br /&gt;
    display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio Station ID&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;2&amp;quot;,&amp;quot;Music Genre....&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;3&amp;quot;,&amp;quot;Now Playing....&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
make_menu(key id)&lt;br /&gt;
{&lt;br /&gt;
     menu_channel=random_channel();&lt;br /&gt;
&lt;br /&gt;
    if (radio_status == 0)&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        llDialog(id,&amp;quot;Menu: Status\n\nRadio is OFF&amp;quot;, [ &amp;quot;ON&amp;quot;, &amp;quot;HELP&amp;quot; ],menu_channel);&lt;br /&gt;
    }&lt;br /&gt;
    else &lt;br /&gt;
    {&lt;br /&gt;
        if (menu_type ==0)&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Genres&amp;quot;, category_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Stations\nGenre: &amp;quot; + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (listen_handle != 0)    llListenRemove(listen_handle);&lt;br /&gt;
    listen_handle=llListen(menu_channel,&amp;quot;&amp;quot;,id,&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
list category_menu(integer num)&lt;br /&gt;
{   // compile menu list of category list&lt;br /&gt;
    // if there are more catagories then can be displayed in the menu&lt;br /&gt;
    // compile a submenu, including options for main menu and more and a blank item.&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
&lt;br /&gt;
    if (len &amp;gt; 9)&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;   // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc. &lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt; last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
&lt;br /&gt;
             while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_HELP;&lt;br /&gt;
             else&lt;br /&gt;
                 menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_OFF;&lt;br /&gt;
             else&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num != last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;       &lt;br /&gt;
        }            &lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
        menu+=(list)button_OFF;&lt;br /&gt;
        menu+=(list)button_HELP;&lt;br /&gt;
    }        &lt;br /&gt;
    &lt;br /&gt;
    return menu;    // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer stations_in_category(integer cat)&lt;br /&gt;
{&lt;br /&gt;
    integer count=0;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
    string category=llList2String(category_list,cat);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (category == llList2String(category_list,i))&lt;br /&gt;
            count++;&lt;br /&gt;
&lt;br /&gt;
    return count;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
list order_buttons(list buttons)&lt;br /&gt;
{&lt;br /&gt;
    integer offset;&lt;br /&gt;
    list fixt;&lt;br /&gt;
    integer flag=0;&lt;br /&gt;
&lt;br /&gt;
    while((offset = llGetListLength(buttons)))&lt;br /&gt;
    {&lt;br /&gt;
        if (offset &amp;gt; 3)&lt;br /&gt;
            flag=1;&lt;br /&gt;
        else&lt;br /&gt;
            flag=0;&lt;br /&gt;
&lt;br /&gt;
        fixt += llList2List(buttons, offset = -3 * flag, -1);&lt;br /&gt;
        buttons = llDeleteSubList(buttons, offset, -1);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return fixt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
list station_list(integer category)&lt;br /&gt;
{&lt;br /&gt;
    list s=[];&lt;br /&gt;
    integer i;&lt;br /&gt;
    string cname=llList2String(category_list,category_index);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; llGetListLength(station_name); i++)&lt;br /&gt;
        if (llList2String(station_category,i) == cname)&lt;br /&gt;
            s+=(list)llList2String(station_name,i);&lt;br /&gt;
&lt;br /&gt;
    return s;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
list station_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
   // compile menu list of station names&lt;br /&gt;
    // if there are more stations then can be displayed in the menu&lt;br /&gt;
    // compile a submenu, including options for main menu and more and a blank item.&lt;br /&gt;
&lt;br /&gt;
    list stations=station_list(category_index);&lt;br /&gt;
    integer len=llGetListLength(stations);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
&lt;br /&gt;
    llSay(0,&amp;quot;Category: &amp;quot; + llList2String(category_list,category_index));&lt;br /&gt;
    llSay(0,&amp;quot;Stations: &amp;quot; + llDumpList2String(stations,&amp;quot;,&amp;quot;));&lt;br /&gt;
        &lt;br /&gt;
    if (len &amp;gt; 11)&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;&lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt;= last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
             integer last=9*num+8;&lt;br /&gt;
&lt;br /&gt;
             menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;gt; 0)&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;lt; last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;                      &lt;br /&gt;
&lt;br /&gt;
            if (len &amp;gt; last)&lt;br /&gt;
                len =last;&lt;br /&gt;
                &lt;br /&gt;
            while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(stations,len);&lt;br /&gt;
        }&lt;br /&gt;
    }            &lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(stations,len);&lt;br /&gt;
    }        &lt;br /&gt;
&lt;br /&gt;
    return menu; // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer has_access(key id)&lt;br /&gt;
{&lt;br /&gt;
    if (llListFindList(banned_keys,(list)id) != -1)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    if (owner_access &amp;amp;&amp;amp; id == llGetOwner())&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (group_access &amp;amp;&amp;amp; llSameGroup(id))&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (public_access)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer random_channel()&lt;br /&gt;
{&lt;br /&gt;
    integer min=-2147483647;&lt;br /&gt;
    integer max=-1000;&lt;br /&gt;
&lt;br /&gt;
    return (integer) (min + llFrand(max-min));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer check_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    integer pos=0;&lt;br /&gt;
&lt;br /&gt;
    if (llGetSubString(url,0,6) == &amp;quot;http://&amp;quot;)&lt;br /&gt;
        pos=7;        &lt;br /&gt;
    if (llGetSubString(url,0,7) == &amp;quot;https://&amp;quot;)&lt;br /&gt;
        pos=8;&lt;br /&gt;
&lt;br /&gt;
    if (pos==0)   return FALSE;&lt;br /&gt;
&lt;br /&gt;
    string str_ip_port=llGetSubString(url,pos,-1);&lt;br /&gt;
    list list_ip_port=llParseString2List(str_ip_port,[&amp;quot;:&amp;quot;],[]);                    // split in ip-adress and port&lt;br /&gt;
    list list_ip=llParseString2List(llList2String(list_ip_port,0),[&amp;quot;.&amp;quot;],[]);    // split ip-adress elements&lt;br /&gt;
&lt;br /&gt;
    if (llGetListLength(list_ip_port) != 2 || llGetListLength(list_ip) != 4)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer test;&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;4;i++)&lt;br /&gt;
    {&lt;br /&gt;
        test=llList2Integer(list_ip,i);&lt;br /&gt;
        if (llList2String(list_ip,i) != (string)test)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        if (test &amp;lt; 0 || test &amp;gt; 255)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    test=llList2Integer(list_ip_port,1);&lt;br /&gt;
    if (llList2String(list_ip_port,1) != (string)test)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer true_value(string input)&lt;br /&gt;
{&lt;br /&gt;
    string value=llToLower(llGetSubString(input,0,0));&lt;br /&gt;
&lt;br /&gt;
    if (value == &amp;quot;y&amp;quot; || value == &amp;quot;t&amp;quot; || value ==&amp;quot;1&amp;quot;)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer process_line(string dataline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(dataline,STRING_TRIM);&lt;br /&gt;
    integer index=llSubStringIndex(line,comment_char);&lt;br /&gt;
    &lt;br /&gt;
    if (index==0)       // line starts with comment - ignore line&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (index!=-1)&lt;br /&gt;
        line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL);   // skip everything after comment_char and trim tail&lt;br /&gt;
&lt;br /&gt;
    if (line==&amp;quot;&amp;quot;)       // Ignore blank lines&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (llToLower(line) == &amp;quot;[access]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 1;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[banned]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 2;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[genre]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 3;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[station]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 4;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llGetSubString(line,0,0) == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; llGetSubString(line,-1,-1) == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: malformed section found at line &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
        config_error=TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: no section found on line: &amp;quot; + (string) lineno);&lt;br /&gt;
        config_error = TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    list breakup=llParseString2List(line,[&amp;quot;=&amp;quot;],[]);&lt;br /&gt;
    string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);&lt;br /&gt;
    string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);&lt;br /&gt;
&lt;br /&gt;
    if (section == 1)            // access&lt;br /&gt;
    {&lt;br /&gt;
        field=llToLower(field);&lt;br /&gt;
&lt;br /&gt;
        if (field==&amp;quot;owner&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            owner_access=true_value(values);                       &lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;group&amp;quot;)&lt;br /&gt;
        {    &lt;br /&gt;
            group_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;public&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            public_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: invalid option on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 2)         // ban list&lt;br /&gt;
    {&lt;br /&gt;
        key try=(key) field;&lt;br /&gt;
&lt;br /&gt;
        if (try)&lt;br /&gt;
        {&lt;br /&gt;
            banned_keys+=(list)((key) field);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 3)           // categories&lt;br /&gt;
    {&lt;br /&gt;
        if (llListFindList(category_list,(list)field) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            category_list+=(list)field;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;genre: &#039;&amp;quot; + field + &amp;quot;&#039; already entered; double entry skipped.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 4)            // stations&lt;br /&gt;
    {&lt;br /&gt;
        list parse=llParseString2List(line,sep_char_list, []);&lt;br /&gt;
        string category=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);&lt;br /&gt;
        string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);&lt;br /&gt;
    &lt;br /&gt;
        if (!available_category(category))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: unknown genre on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (check_url(url))&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                num_stations++;&lt;br /&gt;
                station_category+=(list)category;&lt;br /&gt;
                station_name+=(list)name;&lt;br /&gt;
                station_desc+=(list)desc;&lt;br /&gt;
                station_url+=(list)url;&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llWhisper(0,&amp;quot;This station is already entered under the same genre and same url and is skipped.\nStation: &amp;quot; + name + &amp;quot;\nGenre: &#039;&amp;quot; + category + &amp;quot;&#039;\nURL: &amp;quot; + url);&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: malformed url on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
     &lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
set_parcel_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    parcel_url=url;&lt;br /&gt;
    llSetParcelMusicURL(parcel_url);&lt;br /&gt;
&lt;br /&gt;
    if (parcel_url==&amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        clear_display();&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is OFF&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;station now set to &amp;quot; + llList2String(station_desc,station_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Station: &amp;quot; + llList2String(station_desc,station_index));&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;Genre  : &amp;quot; + llList2String(category_list,category_index));&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;Now playing.....&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer available_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;len;i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(category_list,i)))&lt;br /&gt;
            return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer empty_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(station_category,i)))&lt;br /&gt;
            return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
skip_empty_categories()&lt;br /&gt;
{&lt;br /&gt;
    integer i=0;&lt;br /&gt;
&lt;br /&gt;
    while (i&amp;lt;llGetListLength(category_list))&lt;br /&gt;
    {&lt;br /&gt;
        if (empty_category(llList2String(category_list,i)))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;Warning: Genre &#039;&amp;quot; + llList2String(category_list,i) + &amp;quot;&#039; contains no stations and is deleted.&amp;quot;);&lt;br /&gt;
            category_list=llDeleteSubList(category_list,i,i);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            i++;&lt;br /&gt;
    }&lt;br /&gt;
            &lt;br /&gt;
    num_categories=llGetListLength(category_list);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state default&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        flag=FALSE;&lt;br /&gt;
        lineno=0;&lt;br /&gt;
        config_error=FALSE;&lt;br /&gt;
        num_stations=0;&lt;br /&gt;
        num_categories=0;&lt;br /&gt;
        radio_status=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(config_notecard) != INVENTORY_NONE)&lt;br /&gt;
        {&lt;br /&gt;
           reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
           llWhisper(0, &amp;quot;Reading config notecard...&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;1&amp;quot;,&amp;quot;Reading configuration.&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;2&amp;quot;,&amp;quot;Wait....&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;No config notecard &#039;&amp;quot; +  config_notecard + &amp;quot;&#039; present.&amp;quot;);&lt;br /&gt;
            state offline;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (reqid==id)&lt;br /&gt;
        {        &lt;br /&gt;
            if (data==EOF)&lt;br /&gt;
            {&lt;br /&gt;
                skip_empty_categories();&lt;br /&gt;
                llWhisper(0,&amp;quot;Configuration ok.\n&amp;quot; + (string)num_categories + &amp;quot; genres and &amp;quot; + (string)num_stations + &amp;quot; stations.&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Configuration OK&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;2&amp;quot;,&amp;quot;Genres  : &amp;quot; + (string)num_categories);&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Stations: &amp;quot; + (string)num_stations);&lt;br /&gt;
                state menu;&lt;br /&gt;
            }&lt;br /&gt;
            else &lt;br /&gt;
            {&lt;br /&gt;
                if (process_line(data))&lt;br /&gt;
                    reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
                else if (config_error)&lt;br /&gt;
                {&lt;br /&gt;
                    llWhisper(0,&amp;quot;errors found in configuration. please correct them.&amp;quot;);&lt;br /&gt;
                    state offline;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY &amp;amp;&amp;amp; flag)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state offline&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state offline&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;Reset on owner touch.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    touch_start(integer t)&lt;br /&gt;
   {&lt;br /&gt;
        if (llDetectedKey(0)==llGetOwner())&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state menu&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state menu&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        listen_handle=0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        if (param &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
        key toucher=llDetectedKey(0);&lt;br /&gt;
&lt;br /&gt;
        if (has_access(toucher))&lt;br /&gt;
        {&lt;br /&gt;
            make_menu(toucher);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;sorry, no access.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    listen(integer chan, string name,key id,string msg)&lt;br /&gt;
    {&lt;br /&gt;
        integer index;&lt;br /&gt;
&lt;br /&gt;
        if (menu_type == 0)          // main menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_ON)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=1;&lt;br /&gt;
                set_parcel_url(parcel_url);               &lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is ON&amp;quot;);&lt;br /&gt;
                menu_num=0;&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned on.&amp;quot;);&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=0;&lt;br /&gt;
                set_parcel_url(&amp;quot;&amp;quot;);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned off.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
                {&lt;br /&gt;
                    llGiveInventory(id,info_notecard);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                    llWhisper(0,&amp;quot;sorry, help not available.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (radio_status == 1)&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(category_list, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: genre not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    category_index=index;&lt;br /&gt;
                    llWhisper(0,&amp;quot;Genre now set to &amp;quot; + llList2String(category_list,category_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
                    menu_type=1;&lt;br /&gt;
                    menu_num=0;&lt;br /&gt;
                    make_menu(id);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (menu_type == 1 &amp;amp;&amp;amp; radio_status == 1)     // station menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(station_name, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: station not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    station_index=index;&lt;br /&gt;
                    string new_url=llList2String(station_url,station_index);&lt;br /&gt;
&lt;br /&gt;
                    if (new_url != parcel_url)&lt;br /&gt;
                    {&lt;br /&gt;
                        set_parcel_url(new_url);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        retrieve_titelinfo();&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_response(key id, integer status, list meta, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == httpreq_id)&lt;br /&gt;
        {&lt;br /&gt;
            if (status == 200)&lt;br /&gt;
            {&lt;br /&gt;
                string feed = llGetSubString(body,llSubStringIndex(body, &amp;quot;&amp;lt;body&amp;gt;&amp;quot;) + llStringLength(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;), llSubStringIndex(body,&amp;quot;&amp;lt;/body&amp;gt;&amp;quot;) - 1);&lt;br /&gt;
                list feed_list = llParseString2List(feed,[&amp;quot;,&amp;quot;],[]);&lt;br /&gt;
                string current_title_info= llList2String(feed_list,6);&lt;br /&gt;
                integer length = llGetListLength(feed_list);&lt;br /&gt;
        &lt;br /&gt;
                if(llList2String(feed_list,7))&lt;br /&gt;
                {&lt;br /&gt;
                    integer a = 7;&lt;br /&gt;
                    for(; a&amp;lt;length; ++a)&lt;br /&gt;
                    {&lt;br /&gt;
                        current_title_info += &amp;quot;, &amp;quot; + llList2String(feed_list,a);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
         &lt;br /&gt;
                if (current_title_info != last_title_info)&lt;br /&gt;
                {&lt;br /&gt;
                    last_title_info = current_title_info;&lt;br /&gt;
                    display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + current_title_info);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + no_title_info);&lt;br /&gt;
            }&lt;br /&gt;
        }    &lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
// end of script&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;/div&gt;</description>
			<pubDate>Wed, 09 Feb 2011 21:59:13 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)</comments>
		</item>
		<item>
			<title>Shoutcast - radio controller v0.3 (remake of similar scripts)</title>
			<link>https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133903</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133903</guid>
			<description>&lt;p&gt;Flennan Roffo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}}&lt;br /&gt;
This script controls a shoutcast radio receiver and lets you select the stations that you configured on a notecard. Menu driven. Output of station description, genre and current song title using Xy text.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// Shoutcast - radio controller v0.3&lt;br /&gt;
// Logic Scripts (Flennan Roffo)&lt;br /&gt;
// (c) 2010 - Flennan Roffo (Logic Scripts)&lt;br /&gt;
// &lt;br /&gt;
// Remake of similar script:&lt;br /&gt;
// + LandOwnersRadio V2.0 by Scripter Coba  (( menu driven / notecard config script to select the radio station and sets parcel music url ))&lt;br /&gt;
// + Raven radio infoboard by Jamie Otis    (( worked at the basis of sis service [sis.slserver.com/sis.php] used Xy text display         ))&lt;br /&gt;
// + currentPlaying by Darkie Minotaur      (( used the /7.html info to fetch current song title info, displayed as float text            ))&lt;br /&gt;
//&lt;br /&gt;
// Purpose:&lt;br /&gt;
// * Sets the parcel audio URL and displays the channel info&lt;br /&gt;
// * Uses Xytext to display the info.&lt;br /&gt;
// * Fetches song title info from the shoutcast url&lt;br /&gt;
// Extra Features -- 0.1 release&lt;br /&gt;
// * On/Off option&lt;br /&gt;
// * Allows multiple menus (if options per menu &amp;gt; 12) using a prev/next button&lt;br /&gt;
// * Checks if your url is well-formatted&lt;br /&gt;
// * Will delete genres for which no stations exist&lt;br /&gt;
// * Will skip stations that have same url and same genre (you can however have an identical station url under different genres).&lt;br /&gt;
// * New notecard format&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.2 release&lt;br /&gt;
// * Configurable button text&lt;br /&gt;
// * Gets parcel URL and automatically sets the genre/station and on/off status accordingly (&amp;lt;-- doesn&#039;t work)&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Update -- 0.3 release&lt;br /&gt;
// * Fixed bug (only first station in genre displayed in menu)&lt;br /&gt;
// * Auto reset script when config card updated&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
//&lt;br /&gt;
// This program is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DEBUG=0;&lt;br /&gt;
&lt;br /&gt;
string info_notecard=&amp;quot;Radio Control info&amp;quot;;              ///////    EDITABLE  \\\\\\&lt;br /&gt;
string config_notecard=&amp;quot;Radio Control config&amp;quot;;          ///////    EDITABLE  \\\\\\&lt;br /&gt;
string comment_char=&amp;quot;#&amp;quot;;                                ///////    EDITABLE  \\\\\\&lt;br /&gt;
list sep_char_list= [&amp;quot;|&amp;quot;];                              ///////    EDITABLE  \\\\\\&lt;br /&gt;
float update_time=5.0;                                  ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string no_title_info=&amp;quot;(no title info available)&amp;quot;;       ///////    EDITABLE  \\\\\\&lt;br /&gt;
&lt;br /&gt;
// not used currently - for showing info on current song title elsewhere in the region&lt;br /&gt;
integer broadcast_channel=-1234;                        ///////    EDITABLE  \\\\\\ &lt;br /&gt;
&lt;br /&gt;
// Buttons&lt;br /&gt;
&lt;br /&gt;
string button_MAIN = &amp;quot;MAIN&amp;quot;;&lt;br /&gt;
string button_HELP = &amp;quot;HELP&amp;quot;;&lt;br /&gt;
string button_NEXT = &amp;quot;&amp;gt;&amp;gt;&amp;quot;;&lt;br /&gt;
string button_PREV = &amp;quot;&amp;lt;&amp;lt;&amp;quot;;&lt;br /&gt;
string button_ON   = &amp;quot;ON&amp;quot;;&lt;br /&gt;
string button_OFF  = &amp;quot;OFF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Lists&lt;br /&gt;
&lt;br /&gt;
list category_list=[];&lt;br /&gt;
&lt;br /&gt;
list station_category=[];&lt;br /&gt;
list station_name=[];&lt;br /&gt;
list station_desc=[];&lt;br /&gt;
list station_url=[];&lt;br /&gt;
&lt;br /&gt;
string last_title_info=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
integer radio_status=0;&lt;br /&gt;
string parcel_url=&amp;quot;&amp;quot;;&lt;br /&gt;
integer lineno=0;&lt;br /&gt;
key reqid=NULL_KEY;&lt;br /&gt;
key httpreq_id=NULL_KEY;&lt;br /&gt;
integer config_error=FALSE;&lt;br /&gt;
integer flag;&lt;br /&gt;
integer section=0;&lt;br /&gt;
integer owner_access=TRUE;&lt;br /&gt;
integer group_access=FALSE;&lt;br /&gt;
integer public_access=TRUE;&lt;br /&gt;
list banned_keys=[];&lt;br /&gt;
&lt;br /&gt;
integer menu_channel;&lt;br /&gt;
integer listen_handle;&lt;br /&gt;
integer menu_type=0;&lt;br /&gt;
integer menu_num=0;&lt;br /&gt;
integer category_index=0;&lt;br /&gt;
integer station_index=0;&lt;br /&gt;
&lt;br /&gt;
integer num_categories=0;&lt;br /&gt;
integer num_stations=0;&lt;br /&gt;
&lt;br /&gt;
DebugSay(string msg)&lt;br /&gt;
{&lt;br /&gt;
    if (DEBUG)&lt;br /&gt;
        llSay(0,&amp;quot;(debug) &amp;quot; + msg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
retrieve_titelinfo()&lt;br /&gt;
{&lt;br /&gt;
    string url=llList2String(station_url,station_index);&lt;br /&gt;
    httpreq_id=llHTTPRequest(url + &amp;quot;/7.html  HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n&amp;quot;,[],&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
display_line(string line, string message)&lt;br /&gt;
{&lt;br /&gt;
    // Setup XYtext Variables&lt;br /&gt;
    integer DISPLAY_STRING      = 204000; &lt;br /&gt;
    integer DISPLAY_EXTENDED    = 204001; &lt;br /&gt;
    integer REMAP_INDICES       = 204002; &lt;br /&gt;
    integer RESET_INDICES       = 204003; &lt;br /&gt;
    integer SET_CELL_INFO       = 204004; &lt;br /&gt;
    integer SET_FONT_TEXTURE    = 204005; &lt;br /&gt;
    integer SET_THICKNESS       = 204006; &lt;br /&gt;
    integer SET_COLOR           = 204007; &lt;br /&gt;
&lt;br /&gt;
    llMessageLinked(LINK_SET,DISPLAY_STRING,message,line);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
clear_display() &lt;br /&gt;
{&lt;br /&gt;
    // Clears the display&lt;br /&gt;
    display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio Station ID&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;2&amp;quot;,&amp;quot;Music Genre....&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;3&amp;quot;,&amp;quot;Now Playing....&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
make_menu(key id)&lt;br /&gt;
{&lt;br /&gt;
     menu_channel=random_channel();&lt;br /&gt;
&lt;br /&gt;
    if (radio_status == 0)&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        llDialog(id,&amp;quot;Menu: Status\n\nRadio is OFF&amp;quot;, [ &amp;quot;ON&amp;quot;, &amp;quot;HELP&amp;quot; ],menu_channel);&lt;br /&gt;
    }&lt;br /&gt;
    else &lt;br /&gt;
    {&lt;br /&gt;
        if (menu_type ==0)&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Genres&amp;quot;, category_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Stations\nGenre: &amp;quot; + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (listen_handle != 0)    llListenRemove(listen_handle);&lt;br /&gt;
    listen_handle=llListen(menu_channel,&amp;quot;&amp;quot;,id,&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
list category_menu(integer num)&lt;br /&gt;
{   // compile menu list of category list&lt;br /&gt;
    // if there are more catagories then can be displayed in the menu&lt;br /&gt;
    // compile a submenu, including options for main menu and more and a blank item.&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
&lt;br /&gt;
    if (len &amp;gt; 9)&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;   // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc. &lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt; last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
&lt;br /&gt;
             while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_HELP;&lt;br /&gt;
             else&lt;br /&gt;
                 menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_OFF;&lt;br /&gt;
             else&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num != last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;       &lt;br /&gt;
        }            &lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
        menu+=(list)button_OFF;&lt;br /&gt;
        menu+=(list)button_HELP;&lt;br /&gt;
    }        &lt;br /&gt;
    &lt;br /&gt;
    DebugSay(&amp;quot;main menu: &amp;quot; + llList2CSV(menu));&lt;br /&gt;
&lt;br /&gt;
    return menu;    // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer stations_in_category(integer cat)&lt;br /&gt;
{&lt;br /&gt;
    integer count=0;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
    string category=llList2String(category_list,cat);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (category == llList2String(category_list,i))&lt;br /&gt;
            count++;&lt;br /&gt;
&lt;br /&gt;
    return count;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
list order_buttons(list buttons)&lt;br /&gt;
{&lt;br /&gt;
    integer offset;&lt;br /&gt;
    list fixt;&lt;br /&gt;
    integer flag=0;&lt;br /&gt;
&lt;br /&gt;
    while((offset = llGetListLength(buttons)))&lt;br /&gt;
    {&lt;br /&gt;
        if (offset &amp;gt; 3)&lt;br /&gt;
            flag=1;&lt;br /&gt;
        else&lt;br /&gt;
            flag=0;&lt;br /&gt;
&lt;br /&gt;
        fixt += llList2List(buttons, offset = -3 * flag, -1);&lt;br /&gt;
        buttons = llDeleteSubList(buttons, offset, -1);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return fixt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
list station_list(integer category)&lt;br /&gt;
{&lt;br /&gt;
    list s=[];&lt;br /&gt;
    integer i;&lt;br /&gt;
    string cname=llList2String(category_list,category_index);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; llGetListLength(station_name); i++)&lt;br /&gt;
        if (llList2String(station_category,i) == cname)&lt;br /&gt;
            s+=(list)llList2String(station_name,i);&lt;br /&gt;
&lt;br /&gt;
    return s;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
list station_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
   // compile menu list of station names&lt;br /&gt;
    // if there are more stations then can be displayed in the menu&lt;br /&gt;
    // compile a submenu, including options for main menu and more and a blank item.&lt;br /&gt;
&lt;br /&gt;
    list stations=station_list(category_index);&lt;br /&gt;
    integer len=llGetListLength(stations);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
&lt;br /&gt;
    llSay(0,&amp;quot;Category: &amp;quot; + llList2String(category_list,category_index));&lt;br /&gt;
    llSay(0,&amp;quot;Stations: &amp;quot; + llDumpList2String(stations,&amp;quot;,&amp;quot;));&lt;br /&gt;
        &lt;br /&gt;
    if (len &amp;gt; 11)&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;&lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt;= last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
             integer last=9*num+8;&lt;br /&gt;
&lt;br /&gt;
             menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;gt; 0)&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;lt; last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;                      &lt;br /&gt;
&lt;br /&gt;
            if (len &amp;gt; last)&lt;br /&gt;
                len =last;&lt;br /&gt;
                &lt;br /&gt;
            while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(stations,len);&lt;br /&gt;
        }&lt;br /&gt;
    }            &lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(stations,len);&lt;br /&gt;
    }        &lt;br /&gt;
&lt;br /&gt;
    DebugSay(&amp;quot;station menu: &amp;quot; + llList2CSV(menu));&lt;br /&gt;
        &lt;br /&gt;
    return menu; // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer has_access(key id)&lt;br /&gt;
{&lt;br /&gt;
    if (llListFindList(banned_keys,(list)id) != -1)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    if (owner_access &amp;amp;&amp;amp; id == llGetOwner())&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (group_access &amp;amp;&amp;amp; llSameGroup(id))&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (public_access)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer random_channel()&lt;br /&gt;
{&lt;br /&gt;
    integer min=-2147483647;&lt;br /&gt;
    integer max=-1000;&lt;br /&gt;
&lt;br /&gt;
    return (integer) (min + llFrand(max-min));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer check_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    integer pos=0;&lt;br /&gt;
&lt;br /&gt;
    if (llGetSubString(url,0,6) == &amp;quot;http://&amp;quot;)&lt;br /&gt;
        pos=7;        &lt;br /&gt;
    if (llGetSubString(url,0,7) == &amp;quot;https://&amp;quot;)&lt;br /&gt;
        pos=8;&lt;br /&gt;
&lt;br /&gt;
    if (pos==0)   return FALSE;&lt;br /&gt;
&lt;br /&gt;
    string str_ip_port=llGetSubString(url,pos,-1);&lt;br /&gt;
    list list_ip_port=llParseString2List(str_ip_port,[&amp;quot;:&amp;quot;],[]);                    // split in ip-adress and port&lt;br /&gt;
    list list_ip=llParseString2List(llList2String(list_ip_port,0),[&amp;quot;.&amp;quot;],[]);    // split ip-adress elements&lt;br /&gt;
&lt;br /&gt;
    if (llGetListLength(list_ip_port) != 2 || llGetListLength(list_ip) != 4)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer test;&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;4;i++)&lt;br /&gt;
    {&lt;br /&gt;
        test=llList2Integer(list_ip,i);&lt;br /&gt;
        if (llList2String(list_ip,i) != (string)test)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        if (test &amp;lt; 0 || test &amp;gt; 255)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    test=llList2Integer(list_ip_port,1);&lt;br /&gt;
    if (llList2String(list_ip_port,1) != (string)test)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer true_value(string input)&lt;br /&gt;
{&lt;br /&gt;
    string value=llToLower(llGetSubString(input,0,0));&lt;br /&gt;
&lt;br /&gt;
    if (value == &amp;quot;y&amp;quot; || value == &amp;quot;t&amp;quot; || value ==&amp;quot;1&amp;quot;)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer process_line(string dataline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(dataline,STRING_TRIM);&lt;br /&gt;
    integer index=llSubStringIndex(line,comment_char);&lt;br /&gt;
    &lt;br /&gt;
    if (index==0)       // line starts with comment - ignore line&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (index!=-1)&lt;br /&gt;
        line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL);   // skip everything after comment_char and trim tail&lt;br /&gt;
&lt;br /&gt;
    if (line==&amp;quot;&amp;quot;)       // Ignore blank lines&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (llToLower(line) == &amp;quot;[access]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 1;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[banned]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 2;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[genre]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 3;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[station]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 4;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llGetSubString(line,0,0) == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; llGetSubString(line,-1,-1) == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: malformed section found at line &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
        config_error=TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: no section found on line: &amp;quot; + (string) lineno);&lt;br /&gt;
        config_error = TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    list breakup=llParseString2List(line,[&amp;quot;=&amp;quot;],[]);&lt;br /&gt;
    string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);&lt;br /&gt;
    string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);&lt;br /&gt;
&lt;br /&gt;
    if (section == 1)            // access&lt;br /&gt;
    {&lt;br /&gt;
        field=llToLower(field);&lt;br /&gt;
&lt;br /&gt;
        if (field==&amp;quot;owner&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            owner_access=true_value(values);                       &lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;group&amp;quot;)&lt;br /&gt;
        {    &lt;br /&gt;
            group_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;public&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            public_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: invalid option on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 2)         // ban list&lt;br /&gt;
    {&lt;br /&gt;
        key try=(key) field;&lt;br /&gt;
&lt;br /&gt;
        if (try)&lt;br /&gt;
        {&lt;br /&gt;
            banned_keys+=(list)((key) field);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 3)           // categories&lt;br /&gt;
    {&lt;br /&gt;
//        DebugSay(&amp;quot;category: &#039;&amp;quot; + field + &amp;quot;&#039;&amp;quot;);&lt;br /&gt;
        if (llListFindList(category_list,(list)field) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            category_list+=(list)field;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;genre: &#039;&amp;quot; + field + &amp;quot;&#039; already entered; double entry skipped.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 4)            // stations&lt;br /&gt;
    {&lt;br /&gt;
        list parse=llParseString2List(line,sep_char_list, []);&lt;br /&gt;
        string category=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);&lt;br /&gt;
        string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);&lt;br /&gt;
    &lt;br /&gt;
        if (!available_category(category))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: unknown genre on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            DebugSay(&amp;quot;genre: &#039;&amp;quot; + category + &amp;quot;&#039;&amp;quot;);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (check_url(url))&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                num_stations++;&lt;br /&gt;
                station_category+=(list)category;&lt;br /&gt;
                station_name+=(list)name;&lt;br /&gt;
                station_desc+=(list)desc;&lt;br /&gt;
                station_url+=(list)url;&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llWhisper(0,&amp;quot;This station is already entered under the same genre and same url and is skipped.\nStation: &amp;quot; + name + &amp;quot;\nGenre: &#039;&amp;quot; + category + &amp;quot;&#039;\nURL: &amp;quot; + url);&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: malformed url on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
     &lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
set_parcel_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    parcel_url=url;&lt;br /&gt;
    llSetParcelMusicURL(parcel_url);&lt;br /&gt;
&lt;br /&gt;
    if (parcel_url==&amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        clear_display();&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is OFF&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;station now set to &amp;quot; + llList2String(station_desc,station_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Station: &amp;quot; + llList2String(station_desc,station_index));&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;Genre  : &amp;quot; + llList2String(category_list,category_index));&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;Now playing.....&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer available_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;len;i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(category_list,i)))&lt;br /&gt;
            return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer empty_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(station_category,i)))&lt;br /&gt;
            return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
skip_empty_categories()&lt;br /&gt;
{&lt;br /&gt;
    integer i=0;&lt;br /&gt;
&lt;br /&gt;
    while (i&amp;lt;llGetListLength(category_list))&lt;br /&gt;
    {&lt;br /&gt;
        if (empty_category(llList2String(category_list,i)))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;Warning: Genre &#039;&amp;quot; + llList2String(category_list,i) + &amp;quot;&#039; contains no stations and is deleted.&amp;quot;);&lt;br /&gt;
            category_list=llDeleteSubList(category_list,i,i);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            i++;&lt;br /&gt;
    }&lt;br /&gt;
            &lt;br /&gt;
    num_categories=llGetListLength(category_list);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state default&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        flag=FALSE;&lt;br /&gt;
        lineno=0;&lt;br /&gt;
        config_error=FALSE;&lt;br /&gt;
        num_stations=0;&lt;br /&gt;
        num_categories=0;&lt;br /&gt;
        radio_status=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(config_notecard) != INVENTORY_NONE)&lt;br /&gt;
        {&lt;br /&gt;
           reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
           llWhisper(0, &amp;quot;Reading config notecard...&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;1&amp;quot;,&amp;quot;Reading configuration.&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;2&amp;quot;,&amp;quot;Wait....&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;No config notecard &#039;&amp;quot; +  config_notecard + &amp;quot;&#039; present.&amp;quot;);&lt;br /&gt;
            state offline;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (reqid==id)&lt;br /&gt;
        {        &lt;br /&gt;
            if (data==EOF)&lt;br /&gt;
            {&lt;br /&gt;
                skip_empty_categories();&lt;br /&gt;
                llWhisper(0,&amp;quot;Configuration ok.\n&amp;quot; + (string)num_categories + &amp;quot; genres and &amp;quot; + (string)num_stations + &amp;quot; stations.&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Configuration OK&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;2&amp;quot;,&amp;quot;Genres  : &amp;quot; + (string)num_categories);&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Stations: &amp;quot; + (string)num_stations);&lt;br /&gt;
                state menu;&lt;br /&gt;
            }&lt;br /&gt;
            else &lt;br /&gt;
            {&lt;br /&gt;
                if (process_line(data))&lt;br /&gt;
                    reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
                else if (config_error)&lt;br /&gt;
                {&lt;br /&gt;
                    llWhisper(0,&amp;quot;errors found in configuration. please correct them.&amp;quot;);&lt;br /&gt;
                    state offline;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY &amp;amp;&amp;amp; flag)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state offline&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state offline&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;Reset on owner touch.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    touch_start(integer t)&lt;br /&gt;
   {&lt;br /&gt;
        if (llDetectedKey(0)==llGetOwner())&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state menu&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state menu&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        listen_handle=0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        if (param &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
        key toucher=llDetectedKey(0);&lt;br /&gt;
&lt;br /&gt;
        if (has_access(toucher))&lt;br /&gt;
        {&lt;br /&gt;
            make_menu(toucher);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;sorry, no access.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    listen(integer chan, string name,key id,string msg)&lt;br /&gt;
    {&lt;br /&gt;
        integer index;&lt;br /&gt;
&lt;br /&gt;
        if (menu_type == 0)          // main menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_ON)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=1;&lt;br /&gt;
                set_parcel_url(parcel_url);               &lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is ON&amp;quot;);&lt;br /&gt;
                menu_num=0;&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned on.&amp;quot;);&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=0;&lt;br /&gt;
                set_parcel_url(&amp;quot;&amp;quot;);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned off.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
                {&lt;br /&gt;
                    llGiveInventory(id,info_notecard);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                    llWhisper(0,&amp;quot;sorry, help not available.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (radio_status == 1)&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(category_list, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: genre not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    category_index=index;&lt;br /&gt;
                    llWhisper(0,&amp;quot;Genre now set to &amp;quot; + llList2String(category_list,category_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
                    menu_type=1;&lt;br /&gt;
                    menu_num=0;&lt;br /&gt;
                    make_menu(id);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (menu_type == 1 &amp;amp;&amp;amp; radio_status == 1)     // station menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(station_name, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: station not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    station_index=index;&lt;br /&gt;
                    string new_url=llList2String(station_url,station_index);&lt;br /&gt;
&lt;br /&gt;
                    if (new_url != parcel_url)&lt;br /&gt;
                    {&lt;br /&gt;
                        set_parcel_url(new_url);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        retrieve_titelinfo();&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_response(key id, integer status, list meta, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == httpreq_id)&lt;br /&gt;
        {&lt;br /&gt;
            if (status == 200)&lt;br /&gt;
            {&lt;br /&gt;
                string feed = llGetSubString(body,llSubStringIndex(body, &amp;quot;&amp;lt;body&amp;gt;&amp;quot;) + llStringLength(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;), llSubStringIndex(body,&amp;quot;&amp;lt;/body&amp;gt;&amp;quot;) - 1);&lt;br /&gt;
                list feed_list = llParseString2List(feed,[&amp;quot;,&amp;quot;],[]);&lt;br /&gt;
                string current_title_info= llList2String(feed_list,6);&lt;br /&gt;
                integer length = llGetListLength(feed_list);&lt;br /&gt;
        &lt;br /&gt;
                if(llList2String(feed_list,7))&lt;br /&gt;
                {&lt;br /&gt;
                    integer a = 7;&lt;br /&gt;
                    for(; a&amp;lt;length; ++a)&lt;br /&gt;
                    {&lt;br /&gt;
                        current_title_info += &amp;quot;, &amp;quot; + llList2String(feed_list,a);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
         &lt;br /&gt;
                if (current_title_info != last_title_info)&lt;br /&gt;
                {&lt;br /&gt;
                    last_title_info = current_title_info;&lt;br /&gt;
                    display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + current_title_info);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + no_title_info);&lt;br /&gt;
            }&lt;br /&gt;
        }    &lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
// end of script&lt;br /&gt;
/////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;/div&gt;</description>
			<pubDate>Wed, 09 Feb 2011 21:54:08 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)</comments>
		</item>
		<item>
			<title>Shoutcast - radio controller v0.3 (remake of similar scripts)</title>
			<link>https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133902</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)&amp;diff=1133902</guid>
			<description>&lt;p&gt;Flennan Roffo: Created page with &amp;quot;{{LSL header}} This script controls a shoutcast radio receiver and lets you select the stations that you configured on a notecard. Menu driven. Output of station description, gen…&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL header}}&lt;br /&gt;
This script controls a shoutcast radio receiver and lets you select the stations that you configured on a notecard. Menu driven. Output of station description, genre and current song title using Xy text.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// Shoutcast - radio controller v0.3&lt;br /&gt;
// Logic Scripts (Flennan Roffo)&lt;br /&gt;
// (c) 2010 - Flennan Roffo (Logic Scripts)&lt;br /&gt;
// &lt;br /&gt;
// Remake of similar script:&lt;br /&gt;
// + LandOwnersRadio V2.0 by Scripter Coba  (( menu driven / notecard config script to select the radio station and sets parcel music url ))&lt;br /&gt;
// + Raven radio infoboard by Jamie Otis    (( worked at the basis of sis service [sis.slserver.com/sis.php] used Xy text display         ))&lt;br /&gt;
// + currentPlaying by Darkie Minotaur      (( used the /7.html info to fetch current song title info, displayed as float text            ))&lt;br /&gt;
//&lt;br /&gt;
// Purpose:&lt;br /&gt;
// * Sets the parcel audio URL and displays the channel info&lt;br /&gt;
// * Uses Xytext to display the info.&lt;br /&gt;
// * Fetches song title info from the shoutcast url&lt;br /&gt;
// Extra Features -- 0.1 release&lt;br /&gt;
// * On/Off option&lt;br /&gt;
// * Allows multiple menus (if options per menu &amp;gt; 12) using a prev/next button&lt;br /&gt;
// * Checks if your url is well-formatted&lt;br /&gt;
// * Will delete genres for which no stations exist&lt;br /&gt;
// * Will skip stations that have same url and same genre (you can however have an identical station url under different genres).&lt;br /&gt;
// * New notecard format&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Extra Features -- 0.2 release&lt;br /&gt;
// * Configurable button text&lt;br /&gt;
// * Gets parcel URL and automatically sets the genre/station and on/off status accordingly (&amp;lt;-- doesn&#039;t work)&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
// Update -- 0.3 release&lt;br /&gt;
// * Fixed bug (only first station in genre displayed in menu)&lt;br /&gt;
// * Auto reset script when config card updated&lt;br /&gt;
//////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
//&lt;br /&gt;
// This program is free software: you can redistribute it and/or modify&lt;br /&gt;
// it under the terms of the GNU General Public License as published by&lt;br /&gt;
// the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
// (at your option) any later version.&lt;br /&gt;
//&lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
//&lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
///////////////////////////////////////////////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DEBUG=0;&lt;br /&gt;
&lt;br /&gt;
string info_notecard=&amp;quot;Radio Control info&amp;quot;;              ///////    EDITABLE  \\\\\\&lt;br /&gt;
string config_notecard=&amp;quot;Radio Control config&amp;quot;;          ///////    EDITABLE  \\\\\\&lt;br /&gt;
string comment_char=&amp;quot;#&amp;quot;;                                ///////    EDITABLE  \\\\\\&lt;br /&gt;
list sep_char_list= [&amp;quot;|&amp;quot;];                              ///////    EDITABLE  \\\\\\&lt;br /&gt;
float update_time=5.0;                                  ///////    EDITABLE  \\\\\\ &lt;br /&gt;
string no_title_info=&amp;quot;(no title info available)&amp;quot;;       ///////    EDITABLE  \\\\\\&lt;br /&gt;
&lt;br /&gt;
// not used currently - for showing info on current song title elsewhere in the region&lt;br /&gt;
integer broadcast_channel=-1234;                        ///////    EDITABLE  \\\\\\ &lt;br /&gt;
&lt;br /&gt;
// Buttons&lt;br /&gt;
&lt;br /&gt;
string button_MAIN = &amp;quot;MAIN&amp;quot;;&lt;br /&gt;
string button_HELP = &amp;quot;HELP&amp;quot;;&lt;br /&gt;
string button_NEXT = &amp;quot;&amp;gt;&amp;gt;&amp;quot;;&lt;br /&gt;
string button_PREV = &amp;quot;&amp;lt;&amp;lt;&amp;quot;;&lt;br /&gt;
string button_ON   = &amp;quot;ON&amp;quot;;&lt;br /&gt;
string button_OFF  = &amp;quot;OFF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Lists&lt;br /&gt;
&lt;br /&gt;
list category_list=[];&lt;br /&gt;
&lt;br /&gt;
list station_category=[];&lt;br /&gt;
list station_name=[];&lt;br /&gt;
list station_desc=[];&lt;br /&gt;
list station_url=[];&lt;br /&gt;
&lt;br /&gt;
string last_title_info=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
integer radio_status=0;&lt;br /&gt;
string parcel_url=&amp;quot;&amp;quot;;&lt;br /&gt;
integer lineno=0;&lt;br /&gt;
key reqid=NULL_KEY;&lt;br /&gt;
key httpreq_id=NULL_KEY;&lt;br /&gt;
integer config_error=FALSE;&lt;br /&gt;
integer flag;&lt;br /&gt;
integer section=0;&lt;br /&gt;
integer owner_access=TRUE;&lt;br /&gt;
integer group_access=FALSE;&lt;br /&gt;
integer public_access=TRUE;&lt;br /&gt;
list banned_keys=[];&lt;br /&gt;
&lt;br /&gt;
integer menu_channel;&lt;br /&gt;
integer listen_handle;&lt;br /&gt;
integer menu_type=0;&lt;br /&gt;
integer menu_num=0;&lt;br /&gt;
integer category_index=0;&lt;br /&gt;
integer station_index=0;&lt;br /&gt;
&lt;br /&gt;
integer num_categories=0;&lt;br /&gt;
integer num_stations=0;&lt;br /&gt;
&lt;br /&gt;
DebugSay(string msg)&lt;br /&gt;
{&lt;br /&gt;
    if (DEBUG)&lt;br /&gt;
        llSay(0,&amp;quot;(debug) &amp;quot; + msg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
retrieve_titelinfo()&lt;br /&gt;
{&lt;br /&gt;
    string url=llList2String(station_url,station_index);&lt;br /&gt;
    httpreq_id=llHTTPRequest(url + &amp;quot;/7.html  HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n&amp;quot;,[],&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
display_line(string line, string message)&lt;br /&gt;
{&lt;br /&gt;
    // Setup XYtext Variables&lt;br /&gt;
    integer DISPLAY_STRING      = 204000; &lt;br /&gt;
    integer DISPLAY_EXTENDED    = 204001; &lt;br /&gt;
    integer REMAP_INDICES       = 204002; &lt;br /&gt;
    integer RESET_INDICES       = 204003; &lt;br /&gt;
    integer SET_CELL_INFO       = 204004; &lt;br /&gt;
    integer SET_FONT_TEXTURE    = 204005; &lt;br /&gt;
    integer SET_THICKNESS       = 204006; &lt;br /&gt;
    integer SET_COLOR           = 204007; &lt;br /&gt;
&lt;br /&gt;
    llMessageLinked(LINK_SET,DISPLAY_STRING,message,line);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
clear_display() &lt;br /&gt;
{&lt;br /&gt;
    // Clears the display&lt;br /&gt;
    display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio Station ID&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;2&amp;quot;,&amp;quot;Music Genre....&amp;quot;);&lt;br /&gt;
    display_line(&amp;quot;3&amp;quot;,&amp;quot;Now Playing....&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
make_menu(key id)&lt;br /&gt;
{&lt;br /&gt;
     menu_channel=random_channel();&lt;br /&gt;
&lt;br /&gt;
    if (radio_status == 0)&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        llDialog(id,&amp;quot;Menu: Status\n\nRadio is OFF&amp;quot;, [ &amp;quot;ON&amp;quot;, &amp;quot;HELP&amp;quot; ],menu_channel);&lt;br /&gt;
    }&lt;br /&gt;
    else &lt;br /&gt;
    {&lt;br /&gt;
        if (menu_type ==0)&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Genres&amp;quot;, category_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llDialog(id,&amp;quot;Menu: Stations\nGenre: &amp;quot; + llList2String(category_list,category_index), station_menu(menu_num),menu_channel);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (listen_handle != 0)    llListenRemove(listen_handle);&lt;br /&gt;
    listen_handle=llListen(menu_channel,&amp;quot;&amp;quot;,id,&amp;quot;&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
list category_menu(integer num)&lt;br /&gt;
{   // compile menu list of category list&lt;br /&gt;
    // if there are more catagories then can be displayed in the menu&lt;br /&gt;
    // compile a submenu, including options for main menu and more and a blank item.&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
&lt;br /&gt;
    if (len &amp;gt; 9)&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;   // submenus start at 0. 9th entry is in submenu 0, 10th in 1, etc. &lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt; last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
&lt;br /&gt;
             while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_HELP;&lt;br /&gt;
             else&lt;br /&gt;
                 menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num == 0)&lt;br /&gt;
                menu+=(list)button_OFF;&lt;br /&gt;
             else&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num != last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;       &lt;br /&gt;
        }            &lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(category_list,len);&lt;br /&gt;
&lt;br /&gt;
        menu+=(list)button_OFF;&lt;br /&gt;
        menu+=(list)button_HELP;&lt;br /&gt;
    }        &lt;br /&gt;
    &lt;br /&gt;
    DebugSay(&amp;quot;main menu: &amp;quot; + llList2CSV(menu));&lt;br /&gt;
&lt;br /&gt;
    return menu;    // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer stations_in_category(integer cat)&lt;br /&gt;
{&lt;br /&gt;
    integer count=0;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
    string category=llList2String(category_list,cat);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (category == llList2String(category_list,i))&lt;br /&gt;
            count++;&lt;br /&gt;
&lt;br /&gt;
    return count;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
list order_buttons(list buttons)&lt;br /&gt;
{&lt;br /&gt;
    integer offset;&lt;br /&gt;
    list fixt;&lt;br /&gt;
    integer flag=0;&lt;br /&gt;
&lt;br /&gt;
    while((offset = llGetListLength(buttons)))&lt;br /&gt;
    {&lt;br /&gt;
        if (offset &amp;gt; 3)&lt;br /&gt;
            flag=1;&lt;br /&gt;
        else&lt;br /&gt;
            flag=0;&lt;br /&gt;
&lt;br /&gt;
        fixt += llList2List(buttons, offset = -3 * flag, -1);&lt;br /&gt;
        buttons = llDeleteSubList(buttons, offset, -1);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return fixt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
list station_list(integer category)&lt;br /&gt;
{&lt;br /&gt;
    list s=[];&lt;br /&gt;
    integer i;&lt;br /&gt;
    string cname=llList2String(category_list,category_index);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; llGetListLength(station_name); i++)&lt;br /&gt;
        if (llList2String(station_category,i) == cname)&lt;br /&gt;
            s+=(list)llList2String(station_name,i);&lt;br /&gt;
&lt;br /&gt;
    return s;&lt;br /&gt;
    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
list station_menu(integer num)&lt;br /&gt;
{&lt;br /&gt;
   // compile menu list of station names&lt;br /&gt;
    // if there are more stations then can be displayed in the menu&lt;br /&gt;
    // compile a submenu, including options for main menu and more and a blank item.&lt;br /&gt;
&lt;br /&gt;
    list stations=station_list(category_index);&lt;br /&gt;
    integer len=llGetListLength(stations);&lt;br /&gt;
    list menu=[];&lt;br /&gt;
&lt;br /&gt;
    llSay(0,&amp;quot;Category: &amp;quot; + llList2String(category_list,category_index));&lt;br /&gt;
    llSay(0,&amp;quot;Stations: &amp;quot; + llDumpList2String(stations,&amp;quot;,&amp;quot;));&lt;br /&gt;
        &lt;br /&gt;
    if (len &amp;gt; 11)&lt;br /&gt;
    {&lt;br /&gt;
        integer last_sub=(len-1)/9;&lt;br /&gt;
&lt;br /&gt;
        if (num &amp;gt;= last_sub)&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: wrong submenu number: &amp;quot; + (string) num + &amp;quot;.&amp;quot;);&lt;br /&gt;
            return [ &amp;quot;MAIN&amp;quot; ];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
             integer first=9*num;&lt;br /&gt;
             integer last=9*num+8;&lt;br /&gt;
&lt;br /&gt;
             menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;gt; 0)&lt;br /&gt;
                menu+=(list)button_PREV;&lt;br /&gt;
&lt;br /&gt;
             if (num &amp;lt; last_sub)&lt;br /&gt;
                menu+=(list)button_NEXT;                      &lt;br /&gt;
&lt;br /&gt;
            if (len &amp;gt; last)&lt;br /&gt;
                len =last;&lt;br /&gt;
                &lt;br /&gt;
            while (--len &amp;gt;= first)&lt;br /&gt;
                menu+=(list)llList2String(stations,len);&lt;br /&gt;
        }&lt;br /&gt;
    }            &lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        menu+=(list)button_MAIN;&lt;br /&gt;
&lt;br /&gt;
        while (--len &amp;gt;= 0)&lt;br /&gt;
            menu+=(list)llList2String(stations,len);&lt;br /&gt;
    }        &lt;br /&gt;
&lt;br /&gt;
    DebugSay(&amp;quot;station menu: &amp;quot; + llList2CSV(menu));&lt;br /&gt;
        &lt;br /&gt;
    return menu; // order_buttons(menu);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer has_access(key id)&lt;br /&gt;
{&lt;br /&gt;
    if (llListFindList(banned_keys,(list)id) != -1)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    if (owner_access &amp;amp;&amp;amp; id == llGetOwner())&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (group_access &amp;amp;&amp;amp; llSameGroup(id))&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (public_access)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer random_channel()&lt;br /&gt;
{&lt;br /&gt;
    integer min=-2147483647;&lt;br /&gt;
    integer max=-1000;&lt;br /&gt;
&lt;br /&gt;
    return (integer) (min + llFrand(max-min));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer check_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    integer pos=0;&lt;br /&gt;
&lt;br /&gt;
    if (llGetSubString(url,0,6) == &amp;quot;http://&amp;quot;)&lt;br /&gt;
        pos=7;        &lt;br /&gt;
    if (llGetSubString(url,0,7) == &amp;quot;https://&amp;quot;)&lt;br /&gt;
        pos=8;&lt;br /&gt;
&lt;br /&gt;
    if (pos==0)   return FALSE;&lt;br /&gt;
&lt;br /&gt;
    string str_ip_port=llGetSubString(url,pos,-1);&lt;br /&gt;
    list list_ip_port=llParseString2List(str_ip_port,[&amp;quot;:&amp;quot;],[]);                    // split in ip-adress and port&lt;br /&gt;
    list list_ip=llParseString2List(llList2String(list_ip_port,0),[&amp;quot;.&amp;quot;],[]);    // split ip-adress elements&lt;br /&gt;
&lt;br /&gt;
    if (llGetListLength(list_ip_port) != 2 || llGetListLength(list_ip) != 4)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer test;&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;4;i++)&lt;br /&gt;
    {&lt;br /&gt;
        test=llList2Integer(list_ip,i);&lt;br /&gt;
        if (llList2String(list_ip,i) != (string)test)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        if (test &amp;lt; 0 || test &amp;gt; 255)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    test=llList2Integer(list_ip_port,1);&lt;br /&gt;
    if (llList2String(list_ip_port,1) != (string)test)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer true_value(string input)&lt;br /&gt;
{&lt;br /&gt;
    string value=llToLower(llGetSubString(input,0,0));&lt;br /&gt;
&lt;br /&gt;
    if (value == &amp;quot;y&amp;quot; || value == &amp;quot;t&amp;quot; || value ==&amp;quot;1&amp;quot;)&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer process_line(string dataline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(dataline,STRING_TRIM);&lt;br /&gt;
    integer index=llSubStringIndex(line,comment_char);&lt;br /&gt;
    &lt;br /&gt;
    if (index==0)       // line starts with comment - ignore line&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (index!=-1)&lt;br /&gt;
        line=llStringTrim(llGetSubString(line,0,index-1),STRING_TRIM_TAIL);   // skip everything after comment_char and trim tail&lt;br /&gt;
&lt;br /&gt;
    if (line==&amp;quot;&amp;quot;)       // Ignore blank lines&lt;br /&gt;
        return TRUE;&lt;br /&gt;
&lt;br /&gt;
    if (llToLower(line) == &amp;quot;[access]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 1;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[banned]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 2;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[genre]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 3;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llToLower(line) == &amp;quot;[station]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        section = 4;&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (llGetSubString(line,0,0) == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; llGetSubString(line,-1,-1) == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: malformed section found at line &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
        config_error=TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if (section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;error: no section found on line: &amp;quot; + (string) lineno);&lt;br /&gt;
        config_error = TRUE;&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    list breakup=llParseString2List(line,[&amp;quot;=&amp;quot;],[]);&lt;br /&gt;
    string field=llStringTrim(llList2String(breakup,0),STRING_TRIM);&lt;br /&gt;
    string values=llStringTrim(llList2String(breakup,1),STRING_TRIM);&lt;br /&gt;
&lt;br /&gt;
    if (section == 1)            // access&lt;br /&gt;
    {&lt;br /&gt;
        field=llToLower(field);&lt;br /&gt;
&lt;br /&gt;
        if (field==&amp;quot;owner&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            owner_access=true_value(values);                       &lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;group&amp;quot;)&lt;br /&gt;
        {    &lt;br /&gt;
            group_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (field==&amp;quot;public&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            public_access=true_value(values);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: invalid option on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 2)         // ban list&lt;br /&gt;
    {&lt;br /&gt;
        key try=(key) field;&lt;br /&gt;
&lt;br /&gt;
        if (try)&lt;br /&gt;
        {&lt;br /&gt;
            banned_keys+=(list)((key) field);&lt;br /&gt;
            return TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 3)           // categories&lt;br /&gt;
    {&lt;br /&gt;
//        DebugSay(&amp;quot;category: &#039;&amp;quot; + field + &amp;quot;&#039;&amp;quot;);&lt;br /&gt;
        if (llListFindList(category_list,(list)field) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            category_list+=(list)field;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;genre: &#039;&amp;quot; + field + &amp;quot;&#039; already entered; double entry skipped.&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        return TRUE;&lt;br /&gt;
    }&lt;br /&gt;
    else if (section == 4)            // stations&lt;br /&gt;
    {&lt;br /&gt;
        list parse=llParseString2List(line,sep_char_list, []);&lt;br /&gt;
        string category=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        string desc=llStringTrim(llList2String(parse,2),STRING_TRIM);&lt;br /&gt;
        string url=llStringTrim(llToLower(llList2String(parse,3)),STRING_TRIM);&lt;br /&gt;
    &lt;br /&gt;
        if (!available_category(category))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: unknown genre on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            DebugSay(&amp;quot;genre: &#039;&amp;quot; + category + &amp;quot;&#039;&amp;quot;);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (check_url(url))&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(station_url,(list)url) == -1 || llListFindList(station_category,(list)category) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                num_stations++;&lt;br /&gt;
                station_category+=(list)category;&lt;br /&gt;
                station_name+=(list)name;&lt;br /&gt;
                station_desc+=(list)desc;&lt;br /&gt;
                station_url+=(list)url;&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llWhisper(0,&amp;quot;This station is already entered under the same genre and same url and is skipped.\nStation: &amp;quot; + name + &amp;quot;\nGenre: &#039;&amp;quot; + category + &amp;quot;&#039;\nURL: &amp;quot; + url);&lt;br /&gt;
                return TRUE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;error: malformed url on line: &amp;quot; + (string)lineno + &amp;quot;.\n&amp;quot; + dataline);&lt;br /&gt;
            config_error=TRUE;&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
     &lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
set_parcel_url(string url)&lt;br /&gt;
{&lt;br /&gt;
    parcel_url=url;&lt;br /&gt;
    llSetParcelMusicURL(parcel_url);&lt;br /&gt;
&lt;br /&gt;
    if (parcel_url==&amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        clear_display();&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is OFF&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;station now set to &amp;quot; + llList2String(station_desc,station_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
        display_line(&amp;quot;1&amp;quot;,&amp;quot;Station: &amp;quot; + llList2String(station_desc,station_index));&lt;br /&gt;
        display_line(&amp;quot;2&amp;quot;,&amp;quot;Genre  : &amp;quot; + llList2String(category_list,category_index));&lt;br /&gt;
        display_line(&amp;quot;3&amp;quot;,&amp;quot;Now playing.....&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer available_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(category_list);&lt;br /&gt;
&lt;br /&gt;
    for (i=0;i&amp;lt;len;i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(category_list,i)))&lt;br /&gt;
            return TRUE;&lt;br /&gt;
&lt;br /&gt;
    return FALSE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
integer empty_category(string category)&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer len=llGetListLength(station_category);&lt;br /&gt;
&lt;br /&gt;
    for (i=0; i &amp;lt; len; i++)&lt;br /&gt;
        if (llToLower(category) == llToLower(llList2String(station_category,i)))&lt;br /&gt;
            return FALSE;&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
skip_empty_categories()&lt;br /&gt;
{&lt;br /&gt;
    integer i=0;&lt;br /&gt;
&lt;br /&gt;
    while (i&amp;lt;llGetListLength(category_list))&lt;br /&gt;
    {&lt;br /&gt;
        if (empty_category(llList2String(category_list,i)))&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;Warning: Genre &#039;&amp;quot; + llList2String(category_list,i) + &amp;quot;&#039; contains no stations and is deleted.&amp;quot;);&lt;br /&gt;
            category_list=llDeleteSubList(category_list,i,i);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            i++;&lt;br /&gt;
    }&lt;br /&gt;
            &lt;br /&gt;
    num_categories=llGetListLength(category_list);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state default&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        flag=FALSE;&lt;br /&gt;
        lineno=0;&lt;br /&gt;
        config_error=FALSE;&lt;br /&gt;
        num_stations=0;&lt;br /&gt;
        num_categories=0;&lt;br /&gt;
        radio_status=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(config_notecard) != INVENTORY_NONE)&lt;br /&gt;
        {&lt;br /&gt;
           reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
           llWhisper(0, &amp;quot;Reading config notecard...&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;1&amp;quot;,&amp;quot;Reading configuration.&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;2&amp;quot;,&amp;quot;Wait....&amp;quot;);&lt;br /&gt;
           display_line(&amp;quot;3&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llWhisper(0,&amp;quot;No config notecard &#039;&amp;quot; +  config_notecard + &amp;quot;&#039; present.&amp;quot;);&lt;br /&gt;
            state offline;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (reqid==id)&lt;br /&gt;
        {        &lt;br /&gt;
            if (data==EOF)&lt;br /&gt;
            {&lt;br /&gt;
                skip_empty_categories();&lt;br /&gt;
                llWhisper(0,&amp;quot;Configuration ok.\n&amp;quot; + (string)num_categories + &amp;quot; genres and &amp;quot; + (string)num_stations + &amp;quot; stations.&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Configuration OK&amp;quot;);&lt;br /&gt;
                display_line(&amp;quot;2&amp;quot;,&amp;quot;Genres  : &amp;quot; + (string)num_categories);&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Stations: &amp;quot; + (string)num_stations);&lt;br /&gt;
                state menu;&lt;br /&gt;
            }&lt;br /&gt;
            else &lt;br /&gt;
            {&lt;br /&gt;
                if (process_line(data))&lt;br /&gt;
                    reqid=llGetNotecardLine(config_notecard,lineno++);&lt;br /&gt;
                else if (config_error)&lt;br /&gt;
                {&lt;br /&gt;
                    llWhisper(0,&amp;quot;errors found in configuration. please correct them.&amp;quot;);&lt;br /&gt;
                    state offline;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer ch)&lt;br /&gt;
    {&lt;br /&gt;
        if (ch &amp;amp; CHANGED_INVENTORY &amp;amp;&amp;amp; flag)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state offline&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state offline&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llWhisper(0,&amp;quot;Reset on owner touch.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    touch_start(integer t)&lt;br /&gt;
   {&lt;br /&gt;
        if (llDetectedKey(0)==llGetOwner())&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// state menu&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state menu&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        menu_type=0;&lt;br /&gt;
        menu_num=0;&lt;br /&gt;
        listen_handle=0;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        if (param &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
            llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    touch_start(integer total_num)&lt;br /&gt;
    {&lt;br /&gt;
        key toucher=llDetectedKey(0);&lt;br /&gt;
&lt;br /&gt;
        if (has_access(toucher))&lt;br /&gt;
        {&lt;br /&gt;
            make_menu(toucher);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
            llWhisper(0,&amp;quot;sorry, no access.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    listen(integer chan, string name,key id,string msg)&lt;br /&gt;
    {&lt;br /&gt;
        integer index;&lt;br /&gt;
&lt;br /&gt;
        if (menu_type == 0)          // main menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_ON)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=1;&lt;br /&gt;
                set_parcel_url(parcel_url);               &lt;br /&gt;
                display_line(&amp;quot;1&amp;quot;,&amp;quot;Radio is ON&amp;quot;);&lt;br /&gt;
                menu_num=0;&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned on.&amp;quot;);&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                radio_status=0;&lt;br /&gt;
                set_parcel_url(&amp;quot;&amp;quot;);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
                llWhisper(0,&amp;quot;Radio now turned off.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                if (llGetInventoryType(info_notecard) == INVENTORY_NOTECARD)&lt;br /&gt;
                {&lt;br /&gt;
                    llGiveInventory(id,info_notecard);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                    llWhisper(0,&amp;quot;sorry, help not available.&amp;quot;);&lt;br /&gt;
            }&lt;br /&gt;
            else if (radio_status == 1)&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(category_list, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: genre not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    category_index=index;&lt;br /&gt;
                    llWhisper(0,&amp;quot;Genre now set to &amp;quot; + llList2String(category_list,category_index) + &amp;quot;.&amp;quot;);&lt;br /&gt;
                    menu_type=1;&lt;br /&gt;
                    menu_num=0;&lt;br /&gt;
                    make_menu(id);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (menu_type == 1 &amp;amp;&amp;amp; radio_status == 1)     // station menu&lt;br /&gt;
        {&lt;br /&gt;
            if (msg == button_MAIN)&lt;br /&gt;
            {&lt;br /&gt;
                menu_type=0;&lt;br /&gt;
                menu_num =0;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num++;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else if (msg == button_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                menu_num--;&lt;br /&gt;
                make_menu(id);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                index = llListFindList(station_name, (list)msg);&lt;br /&gt;
&lt;br /&gt;
                if (index == -1)&lt;br /&gt;
                    llWhisper(0,&amp;quot;error: station not found: &amp;quot; + msg);&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    station_index=index;&lt;br /&gt;
                    string new_url=llList2String(station_url,station_index);&lt;br /&gt;
&lt;br /&gt;
                    if (new_url != parcel_url)&lt;br /&gt;
                    {&lt;br /&gt;
                        set_parcel_url(new_url);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        retrieve_titelinfo();&lt;br /&gt;
        llSetTimerEvent(update_time);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_response(key id, integer status, list meta, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == httpreq_id)&lt;br /&gt;
        {&lt;br /&gt;
            if (status == 200)&lt;br /&gt;
            {&lt;br /&gt;
                string feed = llGetSubString(body,llSubStringIndex(body, &amp;quot;&amp;lt;body&amp;gt;&amp;quot;) + llStringLength(&amp;quot;&amp;lt;body&amp;gt;&amp;quot;), llSubStringIndex(body,&amp;quot;&amp;lt;/body&amp;gt;&amp;quot;) - 1);&lt;br /&gt;
                list feed_list = llParseString2List(feed,[&amp;quot;,&amp;quot;],[]);&lt;br /&gt;
                string current_title_info= llList2String(feed_list,6);&lt;br /&gt;
                integer length = llGetListLength(feed_list);&lt;br /&gt;
        &lt;br /&gt;
                if(llList2String(feed_list,7))&lt;br /&gt;
                {&lt;br /&gt;
                    integer a = 7;&lt;br /&gt;
                    for(; a&amp;lt;length; ++a)&lt;br /&gt;
                    {&lt;br /&gt;
                        current_title_info += &amp;quot;, &amp;quot; + llList2String(feed_list,a);&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
         &lt;br /&gt;
                if (current_title_info != last_title_info)&lt;br /&gt;
                {&lt;br /&gt;
                    last_title_info = current_title_info;&lt;br /&gt;
                    display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + current_title_info);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                display_line(&amp;quot;3&amp;quot;,&amp;quot;Title  : &amp;quot; + no_title_info);&lt;br /&gt;
            }&lt;br /&gt;
        }    &lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////&lt;br /&gt;
// end of script&lt;br /&gt;
/////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;/div&gt;</description>
			<pubDate>Wed, 09 Feb 2011 21:48:50 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:Shoutcast_-_radio_controller_v0.3_(remake_of_similar_scripts)</comments>
		</item>
		<item>
			<title>Category:LSL Library</title>
			<link>https://wiki.secondlife.com/w/index.php?title=Category:LSL_Library&amp;diff=1133901</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=Category:LSL_Library&amp;diff=1133901</guid>
			<description>&lt;p&gt;Flennan Roffo: Added: Shoutcast - radio controller&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header|ml=*}}{{RightToc}}&lt;br /&gt;
==Script Library==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em 0.5em 1.5em&amp;quot;&amp;gt;&lt;br /&gt;
Come to this page to see complex examples that show how to combine parts of LSL.&lt;br /&gt;
&lt;br /&gt;
Go to the [[:Category:LSL Examples|LSL Examples]] page to see brief examples of how to use parts of LSL &lt;br /&gt;
&lt;br /&gt;
Why collect complex examples here? Well, ...&lt;br /&gt;
&lt;br /&gt;
There are many [[script|scripts]] that have become buried in the [[Old forum Scripting Library index| old forum Scripting Library]] or the newer [https://blogs.secondlife.com/community/forums/scripting_library?view=discussions Scripting Library forum], were lost with the death of the early scripting forums, or sit idle in [[inventory|inventories]] that could be useful and should be more accessible.&lt;br /&gt;
&lt;br /&gt;
Other scripters may be in the same situation. This wiki is a well-suited medium for a script library. Feel free to add your scripts to the script library by creating new pages for them and linking to those pages here.&lt;br /&gt;
&lt;br /&gt;
Note that there are many more scripts in the LSL Library here, but you can&#039;t get to them if you don&#039;t know they exist, because they are subpages now, instead of an automatically updated category.  Good luck searching.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Rules for posting: ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
#Your script must be tested and working. If it&#039;s not, stick it in your user-space until it is. This is a list of working, usable scripts.&lt;br /&gt;
#Add a link to your script&#039;s page here. Link back to this page from your script&#039;s page. Start your page with &amp;lt;nowiki&amp;gt;{{LSL Header}}&amp;lt;/nowiki&amp;gt;.&lt;br /&gt;
#Do not add scripts that duplicate the same functionality as an existing script or built in {{LSLGC|Functions|function}}. If yours does, explain why.&lt;br /&gt;
#Do not list simple scripts here. Include those among the [[:Category:LSL Examples|LSL Examples]] instead.&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==LSL Script Library==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;sortable&amp;quot; {{Prettytable}}&lt;br /&gt;
|- {{Hl2}}&lt;br /&gt;
! &#039;&#039;&#039;Name&#039;&#039;&#039;&lt;br /&gt;
! &#039;&#039;&#039;Creator&#039;&#039;&#039;&lt;br /&gt;
! &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||[[1st necessity of SL]]&lt;br /&gt;
||[[User:Beer Dailey|Beer Dailey]]&lt;br /&gt;
||Monitors for avatars and (de)activates scripts states to control script performance/lag.&lt;br /&gt;
|-&lt;br /&gt;
||[[SetLinkText]]&lt;br /&gt;
||[[User:Tacusin Memo|Tacusin Memo]]&lt;br /&gt;
||Custom function like llSetText only applying to linked sets.&lt;br /&gt;
|-&lt;br /&gt;
||[[3D Radar]]&lt;br /&gt;
||[[User:Jesse Barnett|Jesse Barnett]]&lt;br /&gt;
||Rezzes a ball for each avatar in range. Each ball tracks its own AV and displays distance.&lt;br /&gt;
|-&lt;br /&gt;
||[[Access (NewAge)]]&lt;br /&gt;
||[[User:Asia Snowfall|Asia Snowfall]]&lt;br /&gt;
||An easy to use script for permissions on who can use the script, Public/Group/Owner&lt;br /&gt;
|-&lt;br /&gt;
||[[Aim Detection]]&lt;br /&gt;
||[[User:Han Shuffle|Unrevoked Clarity]]&lt;br /&gt;
||Monitors for avatars and reports back to owner about who is aiming at them.&lt;br /&gt;
|-&lt;br /&gt;
||[[AntiDelay Node]]&lt;br /&gt;
||[[User:Xaviar Czervik|Xaviar Czervik]]&lt;br /&gt;
||Uses [[llMessageLinked]] to stop those pesky delays.&lt;br /&gt;
|-&lt;br /&gt;
||[[AO Overriding Pose Ball]]&lt;br /&gt;
||[[User:Jesse Barnett|Jesse Barnett]]&lt;br /&gt;
||No more turning your AO off and on when you sit down&lt;br /&gt;
|-&lt;br /&gt;
||[[ARCFOUR Strong Encryption Implementation]]&lt;br /&gt;
||[[User:Nekow42 Zarf|Nekow42 Zarf]]&lt;br /&gt;
||An LSL implementation of ARCFOUR, the most popular stream cipher still in use. It is licensed under a Creative Commons Attribution 3.0 license.&lt;br /&gt;
|-&lt;br /&gt;
||[[Assembly Programming Language|Assembly-Like Programming Language]]&lt;br /&gt;
||[[User:Xaviar Czervik|Xaviar Czervik]]&lt;br /&gt;
||A compiler that runs assembly-like programs.&lt;br /&gt;
|-&lt;br /&gt;
||[[Associative Array Emulator|Associative Array (Dictionary) Emulator]]&lt;br /&gt;
||[[User:Alynna Vixen|Alynna Vixen]]&lt;br /&gt;
||This library provides a set of functions for using a list as an associative array where string based keys can refer to one or more variant elements.&lt;br /&gt;
|-&lt;br /&gt;
||[[AvatarFollower]]&lt;br /&gt;
||[[User:Dale Innis|Dale Innis]]&lt;br /&gt;
||Allows one avatar to automatically follow another.&lt;br /&gt;
|-&lt;br /&gt;
||[[Avatar Radar (NewAge)]]&lt;br /&gt;
||[[User:Asia Snowfall|Asia Snowfall]]&lt;br /&gt;
||Version 1.2; A nice new avatar radar script i just finish that you can place in your hud, Also features avatar locator&lt;br /&gt;
|-&lt;br /&gt;
||[[Base2Dec]]&lt;br /&gt;
||[[User:Siann Beck|Siann Beck]]&lt;br /&gt;
||Convert a number to decimal from any base.&lt;br /&gt;
|-&lt;br /&gt;
||[[BaseN]]&lt;br /&gt;
||[[User:Nexii Malthus|Nexii Malthus]]&lt;br /&gt;
||Variable base compression, dynamically maps to usable UTF code points.&lt;br /&gt;
|-&lt;br /&gt;
||[[Basic A-Star Pathfinder]]&lt;br /&gt;
||[[User:Nexii Malthus|Nexii Malthus]]&lt;br /&gt;
|| My own interpretation of A Star into a highly efficient algorithmn&lt;br /&gt;
|-&lt;br /&gt;
||[[Basic Encryption Modules]]&lt;br /&gt;
||[[User:Beverly Larkin|Beverly Larkin]]&lt;br /&gt;
||Basic encryption scripts, allows you to encrypt a float and shout it to another prim on a randomly chosen channel.&lt;br /&gt;
|-&lt;br /&gt;
||[[Be happy]]&lt;br /&gt;
||[[User:Emmas Seetan|Emmas Seetan]]&lt;br /&gt;
||Basic smile attachment script, makes your avatar smile.&lt;br /&gt;
|-&lt;br /&gt;
||[[Best Neighbor Ad Hiding Script|Best Neighbor]]&lt;br /&gt;
||[[User:Doran Zemlja|Doran Zemlja]]&lt;br /&gt;
||Reduce ad clutter by hiding ads when users are on their own land nearby.&lt;br /&gt;
|-&lt;br /&gt;
||[[BigNum|BigNum Library (RSA Encryption)]]&lt;br /&gt;
||[[User:Xaviar Czervik|Xaviar Czervik]]&lt;br /&gt;
||A BigNum Library for dealing with big numbers! Specialized for modular multiplication, and RSA encryption.&lt;br /&gt;
|-&lt;br /&gt;
||[[Binary Clock v1.1|Binary Clock]]&lt;br /&gt;
||[[User:Fox Diller|Fox Diller]]&lt;br /&gt;
||A Binary Clock.&lt;br /&gt;
|-&lt;br /&gt;
||[[BinaryDecimalConverter]]&lt;br /&gt;
||[[User:Soundless Smalls|Soundless Smalls]]&lt;br /&gt;
||Converts a binary value to a decimal value and vice versa.&lt;br /&gt;
|-&lt;br /&gt;
||[[Blacklist and Remote Kill|Blacklist and Remote Kill]]&lt;br /&gt;
||[[User:Chase Quinnell|Chase Quinnell]]&lt;br /&gt;
||Blacklist(denial of use) or a creator kill script(can delete someone&#039;s item by command on private channel)&lt;br /&gt;
|-&lt;br /&gt;
||[[User_talk:Rolig_Loon/Bookmark_URLs|Bookmark URLs]]&lt;br /&gt;
||[[User:Rolig Loon|Rolig Loon]]&lt;br /&gt;
||Dialog driven HUD reads bookmarked URLs from notecards and navigates directly to them with user&#039;s in-world browser.&lt;br /&gt;
|-&lt;br /&gt;
||[[Builders Buddy|Builder&#039;s Buddy Tool]]&lt;br /&gt;
||[[User:Newfie Pendragon|Newfie Pendragon]]&lt;br /&gt;
||Script to easily move/rotate large builds that exceed the linkable size limit (30 meters).&lt;br /&gt;
|-&lt;br /&gt;
||[[Button Click Detector]]&lt;br /&gt;
||{{User|Sendao Goodman}}&lt;br /&gt;
||Use [[llDetectedTouchUV]] to determine which button was pressed on a texture.&lt;br /&gt;
|-&lt;br /&gt;
||[[Camera following prim]]&lt;br /&gt;
||[[User:Dale Innis|Dale Innis]]&lt;br /&gt;
||Pair of scripts to make a prim follow your camera position around (for lights etc).&lt;br /&gt;
|-&lt;br /&gt;
||[[Camera Sync]]&lt;br /&gt;
||[[User:Meyermagic Salome|Meyermagic Salome]] and [[User:Nomad Padar|Nomad Padar]]&lt;br /&gt;
||A system to synchronize the cameras of two avatars.&lt;br /&gt;
|-&lt;br /&gt;
||[[Chatbot]]&lt;br /&gt;
||Anonymous&lt;br /&gt;
||Compile and run the LSL you type on a channel, faster than you can thru the 2007-08 SL GUI.&lt;br /&gt;
|-&lt;br /&gt;
||[[Chat Logger (GPL)]]&lt;br /&gt;
||[[User:Nobody Fugazi|Nobody Fugazi]]&lt;br /&gt;
||Chat logger which requests permission from participants before recording them.&lt;br /&gt;
|-&lt;br /&gt;
||[[Chat_Relay|Chat Relay]]&lt;br /&gt;
||[[User:grumble Loudon|grumble Loudon]]&lt;br /&gt;
||A Chat relay which can be routed using a path header and won&#039;t echo.&lt;br /&gt;
|-&lt;br /&gt;
||[[ClickAndDrag]]&lt;br /&gt;
||[[User:Nexii Malthus|Nexii Malthus]]&lt;br /&gt;
|| Click and Drag user interface elements using dynamic feedback&lt;br /&gt;
|-&lt;br /&gt;
||[[Code Racer]]&lt;br /&gt;
||Anonymous&lt;br /&gt;
||Race two versions of code forever, to see which runs faster.&lt;br /&gt;
|-&lt;br /&gt;
||[[Code Sizer]]&lt;br /&gt;
||Anonymous&lt;br /&gt;
||Count the bytes compiled from source code, to measure how to write small code.&lt;br /&gt;
|-&lt;br /&gt;
||[[User:Void_Singer/Programs#v7-D_Enh._Color_Picker|Color Changer]]&lt;br /&gt;
||[[User:Void_Singer|Void_Singer]]&lt;br /&gt;
||Dialog driven color changer. Supports 16million+ colors, web color codes, multiple targeted prims, with save and recall.&lt;br /&gt;
|-&lt;br /&gt;
||[[Color Changer|Color Changer Plus]]&lt;br /&gt;
||[[User:Neo Calcutt|Neo Calcutt]]&lt;br /&gt;
||A color changer with 14 colors, a random function, and a custom vector function.&lt;br /&gt;
|-&lt;br /&gt;
||[[Color conversion scripts|Color Conversion]]&lt;br /&gt;
||[[User:Sally LaSalle|Sally LaSalle]]&lt;br /&gt;
||Convert between Red Green Blue (RGB) and Hue Saturation Value (HSV).&lt;br /&gt;
|-&lt;br /&gt;
||[[ColorConvert]]&lt;br /&gt;
||[[User:Siann Beck|Siann Beck]]&lt;br /&gt;
||Convert color values to vector from RGB, hex or HTML color name.&lt;br /&gt;
|-&lt;br /&gt;
||[[Color script]]&lt;br /&gt;
||[[User:Masakazu Kojima|Masakazu Kojima]]&lt;br /&gt;
||Script for changing colors trough a listener with pre-defined colors.&lt;br /&gt;
|-&lt;br /&gt;
||[[Library Combined Library|Combined Library]]&lt;br /&gt;
||[[User:Strife Onizuka|Strife Onizuka]]&lt;br /&gt;
||Library of mostly encoding and decoding functions, some more useful then others.&lt;br /&gt;
* String functions: Replace / Trim right / Trim left / Trim both&lt;br /&gt;
* Unicode conversion: UTF8 to Unicode / Unicode to UTF8&lt;br /&gt;
* List functions: Replace / Compare&lt;br /&gt;
|-&lt;br /&gt;
||[[Computer:jaycoonlanguage]]&lt;br /&gt;
||[[User:jayco121 Bing|jayco121 Bing]]&lt;br /&gt;
|| A language written in LSL that is meant for my computer (available at the shop).&lt;br /&gt;
|-&lt;br /&gt;
||[[Read Note Card Configuration|Configuration Notecard Reader]]&lt;br /&gt;
||{{User|Dedric Mauriac}}&lt;br /&gt;
||A script to read configuration information from a notecard. Parses notecard to extract key words and their assigned values. Allows for comment lines and many more useful features.&lt;br /&gt;
|-&lt;br /&gt;
||[[AdvancedNotecardReader|Configuration Notecard Reader (advanced)]]&lt;br /&gt;
||[[Lear Cale|Lear Cale]]&lt;br /&gt;
||Robust configuration notecard reader; supports multiple notecards with same suffix, handles reconfig on inventory change, and does not usurp the default state.&lt;br /&gt;
|-&lt;br /&gt;
||[[Library_Chat_Relay|Conversation Relay]]&lt;br /&gt;
||[[User:Jippen Faddoul|Jippen Faddoul]]&lt;br /&gt;
||Chat relay which requests permission from participants before relaying their messages. Also includes their attachments. (ToS compliant).&lt;br /&gt;
|-&lt;br /&gt;
||[[Curtain script]]&lt;br /&gt;
||[[User:Zilla Larsson|Zilla Larsson]]&lt;br /&gt;
||A simple script to retract/stretch curtains, blinds, bedcovers and more&lt;br /&gt;
|-&lt;br /&gt;
||[[Dataserver API]]&lt;br /&gt;
||[[User:Revolution Perenti|Revolution Perenti]]&lt;br /&gt;
||Dataserver Framework for Notecards.&lt;br /&gt;
|-&lt;br /&gt;
||[[Date Library]]&lt;br /&gt;
||[[User:Corto Maltese|Corto Maltese]]&lt;br /&gt;
|| Date library, based on number of day since march 3rd 1600, can be used to calculate weekday, date differences, and date offset, and date formating.&lt;br /&gt;
|-&lt;br /&gt;
||[[Day of the Week]]&lt;br /&gt;
||[[User:DoteDote Edison|DoteDote Edison]]&lt;br /&gt;
||Function to get day of the week from [[llGetUnixTime]].&lt;br /&gt;
|-&lt;br /&gt;
||[[Days in Month]]&lt;br /&gt;
||[[User:IntLibber Brautigan begin_of_the_skype_highlighting     end_of_the_skype_highlighting begin_of_the_skype_highlighting     end_of_the_skype_highlighting|IntLibber Brautigan]]&lt;br /&gt;
||Clicking on it returns the number of days in the present month. Useful for scripting calendars and tier systems that need to know the number of days in the month at hand or to calculate for any month. Even adjusts for leap years.&lt;br /&gt;
|-&lt;br /&gt;
||[[Deed Tools]]&lt;br /&gt;
||[[User:Falados Kapuskas|Falados Kapuskas]]&lt;br /&gt;
||Tools that allow the creator to modify Group-Owned (Deeded) Objects via chat.&lt;br /&gt;
|-&lt;br /&gt;
||[[Describe Chatter]]&lt;br /&gt;
||Anonymous&lt;br /&gt;
||Chat to see yourself as others do.&lt;br /&gt;
|-&lt;br /&gt;
||[[Dialog Control]]&lt;br /&gt;
||[[User:Nargus Asturias|Nargus Asturias]]&lt;br /&gt;
|| A (not-so) simple dialog &amp;amp; menu control script. Call dialog and receive selected value via [[link_message]](), with built-in timer and [[link_message]]() notification on time out. Supports multi-pages dialog and numeric property dialog. Button text and dialog&#039;s returned value can differ.&lt;br /&gt;
Latest version also has [[Dialog Menus Control]] built-in; which allow multi-level menus through SL dialog system.&lt;br /&gt;
|-&lt;br /&gt;
||[[MultiUser_Dialog_Handler|Dialog Menus (multiuser)]]&lt;br /&gt;
||[[User:SimonT Quinnell|SimonT Quinnell]]&lt;br /&gt;
|| Menu dialog handler that supports multiple menus open at once from the single script. Displays multi-page menus if necessary as well as allowing for fixed header and footer buttons.  Timeouts as well as Text and button size limits are handled.&lt;br /&gt;
|-&lt;br /&gt;
||[[Dialog NumberPad|Dialog Number Pad]]&lt;br /&gt;
||[[User:DoteDote Edison|DoteDote Edison]]&lt;br /&gt;
||Use a dialog to accept positive integer input from users.&lt;br /&gt;
|-&lt;br /&gt;
||[[Display Names Radar]]&lt;br /&gt;
||[[User:Cerise Sorbet|Cerise Sorbet]]&lt;br /&gt;
||Simple HUD type avatar radar that can show [[display names]] and script memory usage&lt;br /&gt;
|-&lt;br /&gt;
||[[Display Names to Key]]&lt;br /&gt;
||[[User:Joran Yoshikawa|Joran Yoshikawa]]&lt;br /&gt;
||Simple way to get UUIDs from displaynames&lt;br /&gt;
|-&lt;br /&gt;
||[[User:Daemonika_Nightfire/Scripts/DS_Display-Username_Online_Indicator|*DS*_Display-Username_Online_Indicator]]&lt;br /&gt;
||[[User:Daemonika Nightfire|Daemonika Nightfire]]&lt;br /&gt;
||This simple hover text-based script is used to shop owners in Second Life, customers at the current display name and user name to display publicly. Additionally shows the status of the Userkey and online. Furthermore, there are click of a chat link that opens the profile owner. &lt;br /&gt;
|-&lt;br /&gt;
||[[Displayer Script]]&lt;br /&gt;
||[[User:Akinori Kimagawa|Akinori Kimagawa]]&lt;br /&gt;
||Display Words On Top Of An Object&lt;br /&gt;
|-&lt;br /&gt;
||[[Drink script]]&lt;br /&gt;
||[[User:Emmas Seetan|Emmas Seetan]]&lt;br /&gt;
||Used mainly for food and drink in Second Life.&lt;br /&gt;
|-&lt;br /&gt;
||[[User:Daemonika_Nightfire/Scripts/DS_Single_AO-Sit|*DS*_Single_AO-Sit]]&lt;br /&gt;
||[[User:Daemonika Nightfire|Daemonika Nightfire]]&lt;br /&gt;
||Posescript for use with or without AO and with or without Animation. With the menu it is possible the seated Avatar to move.&lt;br /&gt;
|-&lt;br /&gt;
||[[TOXDropBox|DropBox]]&lt;br /&gt;
||[[User:Dimentox Travanti|Dimentox Travanti]]&lt;br /&gt;
|| This is a Drop box which allows people to drop certain items in a object &amp;amp; has many config options.&lt;br /&gt;
|-&lt;br /&gt;
||[[Efficiency Tester]]&lt;br /&gt;
||[[User:Xaviar Czervik|Xaviar Czervik]]&lt;br /&gt;
||Tests the speed of a function.&lt;br /&gt;
|-&lt;br /&gt;
||[[Email-to-IM|Email2IM]]&lt;br /&gt;
||[[User:DoteDote Edison|DoteDote Edison]]&lt;br /&gt;
||Send IMs to SL friends via [[email]] (translate emails from friends into IMs).&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
||[[User:Kireji_Haiku/SIMchat_headset|Encrypted Region-wide chat]]&lt;br /&gt;
||&#039;&#039;&#039;[[User:Kireji Haiku|Kireji Haiku]]&#039;&#039;&#039; &amp;lt;sup&amp;gt;&amp;lt;small&amp;gt;([[User talk:Kireji Haiku|talk]]|[[Special:Contributions/Kireji Haiku|contribs]])&amp;lt;/small&amp;gt;&amp;lt;/sup&amp;gt;&lt;br /&gt;
||Encrypted Region-wide chat&lt;br /&gt;
|-&lt;br /&gt;
||[[ExplodingObjects]]&lt;br /&gt;
||[[User:Dale Innis|Dale Innis]]&lt;br /&gt;
||Causes an object (of the appropriate type) to explode on command.&lt;br /&gt;
|-&lt;br /&gt;
||[[FadeEasy]]&lt;br /&gt;
||[[User:Nika Rugani|Nika Rugani]]&lt;br /&gt;
||The easy way of fading objects in or out (Using llSetLinkAlpha)&lt;br /&gt;
|-&lt;br /&gt;
||[[FastConeSpread]]&lt;br /&gt;
||[[User:Nexii Malthus|Nexii Malthus]]&lt;br /&gt;
|| Fast Algorithmn to achieve cone spread, main use in weaponry systems.&lt;br /&gt;
|-&lt;br /&gt;
||[[User:PixelProphet Lane/Scripts#Fast List Prim Contents|Fast List Prim Contents]]&lt;br /&gt;
||[[User:PixelProphet Lane|PixelProphet Lane]]&lt;br /&gt;
||Fast and efficient method to print Object Inventory (Name, Type and next Owner permissions)&lt;br /&gt;
|-&lt;br /&gt;
||[[Find Avatar Key|Find Avatar Key]]&lt;br /&gt;
||[[User:Huney Jewell|Huney Jewell]]&lt;br /&gt;
||Explores [[UUID]] of avatar whose name is said in local chat or who touches the prim.&lt;br /&gt;
|-&lt;br /&gt;
||[[First Name Letter Prize]]&lt;br /&gt;
||[[User:RaithSphere Whybrow|RaithSphere Whybrow]]&lt;br /&gt;
||Gives a prize if the person who sits on it&#039;s first letter of first name matches the random letter!&lt;br /&gt;
|-&lt;br /&gt;
||[[Fix Small Prims|Fix_Small_Prims]]&lt;br /&gt;
||[[User:Emma Nowhere|Emma Nowhere]]&lt;br /&gt;
||Finds and adjusts the smallest prims in a linkset so that it can be scaled down further.&lt;br /&gt;
|-&lt;br /&gt;
||[[Float2Hex]]&lt;br /&gt;
||[[User:Strife Onizuka|Strife Onizuka]]&lt;br /&gt;
||Very useful for transporting [[float|floats]].&lt;br /&gt;
|-&lt;br /&gt;
||[[Float Box Contents]]&lt;br /&gt;
||[[User:Rolig Loon|Rolig Loon]]&lt;br /&gt;
||Displays object inventory in hover text, identified by type and updated marquee-style.&lt;br /&gt;
|-&lt;br /&gt;
||[[Follower (script)|Follower]]&lt;br /&gt;
||Unknown, uploaded by [[User:Slik Swindlehurst|Slik Swindlehurst]]&lt;br /&gt;
||Makes an object follow the nearest person. Do not use for [[grief|griefing]].&lt;br /&gt;
|-&lt;br /&gt;
||[[GA Event Notifier]]&lt;br /&gt;
||[[User:Victor Hua|Victor Hua]]&lt;br /&gt;
||Gathers seven days event data from a Google calendar and display it through a simple interface. The lsl script can access several calendars at once through seperate php files. One file per calendar. Host the included php on your own web server.&lt;br /&gt;
|-&lt;br /&gt;
||[[Geometric|Geometric Library]]&lt;br /&gt;
||Community Project&lt;br /&gt;
||A substantial amount of various geometric functions for intersection and other purposes of 3D maths.&lt;br /&gt;
|-&lt;br /&gt;
||[[Get Profile Picture]]&lt;br /&gt;
||[[User:Valentine Foxdale|Valentine Foxdale]]&lt;br /&gt;
||Sets the texture of the object to profile picture of the person that touches ot&lt;br /&gt;
|-&lt;br /&gt;
||[[GetTimestampOffset]]&lt;br /&gt;
||[[User:Siann_Beck|Siann Beck]]&lt;br /&gt;
||Returns [[llGetTimestamp]]() with an hour offset.&lt;br /&gt;
|-&lt;br /&gt;
||[[Give InvItem every n hours]]&lt;br /&gt;
||[[User:Criz Collins|Criz Collins]]&lt;br /&gt;
||Will give an inventory item on touch only every n hours, even if somebody touches the object more than once. &lt;br /&gt;
|-&lt;br /&gt;
||[[Give random object]]&lt;br /&gt;
||[[User:Emmas Seetan|Emmas Seetan]]&lt;br /&gt;
||Touch to receive a random object in the prim&#039;s inventory&lt;br /&gt;
|-&lt;br /&gt;
||[[Google Charts]]&lt;br /&gt;
||[[User:Dedric Mauriac|Dedric Mauriac]]&lt;br /&gt;
||Create links to display raw data as a chart image.&lt;br /&gt;
|-&lt;br /&gt;
||[[Google_Translator]]&lt;br /&gt;
||[[User:Ugleh Ulrik|Ugleh Ulrik]]&lt;br /&gt;
||Translates spanish to english, and its simple to make it any other way.&lt;br /&gt;
|-&lt;br /&gt;
||[[Go transparent when walking]]&lt;br /&gt;
||[[User:Emmas Seetan|Emmas Seetan]]&lt;br /&gt;
||An attachment that goes invisible when you walk and visible when you don&#039;t walk.&lt;br /&gt;
|-&lt;br /&gt;
||[[Group Authorization]]&lt;br /&gt;
||[[User:Chase Quinnell|Chase Quinnell]]&lt;br /&gt;
||Checks to see if object is set to appropriate group (checks by [[Group key finder|group key]])&lt;br /&gt;
|-&lt;br /&gt;
||[[Group Information v1.0]]&lt;br /&gt;
||[[User:Tyrennic Rivera|Tyrennic Rivera]]&lt;br /&gt;
||When clicked the prim will show group information (set on the prim) from the official Second Life Search page.&lt;br /&gt;
|-&lt;br /&gt;
||[[Group key finder]]&lt;br /&gt;
||[[User:Emmas Seetan|Emmas Seetan]]&lt;br /&gt;
||Touch to find the key of the group&lt;br /&gt;
|-&lt;br /&gt;
||[[Group Privacy]]&lt;br /&gt;
||[[User:Chance Unknown|Chance Unknown]]&lt;br /&gt;
||Security device to insure members of a group can have a private area. Deactivates when nobody present.&lt;br /&gt;
|-&lt;br /&gt;
||[[Hello Avatar]]&lt;br /&gt;
||Linden Lab&lt;br /&gt;
||SL&#039;s default script.&lt;br /&gt;
|-&lt;br /&gt;
||[[Hello Avatar Companion]]&lt;br /&gt;
||[[Chase Quinnell]]&lt;br /&gt;
||Companion to the original [[Hello Avatar]] script&lt;br /&gt;
|-&lt;br /&gt;
||[[Hierarchics]]&lt;br /&gt;
||[[User:Nexii Malthus|Nexii Malthus]]&lt;br /&gt;
|| Advanced script to create an efficient self-aware hierarchic structure.&lt;br /&gt;
|-&lt;br /&gt;
||[[Hierarchics2]]&lt;br /&gt;
||[[User:Nexii Malthus|Nexii Malthus]]&lt;br /&gt;
|| Second generation, one script per object. Only two functions, can be embedded in others. Uses the new [[llSetLinkPrimitiveParamsFast]]/[[llGetLinkPrimitiveParams]] functions.&lt;br /&gt;
|-&lt;br /&gt;
||[[User:Rolig_Loon/High-Capacity_Greeter-Counter|High-Capacity Greeter-Counter]]&lt;br /&gt;
||[[User:Rolig Loon|Rolig Loon]]&lt;br /&gt;
||Uses a memory compression algorithm to store hashed visitor UUID&#039;s in a string instead of using a list. &lt;br /&gt;
|-&lt;br /&gt;
||[[Holodeck]]&lt;br /&gt;
||[[User:Revolution Perenti|Revolution Perenti]]&lt;br /&gt;
||Home Rezzing System (Open Source).&lt;br /&gt;
|-&lt;br /&gt;
||[[HUD Dots Radar]]&lt;br /&gt;
||[[User:Cerise Sorbet|Cerise]]&lt;br /&gt;
||HUD target example, draws dots on the HUD over avatars in view.&lt;br /&gt;
|-&lt;br /&gt;
||[[Interpolation|Interpolation Library]]&lt;br /&gt;
||[[User:Nexii_Malthus|Nexii Malthus]]&lt;br /&gt;
||A small set of interpolation functions.&lt;br /&gt;
|-&lt;br /&gt;
||[[Intra-Region Update Server]]&lt;br /&gt;
||[[User:Emma_Nowhere|Emma Nowhere]]&lt;br /&gt;
||Centrally update objects such as Freeview screens or teleport pads within a region that are configured by notecards or contain modifiable objects or media assets.&lt;br /&gt;
|-&lt;br /&gt;
||[[Inventory_Based_Menu]]&lt;br /&gt;
||[[User:Revolution Perenti|Revolution Perenti]]&lt;br /&gt;
||Inventory Based Menu System.&lt;br /&gt;
|-&lt;br /&gt;
||[[iTunes RPC Email|iTunes RPC]]&lt;br /&gt;
||[[User:Fox Diller|Fox Diller]]&lt;br /&gt;
||iTunes RPC via LSL [[llEmail]] and [[llRemoteDataReply]].&lt;br /&gt;
|-&lt;br /&gt;
||[[Kilt Editor|Kilt / Skirt Editor]]&lt;br /&gt;
||[[User:Brangus Weir|Brangus Weir]]&lt;br /&gt;
|| This changes all the parameters of all the flexis in the link set in one swell foop!&lt;br /&gt;
|-&lt;br /&gt;
||[[Key Pad Door|Keypad Door]]&lt;br /&gt;
||[[User:Tdub Dowler|Tdub Dowler]]&lt;br /&gt;
|| Door and keypad with changeable code. Follow instructions carefully!&lt;br /&gt;
|-&lt;br /&gt;
||[[Last Sound System]]&lt;br /&gt;
||[[User:Babbage Linden|Babbage Linden]]&lt;br /&gt;
||An LSL [http://Last.fm Last.fm] client.&lt;br /&gt;
|-&lt;br /&gt;
||[[LibraryDisplayLandScreenshot]]&lt;br /&gt;
||[[User:Jon Desmoulins|Jon Desmoulins]]&lt;br /&gt;
||A modified version of LibraryDisplayProfilePic using the new [[PARCEL_DETAILS_ID]] Implemented in Server v1.36&lt;br /&gt;
|-&lt;br /&gt;
||[[User:Daemonika_Nightfire/Scripts/LinkNumber-List_in_llSetLinkPrimitiveParamsFast|LinkNumber-List_in_llSetLinkPrimitiveParamsFast]]&lt;br /&gt;
||[[User:Daemonika Nightfire|Daemonika Nightfire]]&lt;br /&gt;
||Changed several prims in linkset with the same parameters, with a list. Without separate llSetLinkPrimitiveParams for each prim. (ideal for show/hide effects)&lt;br /&gt;
|-&lt;br /&gt;
||[[Linkset resizer]]&lt;br /&gt;
||[[User:Maestro Linden|Maestro Linden]]&lt;br /&gt;
||Systematically rescales a linkset by moving and resizing each prim (by using [[llGetLinkPrimitiveParams]] and [[llSetLinkPrimitiveParamsFast]])&lt;br /&gt;
|-&lt;br /&gt;
||[[Linkset resizer with menu]]&lt;br /&gt;
||[[User:Brilliant Scientist|Brilliant Scientist]]&lt;br /&gt;
||A menu-driven script that rescales a linkset by moving and resizing the prims using [[llGetLinkPrimitiveParams]] and [[llSetLinkPrimitiveParamsFast]] functions. Based on [[Linkset resizer]].&lt;br /&gt;
|-&lt;br /&gt;
||[[Linkset Resizer 2]]&lt;br /&gt;
||[[User:Emma Nowhere|Emma Nowhere]]&lt;br /&gt;
||A more user-friendly resizer script designed for either drop-in use by the end-user or builder or for use in products. Based on [[Fix Small Prims]].&lt;br /&gt;
|-&lt;br /&gt;
||[[List2CSV]]&lt;br /&gt;
||[[User:Kunnis Basiat|Kunnis Basiat]]&lt;br /&gt;
||List2CSV &amp;amp; CSV2List that include preserving type and escaping characters.&lt;br /&gt;
|-&lt;br /&gt;
||[[list_cast]]&lt;br /&gt;
||[[User:Fractured Crystal|Fractured Crystal]]&lt;br /&gt;
||Casts a list of strings into the type they appear to be. Designed for preprocessing user input for feeding into [[llSetPrimitiveParams]]&lt;br /&gt;
|-&lt;br /&gt;
||[[Listener Script]]&lt;br /&gt;
||[[User:Emmas Seetan|Emmas Seetan]]&lt;br /&gt;
||Use to [[listen]] to other people&#039;s conversations (Like spying)&lt;br /&gt;
|-&lt;br /&gt;
||[[User:Void_Singer/Functions#List:_Find_Last_Index|List: Find Last Index]]&lt;br /&gt;
||[[User:Void Singer|Void Singer]]&lt;br /&gt;
||Returns the last index of searched item in a source list. (backwards version of [[llListFindList]])&lt;br /&gt;
|-&lt;br /&gt;
||[[User:Void_Singer/Functions#List:_Multi-Find_Index_.28First_or_Last.29|List: Multi Find]]&lt;br /&gt;
||[[User:Void Singer|Void Singer]]&lt;br /&gt;
||Returns the first found index of multiple search items in a list. (Multi-item version of [[llListFindList]]. Fwd and Rev versions included)&lt;br /&gt;
|-&lt;br /&gt;
||[[User:Void_Singer/Functions#List:_Get_Reverse_Order|List: Reverse]]&lt;br /&gt;
||[[User:Void Singer|Void Singer]]&lt;br /&gt;
||Returns an input List in reverse order&lt;br /&gt;
|-&lt;br /&gt;
||[[Load URL]]&lt;br /&gt;
||[[User:Emmas Seetan|Emmas Seetan]]&lt;br /&gt;
||Touch to get a dialog to visit the URL inside the script.&lt;br /&gt;
|-&lt;br /&gt;
||[[User:Kephra_Nurmi/lsDancemachine|lsDancemachine]]&lt;br /&gt;
||[[User:Kephra_Nurmi|Kephra Nurmi]]&lt;br /&gt;
|| Low lag client server dancemachine.&lt;br /&gt;
|-&lt;br /&gt;
||[[User:Kephra_Nurmi/lsDeejay|lsDeejay Home Edition]] &lt;br /&gt;
||[[User:Kephra_Nurmi|Kephra Nurmi]]&lt;br /&gt;
|| Client server media control for music, video, youtube, pictures, and texture animations.&lt;br /&gt;
|-&lt;br /&gt;
||[[User:Kephra_Nurmi/lsDialog|lsDialog]]&lt;br /&gt;
||[[User:Kephra_Nurmi|Kephra Nurmi]]&lt;br /&gt;
|| Universal notecard driven menu dialog system.&lt;br /&gt;
|-&lt;br /&gt;
||[[User:Kephra_Nurmi/lsDisplay|lsDisplay]]&lt;br /&gt;
||[[User:Kephra_Nurmi|Kephra Nurmi]]&lt;br /&gt;
|| Picture cycler with preloader.&lt;br /&gt;
|-&lt;br /&gt;
||[[User:Kephra_Nurmi/lsDistributor|lsDistributor]]&lt;br /&gt;
||[[User:Kephra_Nurmi|Kephra Nurmi]]&lt;br /&gt;
|| Simple &#039;try&#039; and &#039;buy&#039; vendor system.&lt;br /&gt;
|-&lt;br /&gt;
||[[LSL_languageAPI]]&lt;br /&gt;
||[[User:Gypsy paz|Gypsy Paz]]&lt;br /&gt;
||Multi-lingual API from notecard based language files&lt;br /&gt;
|-&lt;br /&gt;
||[[Mandelbrot Explorer]]&lt;br /&gt;
||[[User:Babbage Linden|Babbage Linden]]&lt;br /&gt;
||An interactive fractal explorer.&lt;br /&gt;
|-&lt;br /&gt;
||[[Materialization Effects]]&lt;br /&gt;
||[[User:Overbrain Unplugged|Overbrain Unplugged]]&lt;br /&gt;
|| Special effects to add to rezzing events to simulate a teleportation or materialization.&lt;br /&gt;
|-&lt;br /&gt;
||[[Merge Sort]]&lt;br /&gt;
||[[User:Xaviar Czervik|Xaviar Czervik]]&lt;br /&gt;
||Implements a Merge Sort in LSL, however this code is 300(ish) times slower than [[llListSort]]. Don&#039;t use this in a script!&lt;br /&gt;
|-&lt;br /&gt;
||[[Minesweeper]]&lt;br /&gt;
||[[User:Xaviar Czervik|Xaviar Czervik]]&lt;br /&gt;
||A simple minesweeper game.&lt;br /&gt;
|-&lt;br /&gt;
||[[Morse Code]]&lt;br /&gt;
||{{User|Bobbyb30 Swashbuckler}}&lt;br /&gt;
||A script that allows for the conversion to and from morse code and can &amp;quot;play&amp;quot; morse code.&lt;br /&gt;
|-&lt;br /&gt;
||[[Multi-displays Texture Cycler]]&lt;br /&gt;
||[[User:Nargus Asturias|Nargus Asturias]]&lt;br /&gt;
||A simple texture rotator designed for multiple display screens. With delay between each screen AND delay between each loop.&lt;br /&gt;
|-&lt;br /&gt;
||[[Multi Item Rezzer|Multi Item Rezzer]]&lt;br /&gt;
||[[User:Jesse Barnett|Jesse Barnett]]&lt;br /&gt;
||A rework of my old High Altitude Rezzer. Place the objects that you wish to choose from to be rezzed inside. Sit on the rezzer and pick the item and the height. It will go to target height and rez the object.&lt;br /&gt;
|-&lt;br /&gt;
||[[Multirezzer|Multirezzer (on collision)]]&lt;br /&gt;
||[[User:Beet Streeter|Beet Streeter]]&lt;br /&gt;
||Spawns up to 10 objects when the object containing the script collides with a user.&lt;br /&gt;
|-&lt;br /&gt;
||[[Name2Key in LSL]]&lt;br /&gt;
||[[User:Maeva Anatine|Maeva Anatine]]&lt;br /&gt;
||Get the Name2Key feature inside your scripts. Works even on lastly subscribed avatars.&lt;br /&gt;
|-&lt;br /&gt;
||[[No Auto-Return]]&lt;br /&gt;
||[[User:Bellla Clarity|Bella Clarity]]&lt;br /&gt;
||To stop your long and hard builds from getting returned in sandboxes (&#039;&#039;only single prims, though!&#039;&#039;).&lt;br /&gt;
|-&lt;br /&gt;
||[[No Auto-Return NR]]&lt;br /&gt;
||[[User:Jor3l Boa|Jor3l Boa]]&lt;br /&gt;
||This really works (29-05-09), needs a nearby region to do the trick and avoid auto return. (Tested on Blue and Rausch)&lt;br /&gt;
|-&lt;br /&gt;
||[[No Auto-Return (Multi)]]&lt;br /&gt;
||[[User:Xaviar Czervik|Xaviar Czervik]]&lt;br /&gt;
||A revision of Bella&#039;s that works for multi-prim objects.&lt;br /&gt;
|-&lt;br /&gt;
||[[No Limit Teleporter]]&lt;br /&gt;
||[[User:Morgam Biedermann|Morgam Biedermann]]&lt;br /&gt;
||Teleport to infinite altitudes (up to 4096m)&lt;br /&gt;
|-&lt;br /&gt;
||[[Object Size]]&lt;br /&gt;
||[[User:Chase Quinnell|Chase Quinnell]]&lt;br /&gt;
||Gets the dimensions and footprint of a linkset&lt;br /&gt;
|-&lt;br /&gt;
||[[Object to Data v1.3|Object to Data]]&lt;br /&gt;
||[[User:Xaviar Czervik|Xaviar Czervik]]&lt;br /&gt;
||Turns an object into text (and back). Allows people to transfer objects through notecards (or otherwise).&lt;br /&gt;
|-&lt;br /&gt;
||[[Online Indicator|Online Indicator]]&lt;br /&gt;
||[[User:Kristy Fanshaw|Kristy Fanshaw]]&lt;br /&gt;
||Will show if the user is online or not. Displays users profile picture and allows to send IM&#039;s to user. Also gives a link to open the users profile&lt;br /&gt;
|-&lt;br /&gt;
||[[Open Group Join]]&lt;br /&gt;
||[[User:Alicia Stella|Alicia Stella]]&lt;br /&gt;
||User Touches Object to Join Group from Group Info window, (no bot.)&lt;br /&gt;
|-&lt;br /&gt;
||[[Open Prim Animator]]&lt;br /&gt;
||[[User:Todd Borst|Todd Borst]]&lt;br /&gt;
||Single script prim animation tool.  Menu driven, easy to use.&lt;br /&gt;
|-&lt;br /&gt;
||[[Open Zyngo Skin Installer]]&lt;br /&gt;
||[[User:Tmzasz Luminos|Tmzasz Luminos]]&lt;br /&gt;
||A Simple Script designed to install skins on the popular Skill machines.&lt;br /&gt;
|-&lt;br /&gt;
||[[One Script, many doors]]&lt;br /&gt;
||[[User:Kyrah Abattoir|Kyrah Abattoir]]&lt;br /&gt;
||Door script able to manage more than 50 linked doors from a single script instance.&lt;br /&gt;
|-&lt;br /&gt;
||[[ParseString2List]]&lt;br /&gt;
||[[User:Strife Onizuka|Strife Onizuka]]&lt;br /&gt;
||Same as [[llParseString2List]] and [[llParseStringKeepNulls]], but not limited to 8 spacers or separators. Thus substitute a call to the [[llParseString2List]] and [[llParseStringKeepNulls]] functions by a call to [[Parse_String_To_List|ParseString2List]] whenever you have more than 8 separators or more than 8 spacers.&lt;br /&gt;
|-&lt;br /&gt;
||[[Password Generator]]&lt;br /&gt;
||[[User:Syntrax Canucci|Syntrax Canucci]]&lt;br /&gt;
||This is an over-complicated, semi-complex password generator, which goes through multiple steps.&lt;br /&gt;
|-&lt;br /&gt;
||[[Pathfinder]]&lt;br /&gt;
||[[User:Babbage Linden|Babbage Linden]]&lt;br /&gt;
||A potential field based pathfinding library.&lt;br /&gt;
|-&lt;br /&gt;
||[[Personal ATM Machine]]&lt;br /&gt;
||[[User:Jessikiti Nikitin|Jessikiti Nikitin]]&lt;br /&gt;
||Allows deposits and withdrawals into another of your accounts, without the account being logged in.&lt;br /&gt;
|-&lt;br /&gt;
||[[Phantom Child]]&lt;br /&gt;
||[[User:Aeron Kohime|Aeron Kohime]]&lt;br /&gt;
||Causes a child in a link set to become phantom without the entire object becoming phantom.&lt;br /&gt;
|-&lt;br /&gt;
||[[PhysicsLib]]&lt;br /&gt;
||[[User:Nexii Malthus|Nexii Malthus]]&lt;br /&gt;
|| Interesting set of fun physics functions.&lt;br /&gt;
|-&lt;br /&gt;
||[[Play and Loop Sound]]&lt;br /&gt;
||[[User:Bellla Clarity|Bella Clarity]]&lt;br /&gt;
||Very short and simple script; plays and loops a sound in an object.&lt;br /&gt;
|-&lt;br /&gt;
||[[Posing stand|Posing Stand]]&lt;br /&gt;
||[[User:Bellla Clarity|Bella Clarity]]&lt;br /&gt;
||Just a pose script to edit [[attachments]] more easily.&lt;br /&gt;
|-&lt;br /&gt;
||[[PosJump]]&lt;br /&gt;
||[[User:Uchi Desmoulins|Uchi Desmoulins]]&lt;br /&gt;
||A much more efficient alternative to the popular [[warpPos]] function for bypassing 10m distance-moved limitations.&lt;br /&gt;
|-&lt;br /&gt;
||[[Prefix Calculator]]&lt;br /&gt;
||[[User:Xaviar Czervik|Xaviar Czervik]]&lt;br /&gt;
|| A calculator that evaluates expressions in prefix notation. &lt;br /&gt;
&amp;lt;code&amp;gt;+ 3 4 = 5. * + 1 2 + 3 4 = 14.&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
||[[Progress Bar]]&lt;br /&gt;
||[[User:Nexii Malthus|Nexii Malthus]]&lt;br /&gt;
|| Flexible and powerful little function for creating progress bars useful in hovertext.&lt;br /&gt;
|-&lt;br /&gt;
||[[Pseudo-random Number Generator]]&lt;br /&gt;
||[[User:Xaviar Czervik|Xaviar Czervik]]&lt;br /&gt;
||Generates a Pseudo-random number between -0x7FFFFFFF and 0x7FFFFFFF&lt;br /&gt;
|-&lt;br /&gt;
||[[User:Rolig_Loon/Quiz_From_Notecard|Quiz From Notecard]]&lt;br /&gt;
||[[User:Rolig Loon|Rolig Loon]]&lt;br /&gt;
||A multiple-choice testing script that reads questions and answer choices from a notecard and presents them in dialog boxes.&lt;br /&gt;
|-&lt;br /&gt;
||[[Rainbow_palette]]&lt;br /&gt;
||[[User:Rui Clary|Rui Clary]]&lt;br /&gt;
||Build a color picker, using only one prim, and a few lines of code.&lt;br /&gt;
|-&lt;br /&gt;
||[[Random Gaussian Number Generator]]&lt;br /&gt;
||[[User:Vlad Davidson|Vlad Davidson]]&lt;br /&gt;
||Generates a random number drawn from a normal (Gaussian; bell-curve) distribution, based on a specified mean/stdev&lt;br /&gt;
|-&lt;br /&gt;
||[[Random AV Profile Projector]]&lt;br /&gt;
||[[User:Debbie Trilling|Debbie Trilling]]&lt;br /&gt;
||Randomly selects an AV from a crowd &amp;amp; then projects their profile picture as a &#039;holographic&#039; image &lt;br /&gt;
|-&lt;br /&gt;
||[[Random Object Vendor]]&lt;br /&gt;
||[[User:CodeBastard Redgrave|CodeBastard Redgrave]]&lt;br /&gt;
||Simple vendor that gives out random objects when paid the right amount &lt;br /&gt;
|-&lt;br /&gt;
||[[Random Password Generator]]&lt;br /&gt;
||[[User:Jor3l Boa|Jor3l Boa]]&lt;br /&gt;
||Generate Random passwords based on String Length.&lt;br /&gt;
|-&lt;br /&gt;
||[[RavText]]&lt;br /&gt;
||[[User:Ravenous Dingo|Ravenous Dingo]]&lt;br /&gt;
||An alternate to XyText.  This is a lightweight, multiple font 10 character text display system.  It only supports uppercase alphanumeric text and a few special characters, but it is very fast, renders quickly and supports multiple fonts. It is meant for specialized use when all that is desired is basic, fast text display and the extra &amp;quot;bells and whistles&amp;quot; are not needed.&lt;br /&gt;
|-&lt;br /&gt;
||[[User:PixelProphet Lane/Scripts#Real Object Inventory To Dialog|Real Object Inventory To Dialog]]&lt;br /&gt;
||[[User:PixelProphet Lane|PixelProphet Lane]]&lt;br /&gt;
||Display any amount of items contained in an Object in a Dialog, regardless of item name length.&lt;br /&gt;
|-&lt;br /&gt;
||[[RentalBoxv1|Rental Box, Simply]]&lt;br /&gt;
||[[User:Sendao Goodman|Sendao Goodman]]&lt;br /&gt;
||Simple explanation of how to make rental boxes.&lt;br /&gt;
|-&lt;br /&gt;
||[[Rental Cube]]&lt;br /&gt;
||[[User:Hank Ramos|Hank Ramos]]&lt;br /&gt;
||Simple cube for renting out a space.&lt;br /&gt;
|-&lt;br /&gt;
||[[Remote Texture Loader]]&lt;br /&gt;
||{{User|Bobbyb30 Swashbuckler}}&lt;br /&gt;
||A set of scripts for remotely loading textures within a sim. This means that a single &amp;quot;texture server&amp;quot; can manage multiple changing billboards within a sim.&lt;br /&gt;
|-&lt;br /&gt;
||[[Say Region Frames Per Second|Region Frames Per Second]]&lt;br /&gt;
||[[User:Heymeriou Mystakidou|Heymariou Mystakidou]]&lt;br /&gt;
|| Says the region name and frames per second out loud on command.&lt;br /&gt;
|-&lt;br /&gt;
||[[Resizer multi-prims|Resizer multi-prims]]&lt;br /&gt;
||[[User:Christy Mansbridge|Christy Mansbridge]]&lt;br /&gt;
||1 Mono script to resize object (1 to 256 prims) by blue menu. Avoid risk to break the build by increasing link distance.&lt;br /&gt;
|-&lt;br /&gt;
||[[sbDialog]]&lt;br /&gt;
||[[User:Siann_Beck|Siann Beck]]&lt;br /&gt;
||A simple replacement function for [[llDialog]]. It re-orders the button list so that the button values, as passed to it, display left-to-right, top-to-bottom. It also opens a [[llListen|listen]] on the specified channel, and returns the handle.&lt;br /&gt;
|-&lt;br /&gt;
||[[Scheduler]]&lt;br /&gt;
||[[User:Haravikk Mistral|Haravikk Mistral]]&lt;br /&gt;
||Schedule multiple events using a single script timer&lt;br /&gt;
|-&lt;br /&gt;
||[[Scheme_Interpreter|Scheme Interpreter]]&lt;br /&gt;
||[[User:Xaviar Czervik|Xaviar Czervik]]&lt;br /&gt;
||A scheme interpreter capable of handling most scheme expressions, including lambda and lists.&lt;br /&gt;
|-&lt;br /&gt;
||[[Script Override Functions]]&lt;br /&gt;
||[[User:Revolution Perenti|Revolution Perenti]]&lt;br /&gt;
||bypass default strings, integer etc in chat channel.&lt;br /&gt;
|-&lt;br /&gt;
||[[Scripted Attachment Detector.lsl|Scripted Attachment Detector]]&lt;br /&gt;
||{{User|Bobbyb30 Swashbuckler}}&lt;br /&gt;
||A script that will display avatars wearing scripted attatchments in hovertext. This may be worn as an hud or rezzed. &lt;br /&gt;
|-&lt;br /&gt;
||[[Self Upgrading Script Enhanced]]&lt;br /&gt;
||[[User:Cron Stardust|Cron Stardust]]&lt;br /&gt;
||Keeps only latest version of the script on prim (even with multiple adds of the same script!)&lt;br /&gt;
|-&lt;br /&gt;
||[[Sensor Visualizer]]&lt;br /&gt;
||[[User:Cerise Sorbet|Cerise Sorbet]]&lt;br /&gt;
||Shows the size and shape you get with [[llSensor]] range and arc parameters&lt;br /&gt;
|-&lt;br /&gt;
||[[Serverless Key Exchange]]&lt;br /&gt;
||[[User:Sendao Goodman|Sendao Goodman]]&lt;br /&gt;
||Maintains a network of object keys without using an external server.&lt;br /&gt;
|-&lt;br /&gt;
||[[SHA1|SHA1 Hash]]&lt;br /&gt;
||[[User:Strife Onizuka|Strife Onizuka]]&lt;br /&gt;
||Performs a SHA1 Hash on an input text. Similar to MD5 only (slightly) more secure. &lt;br /&gt;
|-&lt;br /&gt;
||[[Shoutcast - radio controller v0.3 (remake of similar scripts)]]&lt;br /&gt;
||[[User:Flennan Roffo|Logic Scripts]]&lt;br /&gt;
||Control your shoutcast radio stations with this shoutcast controller. Uses notecard for info about genres and stations and menu to select the station. Sends info to Xytext display.&lt;br /&gt;
|-&lt;br /&gt;
||[[User:PixelProphet Lane/Scripts#Show Agent Script Count and memory|Show Agent Script Count and memory]]&lt;br /&gt;
||[[User:PixelProphet Lane|PixelProphet Lane]]&lt;br /&gt;
||Fast and efficient method to display the amount of scripts and memory usage for an agent&lt;br /&gt;
|-&lt;br /&gt;
||[[Sim Map Particle Projector]]&lt;br /&gt;
||[[User:Jesse Barnett|Jesse Barnett]]&lt;br /&gt;
||Displays a floating map of the sim the script is in.&lt;br /&gt;
|-&lt;br /&gt;
||[[Sim Restart Logger]]&lt;br /&gt;
||[[User:Kyrah Abattoir|Kyrah Abattoir]]&lt;br /&gt;
||Counts region restarts and displays log of last 9 restarts together with region FPS and dilation. &lt;br /&gt;
|-&lt;br /&gt;
||[[Simple Elevator in a Box]]&lt;br /&gt;
||[[User:Hank Ramos|Hank Ramos]]&lt;br /&gt;
||Simple elevator example.&lt;br /&gt;
|-&lt;br /&gt;
||[[Simple Pay Door]]&lt;br /&gt;
||[[User:Giygas Static|Giygas Static]]&lt;br /&gt;
||Simple door you pay to get access.&lt;br /&gt;
|-&lt;br /&gt;
||[[Skillingo AntiHack Script]]&lt;br /&gt;
||[[User:Tmzasz Luminos|Tmzasz Luminos]]&lt;br /&gt;
||A simple Protection script for skillingo thats modifyable to work with other machines.&lt;br /&gt;
|-&lt;br /&gt;
||[[Skunk Money]]&lt;br /&gt;
||[[User:Hank Ramos|Hank Ramos]]&lt;br /&gt;
||Fun gambling machine of yesteryear, which only supports freeplay now due to SL regulations against gambling. &lt;br /&gt;
|-&lt;br /&gt;
||[[SLateIt]]&lt;br /&gt;
||[[User:Babbage Linden|Babbage Linden]]&lt;br /&gt;
||An augmented virtual reality HUD.&lt;br /&gt;
|-&lt;br /&gt;
||[[SLetanque]]&lt;br /&gt;
||[[User:Babbage Linden|Babbage Linden]]&lt;br /&gt;
||An LSL petanque game.&lt;br /&gt;
|-&lt;br /&gt;
||[[SLURL HUD]]&lt;br /&gt;
||[[User:CodeBastard Redgrave|CodeBastard Redgrave]]&lt;br /&gt;
||Touch this HUD to get a SLURL through IM, email and floating text.&lt;br /&gt;
|-&lt;br /&gt;
||[[BuildSlurl (NewAge)]]&lt;br /&gt;
||[[User:Archile Azalee|Archile Azalee]]&lt;br /&gt;
||A way to create a SLurl in a single function BuildSlurl&lt;br /&gt;
|-&lt;br /&gt;
||[[SL Mail V1.2]]&lt;br /&gt;
||[[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
||Second Life mail client V1.2 (released sept&#039;07). Send and receive mail from within Second Life from and to any address. With Address Book function and many chat commands. V1.3 is upcoming soon! &lt;br /&gt;
|-&lt;br /&gt;
||[[SL_NTPoHTTP_v1.1_client|SL NTPoHTTP client]]&lt;br /&gt;
|[[User:SignpostMarv Martin|SignpostMarv Martin]]&lt;br /&gt;
||Second Life Needs Time Parsing over Hyper Text Transfer Protocol&lt;br /&gt;
Emulates the function of [[llGetWallclock]] for any timezone by using SLOpenID&#039;s SLNTPoHTTP service. Also supports ISO 8601 and RFC 2822 timestamps. Script is dependent upon an external service operated by the author!&lt;br /&gt;
|-&lt;br /&gt;
||[[Smooth Rotating Door]]&lt;br /&gt;
|[[User:Toy Wylie|Toy Wylie]]&lt;br /&gt;
||A script for doors that open and close smoothly using llTargetOmega&lt;br /&gt;
|-&lt;br /&gt;
||[[Smooth Sliding Door]]&lt;br /&gt;
|[[User:SimonT Quinnell|SimonT Quinnell]]&lt;br /&gt;
||A script for sliding doors that open and close smoothly using [[llMoveToTarget]]. Asjusts for prim orientation.&lt;br /&gt;
|-&lt;br /&gt;
||[[Speed Tester]]&lt;br /&gt;
||{{User|Bobbyb30 Swashbuckler}}&lt;br /&gt;
||Similar to the [[Efficiency Tester]], this script allows you to test the speed of a particular function or snippet with multiple trials giving min/max/avg/median and the standard deviation.&lt;br /&gt;
|-&lt;br /&gt;
||[[Spiral Staircase Generator]]&lt;br /&gt;
|[[User:Meyermagic Salome|Meyermagic Salome]]&lt;br /&gt;
||Generates nice looking spiral staircases without much hassle.&lt;br /&gt;
|-&lt;br /&gt;
||[[Static URL&#039;s for HTTP-In Service|Static_URLs]]&lt;br /&gt;
||[[User:Jor3l Boa|Jor3l Boa]]&lt;br /&gt;
||How to generate a static url for HTTP-In temporal limitations.&lt;br /&gt;
|-&lt;br /&gt;
||[[String Compare]]&lt;br /&gt;
||[[User:Xaviar Czervik|Xaviar Czervik]]&lt;br /&gt;
||Compares two strings and reliably returns either 1, -1, or 0 if they are the same.&lt;br /&gt;
|-&lt;br /&gt;
||[[Synchronize]]&lt;br /&gt;
||[[User:Cay Trudeau|Cay Trudeau]]&lt;br /&gt;
||Makes synchronized start to a task on even/odd seconds&lt;br /&gt;
|-&lt;br /&gt;
||[[User:Void_Singer/Functions#String:_Find_Last_Index|String: Reverse]]&lt;br /&gt;
||[[User:Void Singer|Void Singer]]&lt;br /&gt;
||Returns an input string in reverse order&lt;br /&gt;
|-&lt;br /&gt;
||[[User:Void_Singer/Functions#String:_Get_Reverse_Order|String: Last Index]]&lt;br /&gt;
||[[User:Void Singer|Void Singer]]&lt;br /&gt;
||Returns the last index of search found in string (the backward equivalent of [[llSubStringIndex]])&lt;br /&gt;
|-&lt;br /&gt;
||[[Tail Messages (NewAge)]]&lt;br /&gt;
||[[User:Asia Snowfall|Asia Snowfall]]&lt;br /&gt;
||A super nice easy to use script for those non-scripters out there! NewAge coding has done it again where you no longer need to scroll up and down adding buttons and adding messages, Features a tag system (you&#039;ll see what i mean :P)&lt;br /&gt;
|-&lt;br /&gt;
||[[Teleport HUD]]&lt;br /&gt;
||[[User:Jesse Barnett|Jesse Barnett]]&lt;br /&gt;
||WORKS TO 4096 METERS!! Very user friendly teleport HUD. Add destinations by touching &amp;quot;Add&amp;quot; &amp;amp; naming destination in chat. Automatically gets sim name and coordinates. Will only display the destinations in the sim you are currently in. Demonstrates more advanced list manipulation and stride functions.&lt;br /&gt;
|-&lt;br /&gt;
||[[User:Void_Singer/Programs#v7-D_Enh._Landmark-2-Map|Teleporter (landmark based)]]&lt;br /&gt;
||[[User:Void_Singer|Void_Singer]]&lt;br /&gt;
||Uses Landmarks to offer map teleports. Works as Hud or inworld objects, just drop in landmarks and go.&lt;br /&gt;
|-&lt;br /&gt;
||[[Text_Scroller|Text Scroller]]&lt;br /&gt;
||[[User:Fred_Gandt|Fred Gandt]]&lt;br /&gt;
||A simple text display object that scrolls text (applied as a texture) from right to left (like &#039;&#039;those&#039;&#039; LED signs) in a continuous loop.&lt;br /&gt;
|-&lt;br /&gt;
||[[Bobbyb&#039;s texture changer|Texture Changers]]&lt;br /&gt;
||{{User|Bobbyb30 Swashbuckler}}&lt;br /&gt;
||A collection of texture changing scripts.&lt;br /&gt;
|-&lt;br /&gt;
||[[Texture Menu Management|Texture Management]]&lt;br /&gt;
||[[User:Revolution Perenti|Revolution Perenti]]&lt;br /&gt;
||Dialog Menu based Texture Selection.&lt;br /&gt;
|-&lt;br /&gt;
||[[Tic Tac Toe]]&lt;br /&gt;
||[[User:CG Linden|CG Linden]]&lt;br /&gt;
||Step by step demo on how to implement a larger scripting project&lt;br /&gt;
|-&lt;br /&gt;
||[[TightList]]&lt;br /&gt;
||[[User:Strife Onizuka|Revolution Perenti]]&lt;br /&gt;
||Tight List is a family of functions for encoding lists as strings and then decoding them back into lists.&lt;br /&gt;
There are two flavors: TightList and TightListType. TightListType preserves types and uses a 6 char header, while TightList uses a 1 char header that doesn&#039;t preserve type. &lt;br /&gt;
|-&lt;br /&gt;
||[[Timer Module]]&lt;br /&gt;
||[[User:Isabelle Aquitaine|Isabelle Aquitaine]]&lt;br /&gt;
||Manage multiple timers via linked messages.&lt;br /&gt;
|-&lt;br /&gt;
||[[User:Void_Singer/Functions#Unix_time_code_to_list_format|Timestamp:&amp;lt;br&amp;gt;Unix time code to list format]]&lt;br /&gt;
||[[User:Void Singer|Void Singer]]&lt;br /&gt;
||converts Unix timestamps to their [Y, M, D, h, m, s] equivalents (ex: 1234567890 to [2009, 2, 13, 3, 31, 30])&lt;br /&gt;
|-&lt;br /&gt;
||[[User:Void_Singer/Functions#List_format_to_Unix_time_code.|Timestamp:&amp;lt;br&amp;gt;List format to Unix time code]]&lt;br /&gt;
||[[User:Void Singer|Void Singer]]&lt;br /&gt;
||converts [Y, M, D, h, m, s] timestamps to their Unix equivalents (ex: [2009, 2, 13, 3, 31, 30] to 1234567890)&lt;br /&gt;
|-&lt;br /&gt;
||[[User:Void_Singer/Functions#Weekday_from_Unix_timestamp|Timestamp:&amp;lt;br&amp;gt;Weekday from Unix timestamp]]&lt;br /&gt;
||[[User:Void Singer|Void Singer]]&lt;br /&gt;
||Gets weekday from Unix timestamps (ex: &amp;quot;Friday&amp;quot; from 1234567890)&lt;br /&gt;
|-&lt;br /&gt;
||[[User:Void_Singer/Functions#Weekday_from_.28_Y.2C_M.2C_D_.29_format|Timestamp:&amp;lt;br&amp;gt;Weekday from (Y, M, D) format]]&lt;br /&gt;
||[[User:Void Singer|Void Singer]]&lt;br /&gt;
||Gets weekday from (Y, M, D) timestamps (ex: &amp;quot;Friday&amp;quot; from (2009, 2, 13))&lt;br /&gt;
|-&lt;br /&gt;
||[[Touch A Quote]]&lt;br /&gt;
||[[User:CodeBastard Redgrave|CodeBastard Redgrave]]&lt;br /&gt;
||Touch an object to read quotes sequentially from a notecard&lt;br /&gt;
|-&lt;br /&gt;
||[[Touring Balloon]]&lt;br /&gt;
||[[User:Hank Ramos|Hank Ramos]]&lt;br /&gt;
||Automated touring balloon with many options from long ago.  Always seems to work on one SL release, and not the other.&lt;br /&gt;
|-&lt;br /&gt;
||[[Under Age Boot]]&lt;br /&gt;
|[[User:Chance Unknown|Chance Unknown]]&lt;br /&gt;
||Security device example to teleport home accounts below a minimum age limit; can be useful in combating free griefer accounts.&lt;br /&gt;
|-&lt;br /&gt;
||[[User:Rolig_Loon/UNDO_PosRot|UNDO_PosRot]]&lt;br /&gt;
||[[User:Rolig Loon|Rolig Loon]]&lt;br /&gt;
||Allows user to undo position and rotation changes that have been made &amp;quot;manually&amp;quot; to any or all prims in a linkset.&lt;br /&gt;
|-&lt;br /&gt;
||[[Universal Translator]]&lt;br /&gt;
|[[User:Hank Ramos|Hank Ramos]]&lt;br /&gt;
||Chat listener that handles seamless translation of public chat between 50+ written languages without the need for configuration.  Handles numerous avatars, auto-detects languages, and works together with multiple copies of translators to spread-workload using a sophisticated back-end communications sub-system.&lt;br /&gt;
|-&lt;br /&gt;
||[[Unix2DateTime]]&lt;br /&gt;
|[[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
||Conversion from Unix time ([[llGetUnixTime]]()) to date and time string and vice versa.&lt;br /&gt;
|-&lt;br /&gt;
||[[Unmutable Descript Nagger]]&lt;br /&gt;
|[[User:Bobbyb30 Zohari|Bobbyb30 Zohari]]&lt;br /&gt;
||To nag avatars to take off their scripted attatchments.&lt;br /&gt;
|-&lt;br /&gt;
||[[Unpacker On Rez (NewAge)]]&lt;br /&gt;
|[[User:Asia Snowfall|Asia Snowfall]]&lt;br /&gt;
||A very simple to use script for all you creators out there, This script will enable you to send out boxed items and make it easier for users to unpack, Also features auto die on completion. Very simple to configure!&lt;br /&gt;
|-&lt;br /&gt;
||[[Unpacker On Touch (NewAge)]]&lt;br /&gt;
|[[User:Asia Snowfall|Asia Snowfall]]&lt;br /&gt;
||Exactly like Unpacker On Rez, But changed some things about to make it Unpack On Touch&lt;br /&gt;
|-&lt;br /&gt;
||[[Update distributor]]&lt;br /&gt;
|[[User:Dale Innis|Dale Innis]]&lt;br /&gt;
||Distribute an object (like a project update) to a list of people named in a notecard.&lt;br /&gt;
|-&lt;br /&gt;
||[[UUID2Channel]]&lt;br /&gt;
||[[User:Project Neox|Project Neox]]&lt;br /&gt;
||Optimised version of the original key2channel generators.&lt;br /&gt;
|-&lt;br /&gt;
||[[UUID Song Generator]]&lt;br /&gt;
||{{User|Sendao Goodman}}&lt;br /&gt;
||Translates a UUID into a simple song and plays it.&lt;br /&gt;
|-&lt;br /&gt;
||[[VirtualID_URLMap|VirtualID URL Mapper for HTTP-in]]&lt;br /&gt;
|[[User:Cenji Neutra|Cenji Neutra]]&lt;br /&gt;
||A script showing how to setup a static URL of the form &amp;lt;your-alias&amp;gt;.obj.virtualid.info which maps to the dynamic HTTP-in URL LSL generates and keeps it up-to-date.&lt;br /&gt;
|-&lt;br /&gt;
||[[User:Void_Singer/Programs#v7-D_Advanced_Visitor_Greeter|Visitor Greeter]]&lt;br /&gt;
|[[User:Void_Singer|Void_Singer]]&lt;br /&gt;
||Reduced spam visitor greeter, highly configurable, easy to modify.&lt;br /&gt;
|-&lt;br /&gt;
||[[Visitor Logger (Web/Basic) ]]&lt;br /&gt;
|[[User:Buddy Sprocket|Buddy Sprocket]]&lt;br /&gt;
||A very basic visitor logger - log visitors in SL to a text file on your web-site.&lt;br /&gt;
|-&lt;br /&gt;
||[[Vote Simple]]&lt;br /&gt;
|[[User:JB_Kraft|JB Kraft]]&lt;br /&gt;
||Simple vote collector. One avi, one vote.&lt;br /&gt;
|-&lt;br /&gt;
||[[Walking Sound (NewAge)]]&lt;br /&gt;
|[[User:Asia Snowfall|Asia Snowfall]]&lt;br /&gt;
||Very powerful walking sound script, Featuring customer ability to add their own sounds with the API Sound Feature!&lt;br /&gt;
|-&lt;br /&gt;
||[[WarpPos]]&lt;br /&gt;
|[[User:Keknehv Psaltery|Keknehv Psaltery]]&lt;br /&gt;
||Non-physical movement without the 10m limit.&lt;br /&gt;
|-&lt;br /&gt;
||[[Wiki3DBuilder]] [[Wiki3DBuilder1.0]]&lt;br /&gt;
||[[User:Salahzar Stenvaag|Salahzar Stenvaag]] &lt;br /&gt;
||Allows a group of people to collectively build up complex 3D mindmaps with connected concepts. Uses particles for connections and low prim usage. Nodes can be textured, colored, changed form size moved collectively by everybody and can distribute notecards, landmarks, URL, objects, textures. I provide two version 0.1 and 1.0 and probably next version will communicate with moodle and sloodle external websites.&lt;br /&gt;
|-&lt;br /&gt;
||[[Window Control]]&lt;br /&gt;
||[[User:Emmas Seetan|Emmas Seetan]]&lt;br /&gt;
||For window opacity, helpful for buildings.&lt;br /&gt;
|-&lt;br /&gt;
||[[WHMcs SecondLife plugin]]&lt;br /&gt;
|[[User:Alicia Sautereau|Alicia Sautereau]]&lt;br /&gt;
||Linden Dollar payment plugin for the WHMcs hosting portal.&lt;br /&gt;
|-&lt;br /&gt;
||[[XTEA Strong Encryption Implementation]]&lt;br /&gt;
||[[User:Morse Dillon|Morse Dillon]]&lt;br /&gt;
||An LSL implementation of XTEA (eXtended Tiny Encryption Algorithm).  This is the first known public release of a &#039;real&#039; strong encryption implementation in LSL and is released under the GNU General Public License (GPL).&lt;br /&gt;
|-&lt;br /&gt;
||[[XyText 1.5|XyText]]&lt;br /&gt;
||[[User:Xylor Baysklef|Xylor Baysklef]]&lt;br /&gt;
|| Display text (up to 10 characters) on a prim. Use as many prims as desired.&lt;br /&gt;
|-&lt;br /&gt;
||[[XyyyyzText|XyyyyzText]]&lt;br /&gt;
||[[User:Criz Collins|Criz Collins]]&lt;br /&gt;
|| Display text (up to 10 characters) on a prim. Displays different text for each line instead of one single text, that will be broken into the next lines. Watch here for what that means: http://screencast.com/t/1wMLujLcEO&lt;br /&gt;
|-&lt;br /&gt;
||[[XyzzyText|XyzzyText]]&lt;br /&gt;
||[[User:Thraxis Epsilon|Thraxis Epsilon]] and [[User:Gigs Taggart|Gigs Taggart]]&lt;br /&gt;
|| Display text (up to 10 characters) on a prim. Way more efficient than XyText.&lt;br /&gt;
|-&lt;br /&gt;
||[[Youtube TV]]&lt;br /&gt;
||[[User:Morgam Biedermann|Morgam Biedermann]]&lt;br /&gt;
||Watch your favorite Youtube videos / auto set the texture to the parcel media texture.&lt;br /&gt;
|-&lt;br /&gt;
||[[Zero Lag Poseball]]&lt;br /&gt;
||[[User:Jippen Faddoul|Jippen Faddoul]] and [[User:Daemonika Nightfire|Daemonika Nightfire]]&lt;br /&gt;
||A simple poseball with no lag&lt;br /&gt;
|-&lt;br /&gt;
||[[Input number of seconds, get a string back that shows days, hours, minutes, seconds]]&lt;br /&gt;
||[[User:Fire Centaur|Fire Centaur]]&lt;br /&gt;
||Returns a string that displays days, hours, seconds&lt;br /&gt;
|-&lt;br /&gt;
||[[Random Giver Prim]]&lt;br /&gt;
||[[User:Damian Darkwyr|Damian Darkwyr]]&lt;br /&gt;
||A randomized item giver with a game-like twist&lt;br /&gt;
|-&lt;br /&gt;
||[[Client Specific Contents Giver]]&lt;br /&gt;
||[[User:Damian Darkwyr|Damian Darkwyr]]&lt;br /&gt;
||Give Contents only to users of a specific Client. Such as Phoenix, CoolVL or 2.0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Support Script Library==&lt;br /&gt;
These are scripts in other languages, intended to be run on other systems that support scripts written in LSL&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;sortable&amp;quot; {{Prettytable}}&lt;br /&gt;
|- {{Hl2}}&lt;br /&gt;
! &#039;&#039;&#039;Name&#039;&#039;&#039;&lt;br /&gt;
! &#039;&#039;&#039;Creator&#039;&#039;&#039;&lt;br /&gt;
! &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|| [[User:Ina Centaur/UUID/calimg.api|Calendar Image UUID API]]&lt;br /&gt;
|| [[User:Ina Centaur|Ina Centaur]]&lt;br /&gt;
|| API that gives the UUID of an image of a calendar image give month and year arguments.&lt;br /&gt;
|-&lt;br /&gt;
||[[HTTP Post request to a PHP server]]&lt;br /&gt;
||[[User:Corto Maltese|Corto Maltese]]&lt;br /&gt;
|| This small library allows you to make simple POST requests to your website. The libraries allow you to get your request through the variable $_POST on the server. It also include a basic security mechanism aimed to stop hacking. Comprises of LSL client script and PHP server script.&lt;br /&gt;
|-&lt;br /&gt;
|| [[User:Ina Centaur/PHP/k2n.php|Key2Name.php]]&lt;br /&gt;
|| [[User:Ina Centaur|Ina Centaur]]&lt;br /&gt;
|| Get Avatar&#039;s Name using Second Life search service. (like in LSL Key2Name)&lt;br /&gt;
|-&lt;br /&gt;
|| [[Lame_Object_DNS_and_Cross_Sim_Messaging|Lame Object DNS and Cross Sim Messaging]]&lt;br /&gt;
|| [[User:Liandra Ceawlin|Liandra Ceawlin]]&lt;br /&gt;
|| Simple, cheeseball method of doing cross-sim communications with http-in and an external object DNS service.&lt;br /&gt;
|-&lt;br /&gt;
|| [[User:SignpostMarv Martin/PHP/llXorBase64StringsCorrect|llXorBase64StringsCorrect]]&lt;br /&gt;
|| [[User:SignpostMarv Martin|SignpostMarv Martin]]&lt;br /&gt;
|| An implementation of [[llXorBase64StringsCorrect]] in PHP- should be useful if you&#039;re using llXorBase64StringsCorrect to do cryptography work in LSL2 and posting it out to the web via [[llHTTPRequest]].&lt;br /&gt;
|-&lt;br /&gt;
|| [[User:SignpostMarv Martin/PHP/lsl fu.php|lsl_fu.php]]&lt;br /&gt;
|| [[User:SignpostMarv Martin|SignpostMarv Martin]]&lt;br /&gt;
|| A basic OOP&#039;d PHP Class containing VeloxSeverine&#039;s $_POST fixer and Marv&#039;s own eccentric ideas for &amp;quot;fixing&amp;quot; things.&lt;br /&gt;
|-&lt;br /&gt;
|| [[User:Jor3l Boa/PHP/n2k.php|Name2Key.php]]&lt;br /&gt;
|| [[User:Jor3l Boa|Jor3l Boa]]&lt;br /&gt;
|| Get Avatar&#039;s UUID using Second Life search service. (like in LSL Name2Key)&lt;br /&gt;
|-&lt;br /&gt;
|| [[Public_Object_DNS|Public Object DNS]]&lt;br /&gt;
|| [[User:Liandra Ceawlin|Liandra Ceawlin]]&lt;br /&gt;
|| Public object DNS-like system running on GAE, for http-in. Hopefully scalable enough for wide-spread usage.&lt;br /&gt;
|-&lt;br /&gt;
|| Silo&lt;br /&gt;
|| [[User:Zero_Linden|Zero Linden]]&lt;br /&gt;
|| General purpose data store in PHP.  Use this to persist arbitrary data from LSL via [[llHTTPRequest]].  See:&lt;br /&gt;
* [http://www.notabene-sl.com/misc/silo-README.txt README] file&lt;br /&gt;
* [http://www.notabene-sl.com/misc/silo.tgz silo.tgz] tarball&lt;br /&gt;
* forum post [http://forums-archive.secondlife.com/54/69/119570/1.html Announcement].&lt;br /&gt;
|-&lt;br /&gt;
||[[Silverday ObjectDNS]]&lt;br /&gt;
||[[User:Till Stirling|Till Stirling]]&lt;br /&gt;
||Dynamic Object-DNS-System to provide dynamic mapping of LSL-URLs to persistent domains. Features include redirect service, password protected domains, write protected domains, LSL-API for all necessary functions, optional web-interface.&lt;br /&gt;
|-&lt;br /&gt;
|| [http://aubretec.com/products/sldb SLDB]&lt;br /&gt;
|| [[User:Luc Aubret|Luc Aubret]]&lt;br /&gt;
|| Flexible web database storage using PHP/MySQL.  Used to store per-user field/value pairs from in-world objects using [[llHTTPRequest]]. &lt;br /&gt;
* [http://aubretec.com/support/manuals/sldbkit/ Implementation Guide]&lt;br /&gt;
* [http://aubretec.com/wp-content/uploads/2009/05/sldb.zip Download] (.zip, 12kb)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Articles&#039;&#039;&#039;&lt;br /&gt;
*[[:Category:LSL Examples| Examples]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{LSLC|}}&lt;/div&gt;</description>
			<pubDate>Wed, 09 Feb 2011 21:44:02 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Category_talk:LSL_Library</comments>
		</item>
		<item>
			<title>WhoAddedWhat</title>
			<link>https://wiki.secondlife.com/w/index.php?title=WhoAddedWhat&amp;diff=1133331</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=WhoAddedWhat&amp;diff=1133331</guid>
			<description>&lt;p&gt;Flennan Roffo: small typing error corrected&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;To enable you to tell what has been added to a script in the event of &#039;&#039;&#039;CHANGED_ALLOWED_DROP&#039;&#039;&#039; you can use the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;// Scripted by Laronzo Fitzgerald&lt;br /&gt;
&lt;br /&gt;
list content[]; // a list of all items already added to the object&lt;br /&gt;
&lt;br /&gt;
if (change &amp;amp; (CHANGED_ALLOWED_DROP | CHANGED_INVENTORY))&lt;br /&gt;
{&lt;br /&gt;
    integer n = llGetInventoryNumber(INVENTORY_ALL);            &lt;br /&gt;
&lt;br /&gt;
    while(n)&lt;br /&gt;
    {&lt;br /&gt;
         integer valid = llGetListLength(contents);&lt;br /&gt;
         if(valid != 0)&lt;br /&gt;
         {&lt;br /&gt;
              string added = llGetInventoryName(INVENTORY_ALL, --n);&lt;br /&gt;
              integer index = llListFindList(content, [added]);&lt;br /&gt;
              if(!(~index))&lt;br /&gt;
              {&lt;br /&gt;
                   integer type = llGetInventoryType(added);&lt;br /&gt;
&lt;br /&gt;
                   if(type != 10 &amp;amp;&amp;amp; (string)type != &amp;quot;&amp;quot;) // don&#039;t add the object&#039;s script to the list of items!&lt;br /&gt;
                   {&lt;br /&gt;
		        content += added; // add the new item to the checklist of inventory items&lt;br /&gt;
                        // Do anything else you want related to the new item here&lt;br /&gt;
                   }&lt;br /&gt;
              }&lt;br /&gt;
         }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[llAllowInventoryDrop]]&lt;/div&gt;</description>
			<pubDate>Sat, 05 Feb 2011 21:43:39 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:WhoAddedWhat</comments>
		</item>
		<item>
			<title>SL Mail V1.2</title>
			<link>https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=1132583</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=1132583</guid>
			<description>&lt;p&gt;Flennan Roffo: /* Second Life mail client */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}} __NOTOC__&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=&#039;&#039;&#039;Second Life mail client&#039;&#039;&#039;=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Send and receive email from within Second Life from and to any address.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implemented with Address Book function (in a notecard named &#039;Address Book&#039;) to stores addresses by name  and to compile groups of named addresses. Current version is stand-alone (no server functionality) and uses chat commands only.&lt;br /&gt;
&lt;br /&gt;
[[Image:BannerSLMail.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.slmail.info slmail.info] &amp;lt;strike&amp;gt;(website coming soon!)&amp;lt;/strike&amp;gt; &amp;lt;b&amp;gt;url slmail.info no longer used for SL Mail, and was taken for some other purpose.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Release Notes V1.2=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 Release notes (edition 2, 4 sept 2007)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LICENCE INFO&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is released under GNU free software licence&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;PRODUCTION &amp;amp; MAINTANENCE&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
by Logic Scripted Products and Script Services&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.logicscripts.org logicscripts.org] (website coming soon!)&lt;br /&gt;
&lt;br /&gt;
SLurl:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Contact: [[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
&lt;br /&gt;
Email: [mailto:info@slmail.info &#039;&#039;&#039;info&#039;&#039;&#039;] or [mailto:Flennan.Roffo@slmail.info &#039;&#039;&#039;Flennan Roffo&#039;&#039;&#039;]&lt;br /&gt;
&#039;&#039;&#039;* The slmail.info URL appears to not be registered and this information appears to be out of date. *&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;DESCRIPTION&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is a simple tool to send and receive mail from within SL.&lt;br /&gt;
You can either compose a message yourself using chat recording, or choose a notecard from inventory to send. The Address Book functionality allows you to use short names for mail recipients stored in a notecard. The current version does not have a persisent mail address. Watch out for the upcoming next release (V1.3) which will facilitate persisent in-world mail addresses and will be enhanced with many new features (See: Requests For Change (RFC).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;COMMANDS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Help&#039;&#039;&#039;&lt;br /&gt;
||Show Help about available commands&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Record&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording (for owner only).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Stop&#039;&#039;&#039;&lt;br /&gt;
||Stops the chat recording without sending&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Continue&#039;&#039;&#039;&lt;br /&gt;
||Continues a previously stopped chat recording. Lines will be appended to you recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Show&#039;&#039;&#039;&lt;br /&gt;
||Shows the content of the recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send&#039;&#039;&#039;&lt;br /&gt;
||If recording, stops the recording, and sends the mail (need to supply mail address and subject first!)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send &amp;lt;notecard&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Sends the content of the notecard, instead of the chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Ignore&#039;&#039;&#039;&lt;br /&gt;
||Ignores your current chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject &amp;lt;subject&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the subject of the mail.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail subject.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Set the HOME address of the owner (mail will be forwarder to this address when offline).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home&#039;&#039;&#039;&lt;br /&gt;
||Show the HOME address.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Info&#039;&#039;&#039;&lt;br /&gt;
||Shows the mail address the object this script is running in uses (e.g. &amp;lt;object-key&amp;gt;@lsl.secondlife.com).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Read&#039;&#039;&#039;&lt;br /&gt;
||Reads the current message from the mail buffer (the mail buffer gets filled with mail you receive)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Select &amp;lt;msg&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Select a message number from the availabe messages in the mail buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Next&#039;&#039;&#039;&lt;br /&gt;
||Make next message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Prev&#039;&#039;&#039;&lt;br /&gt;
||Make previous message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@First&#039;&#039;&#039;&lt;br /&gt;
||Make the first message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Last&#039;&#039;&#039;&lt;br /&gt;
||Make the last message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Clear&#039;&#039;&#039;&lt;br /&gt;
||Clear the mail buffer&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Delete&#039;&#039;&#039;&lt;br /&gt;
||Deletes only the current message&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Reply&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording to reply to the current message. Mail adress and subject are filled in automatically.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* Commands are case insensitive (&amp;quot;@read&amp;quot; == &amp;quot;@READ&amp;quot;). Arguments might not be case insensitive.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;ADDRESS BOOK FORMAT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
A notecard of the name &#039;Address Book&#039; is read during initialization which may contain Address Book items and Groups.&lt;br /&gt;
The notecard is split in two sections, which need to be defined in that particular order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[ADDRESS BOOK]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Defines the section in which you can put names for mail addresses,  like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name1=account@thisdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name2=user@otherdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[GROUP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define groups of previously defined names under a new name, like for instance:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyGroup=Name1, Name2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note that names of groups and individual mail adresses share the same namespace and must be unique.&lt;br /&gt;
&lt;br /&gt;
So when you filled in your mail adresses in the Address Book, you can now use:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail Name1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to  &amp;lt;account@thisdomain.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail MyGroup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to &amp;lt;account@thisdomain.com&amp;gt; and &amp;lt;user@otherdomain.com&amp;gt;&lt;br /&gt;
Mails will be sent one after another.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* Names for Addreses and Groups are case insensitive (e.g. &amp;quot;mary&amp;quot;  == &amp;quot;MARY&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* The special address &#039;Self&#039; can be used in commands where otherwise an address specification can be used. &#039;Self&#039; is case insensitive (e.g. &amp;quot;self&amp;quot; == &amp;quot;SELF&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LIMITATIONS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
The current version is limited by the following:&lt;br /&gt;
&lt;br /&gt;
* Chat recording lines are limited by the 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Output of lines from the mail buffer are also limited by this 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Incoming mail is limited to a 1000 (1024?) byte limit&lt;br /&gt;
&lt;br /&gt;
* Outgoing mai is limited by a 4096 byte limit, which includes the standard mail header (region/location info on the first two lines)&lt;br /&gt;
&lt;br /&gt;
We are making adjustments to this release to help overcome these limitations. At least the line lenght limit can be overcome by introducing a line continuation character (for example a hyphen &#039;-&#039;) that when used at the end of a line appends the next line, so lines longer then 255 bytes are possible then.&lt;br /&gt;
&lt;br /&gt;
To overcome the outgoing mail length limit, the mail can be broken textualy into parts, and each part can be send seperatedely, with an indication in the subject or in an introduced primary line of the mail body to indicate that the mail was split into parts.&lt;br /&gt;
For incoming mail and at least to receive mail from other SL Mail programs, a protocol will be introduced to receive mail in parts that are joined together after receiving them to form a single mail.&lt;br /&gt;
&lt;br /&gt;
These enhancements will be made available in the next release (V1.3) of SL Mail &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;BUGS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Report any bugs you find in this release to Logic (IM: Flennan Roffo).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;REQUEST FOR CHANGE (RFC)&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Do you have additional wishes for enhancement of this product?&lt;br /&gt;
Contact Flennan Roffo and we will see if they can be implemented in the next release.&lt;br /&gt;
&lt;br /&gt;
Existing RFC&#039;s are:&lt;br /&gt;
&lt;br /&gt;
* Menu support for commands.&lt;br /&gt;
&lt;br /&gt;
* Lines on incoming/outgoing mail longer than 255 bytes.&lt;br /&gt;
&lt;br /&gt;
* Send messages longer than 4096 (minus SL mail header) bytes.&lt;br /&gt;
&lt;br /&gt;
* Receive messages longer than 1024 bytes.&lt;br /&gt;
&lt;br /&gt;
* Permanent mail addresses for the SL Mail client (like: &amp;lt;Flennan.Roffo@somedomain.sl&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Add your RFC!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In-world join the group &amp;quot;SL Mail&amp;quot; for bug reports, feature requests, the latest SL Mail release, and notices about development issues.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scripts=&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==Script: SL Mail v1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail core module which scans for incoming mail messages and executes commands used by the owner.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail V1.2.lsl&lt;br /&gt;
// (c) 2007 Logic Scripted Products and Script Services&lt;br /&gt;
// Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
// VERSION&lt;br /&gt;
// Version: 1.2&lt;br /&gt;
&lt;br /&gt;
// HISTORY&lt;br /&gt;
// Date         Version     Author              Comment&lt;br /&gt;
// --------------------------------------------------------------------------------------&lt;br /&gt;
// 28 aug 2007  V 1.0       Flennan Roffo       Created&lt;br /&gt;
//&lt;br /&gt;
//  1 sep 2007  V 1.1       Flennan Roffo       @Reply empties the recording buffer.&lt;br /&gt;
//                                                @Send while recording ends recording&lt;br /&gt;
//                                                and sends the mail if a mail address&lt;br /&gt;
//                                                and subject are supplied.&lt;br /&gt;
//                                                Fixed incorrect date in Unix2DateTime.&lt;br /&gt;
//  3 sep 2007  V 1.2       Flennan Roffo       Notification options:&lt;br /&gt;
//                                              - When online, send an IM when mail is received.&lt;br /&gt;
//                                              - When offline, send to HOME mail adress.&lt;br /&gt;
//                                              Adressbook&lt;br /&gt;
//                                              - Read adress book from config notecard.&lt;br /&gt;
&lt;br /&gt;
// LICENCE&lt;br /&gt;
// This program is free software; you can redistribute it and/or&lt;br /&gt;
// modify it under the terms of the GNU General Public License&lt;br /&gt;
// as published by the Free Software Foundation; either version 2&lt;br /&gt;
// of the License, or (at your option) any later version.&lt;br /&gt;
// &lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
// &lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program; if not, write to the Free Software&lt;br /&gt;
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
// (Also available at http://www.gnu.org/copyleft/gpl.html) &lt;br /&gt;
&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// Let&#039;s you record a message and sent to email and get messages and reply to messages.&lt;br /&gt;
// Must supply a valid mail adress and non-empty subject using chat commands.&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
// 1) Check for the maximum length of an email message (including newline and header).&lt;br /&gt;
// 2) Read adress book from notecard.                                    *DONE*&lt;br /&gt;
// 3) Send incoming mail to personal mail adress when offline.            *DONE*&lt;br /&gt;
// 4) Alert with an IM when online upon receiving new mail.                *DONE*&lt;br /&gt;
&lt;br /&gt;
string   SL_MAIL_VERSION = &amp;quot;V 1.2&amp;quot;;&lt;br /&gt;
string   SL_MAIL_DATE    = &amp;quot; 2 sep 2007&amp;quot;;&lt;br /&gt;
integer  ErrorFlag         = FALSE;&lt;br /&gt;
list     ScriptList        = [ &amp;quot;SL Mail Help V1.2&amp;quot;, &amp;quot;SL Mail AddressBook V1.2&amp;quot;, &lt;br /&gt;
                                &amp;quot;SL Mail OnlineStatus V1.2&amp;quot;, &amp;quot;SL Mail FetchNotecard V1.2&amp;quot; ];    &lt;br /&gt;
string   LSL_DOMAIN=&amp;quot;lsl.secondlife.com&amp;quot;; &lt;br /&gt;
integer  StatusOnline=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Commands&lt;br /&gt;
&lt;br /&gt;
string  COMMAND_RECORD     = &amp;quot;@RECORD&amp;quot;;&lt;br /&gt;
string  COMMAND_CONTINUE   = &amp;quot;@CONTINUE&amp;quot;;&lt;br /&gt;
string  COMMAND_STOP       = &amp;quot;@STOP&amp;quot;;&lt;br /&gt;
string  COMMAND_MAIL       = &amp;quot;@MAIL&amp;quot;;&lt;br /&gt;
string  COMMAND_SUBJECT    = &amp;quot;@SUBJECT&amp;quot;;&lt;br /&gt;
string  COMMAND_SEND       = &amp;quot;@SEND&amp;quot;;&lt;br /&gt;
string  COMMAND_SEE        = &amp;quot;@SEE&amp;quot;;&lt;br /&gt;
string  COMMAND_IGNORE     = &amp;quot;@IGNORE&amp;quot;;&lt;br /&gt;
string  COMMAND_READ       = &amp;quot;@READ&amp;quot;;&lt;br /&gt;
string  COMMAND_DELETE     = &amp;quot;@DELETE&amp;quot;;&lt;br /&gt;
string  COMMAND_CLEAR      = &amp;quot;@CLEAR&amp;quot;;&lt;br /&gt;
string  COMMAND_REPLY      = &amp;quot;@REPLY&amp;quot;;&lt;br /&gt;
string  COMMAND_NEXT       = &amp;quot;@NEXT&amp;quot;;&lt;br /&gt;
string  COMMAND_PREV       = &amp;quot;@PREV&amp;quot;;&lt;br /&gt;
string  COMMAND_FIRST      = &amp;quot;@FIRST&amp;quot;;&lt;br /&gt;
string  COMMAND_LAST       = &amp;quot;@LAST&amp;quot;;&lt;br /&gt;
string  COMMAND_LIST       = &amp;quot;@LIST&amp;quot;;&lt;br /&gt;
string  COMMAND_SELECT     = &amp;quot;@SELECT&amp;quot;;&lt;br /&gt;
string  COMMAND_HELP       = &amp;quot;@HELP&amp;quot;;&lt;br /&gt;
string  COMMAND_INFO       = &amp;quot;@INFO&amp;quot;;&lt;br /&gt;
string  COMMAND_RESET      = &amp;quot;@RESET&amp;quot;;&lt;br /&gt;
string  COMMAND_SHOW       = &amp;quot;@SHOW&amp;quot;;&lt;br /&gt;
string  COMMAND_ON         = &amp;quot;@ON&amp;quot;;&lt;br /&gt;
string  COMMAND_OFF        = &amp;quot;@OFF&amp;quot;;&lt;br /&gt;
string  COMMAND_HOME       = &amp;quot;@HOME&amp;quot;;&lt;br /&gt;
string  COMMAND_LOAD       = &amp;quot;@LOAD&amp;quot;;&lt;br /&gt;
string  COMMAND_ADDRESS    = &amp;quot;@ADDRESS&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Recording&lt;br /&gt;
&lt;br /&gt;
integer Recording = FALSE;&lt;br /&gt;
&lt;br /&gt;
list    ChatRecording=[];&lt;br /&gt;
integer NumLines=0;&lt;br /&gt;
integer Length=0;&lt;br /&gt;
&lt;br /&gt;
list     TimeList=[];&lt;br /&gt;
list     AddressList=[];&lt;br /&gt;
list     SubjectList=[];&lt;br /&gt;
list     BodyList=[];&lt;br /&gt;
integer  NumMessages=0;&lt;br /&gt;
integer  CurrentMessage=-1;&lt;br /&gt;
&lt;br /&gt;
float    MAIL_FETCH_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
// Link Messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP                        = 10000;&lt;br /&gt;
integer MSG_STATUS_ONLINE               = 30000;&lt;br /&gt;
integer MSG_STATUS_OFFLINE              = 30100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED          = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR           = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Unix Time conversion //////////////////&lt;br /&gt;
&lt;br /&gt;
integer DAYS_PER_YEAR        = 365;                // Non leap year&lt;br /&gt;
integer SECONDS_PER_YEAR     = 31536000;          // Non leap year&lt;br /&gt;
integer SECONDS_PER_DAY      = 86400;&lt;br /&gt;
integer SECONDS_PER_HOUR     = 3600;&lt;br /&gt;
integer SECONDS_PER_MINUTE   = 60;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// LeapYear() /////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer LeapYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (year % 4 == 0)&lt;br /&gt;
    {&lt;br /&gt;
        if (year % 100 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (year % 400 == 0)&lt;br /&gt;
            {&lt;br /&gt;
                return 1;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// DaysPerMonth() ///////////////////////////////////////&lt;br /&gt;
                &lt;br /&gt;
integer DaysPerMonth(integer year,integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;lt; 8)&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (month == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if (LeapYear(year))&lt;br /&gt;
                {&lt;br /&gt;
                    return 29;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    return 28;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 30;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 30;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////// DaysPerYear() ////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DaysPerYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (LeapYear(year))&lt;br /&gt;
        return DAYS_PER_YEAR + 1;&lt;br /&gt;
    else&lt;br /&gt;
        return DAYS_PER_YEAR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Unix2DataTime() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list Unix2DateTime(integer unixtime)&lt;br /&gt;
{&lt;br /&gt;
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;&lt;br /&gt;
    integer day = days_since_1_1_1970 + 1;&lt;br /&gt;
    integer year  = 1970;&lt;br /&gt;
    integer days_per_year = DaysPerYear(year);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_year)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_year;&lt;br /&gt;
        ++year;&lt;br /&gt;
        days_per_year = DaysPerYear(year);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer month = 1;&lt;br /&gt;
    integer days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_month)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_month;&lt;br /&gt;
        &lt;br /&gt;
        if (++month &amp;gt; 12)&lt;br /&gt;
        {    &lt;br /&gt;
            ++year;&lt;br /&gt;
            month = 1;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;&lt;br /&gt;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;&lt;br /&gt;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;&lt;br /&gt;
    integer minute      = second / SECONDS_PER_MINUTE;&lt;br /&gt;
    second               = second % SECONDS_PER_MINUTE;&lt;br /&gt;
    &lt;br /&gt;
    return [ year, month, day, hour, minute, second ];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// MonthName() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list MonthNameList = [     &amp;quot;JAN&amp;quot;, &amp;quot;FEB&amp;quot;, &amp;quot;MAR&amp;quot;, &amp;quot;APR&amp;quot;, &amp;quot;MAY&amp;quot;, &amp;quot;JUN&amp;quot;, &lt;br /&gt;
                        &amp;quot;JUL&amp;quot;, &amp;quot;AUG&amp;quot;, &amp;quot;SEP&amp;quot;, &amp;quot;OCT&amp;quot; , &amp;quot;NOV&amp;quot;, &amp;quot;DEC&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
string MonthName(integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;gt;= 0 &amp;amp;&amp;amp; month &amp;lt; 12)&lt;br /&gt;
        return llList2String(MonthNameList, month);&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// DateString() ///////////////////////////&lt;br /&gt;
&lt;br /&gt;
string DateString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer year       = llList2Integer(timelist,0);&lt;br /&gt;
    integer month      = llList2Integer(timelist,1);&lt;br /&gt;
    integer day        = llList2Integer(timelist,2);&lt;br /&gt;
    &lt;br /&gt;
    return (string)day + &amp;quot;-&amp;quot; + MonthName(month - 1) + &amp;quot;-&amp;quot; + (string)year;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// TimeString() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string TimeString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer hour          = llList2Integer(timelist,3);&lt;br /&gt;
    integer minute         = llList2Integer(timelist,4);&lt;br /&gt;
    integer second         = llList2Integer(timelist,5);&lt;br /&gt;
    string  hourstr     = (string)hour;&lt;br /&gt;
    string  minutestr   = (string)minute;&lt;br /&gt;
    string  secondstr   = (string)second;&lt;br /&gt;
    &lt;br /&gt;
    if (hour &amp;lt; 10)         hourstr     = &amp;quot;0&amp;quot; + hourstr;&lt;br /&gt;
    if (minute &amp;lt; 10)     minutestr     = &amp;quot;0&amp;quot; + minutestr;&lt;br /&gt;
    if (second &amp;lt; 10)    secondstr    = &amp;quot;0&amp;quot; + secondstr;&lt;br /&gt;
    return hourstr + &amp;quot;:&amp;quot; + minutestr + &amp;quot;:&amp;quot; + secondstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() /////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string body)&lt;br /&gt;
{&lt;br /&gt;
    // llOwnerSay(&amp;quot;Sending message to &#039;&amp;quot; + address + &amp;quot;&#039; with subject &#039;&amp;quot; + subject +&amp;quot;&#039;.&amp;quot;);&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND, body, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// SendHome() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendHome(string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SENDHOME, body, (key)subject);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Show() ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Show()&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;Current chat recording is:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; NumLines; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(ChatRecording,i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;Lines is &amp;quot; + (string)NumLines);&lt;br /&gt;
    llOwnerSay(&amp;quot;Message length is &amp;quot; + (string)Length);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Read() /////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Read()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;Reading message &amp;quot; + (string)CurrentMessage + &amp;quot; from mail buffer.&amp;quot;);&lt;br /&gt;
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);&lt;br /&gt;
    list timelist=Unix2DateTime(time);&lt;br /&gt;
    string Address = llList2String(AddressList,CurrentMessage);&lt;br /&gt;
    string Subject = llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
    string Body    = llList2String(BodyList,CurrentMessage);&lt;br /&gt;
    llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Address: &amp;quot; + Address);&lt;br /&gt;
    llOwnerSay(&amp;quot;Subject: &amp;quot; + Subject);&lt;br /&gt;
    llOwnerSay(&amp;quot;Begin of message body:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    list bodylist=llParseStringKeepNulls(Body, [ &amp;quot;\n&amp;quot; ], []);&lt;br /&gt;
    integer num=llGetListLength(bodylist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(bodylist,i));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;End of message body.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////// List ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
List()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;The mail buffer contains the following messages:\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; NumMessages; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer time=llList2Integer(TimeList,i);&lt;br /&gt;
        list timelist=Unix2DateTime(time);&lt;br /&gt;
        if (i &amp;gt; 0) llOwnerSay(&amp;quot;+-+-+-+-+-+-+-+-+-+-+-+-&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Message: &amp;quot; + (string)i);&lt;br /&gt;
        llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;From:    &amp;quot; + llList2String(AddressList,i));&lt;br /&gt;
        llOwnerSay(&amp;quot;Subject: &amp;quot; + llList2String(SubjectList,i));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////// NotifyNewMail() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
NotifyNewMail(string time, string address, string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    list timelist=Unix2DateTime((integer)time);&lt;br /&gt;
&lt;br /&gt;
    if (StatusOnline)&lt;br /&gt;
    {&lt;br /&gt;
        llInstantMessage(llGetOwner(), &amp;quot;You received a new mail message on &amp;quot; &lt;br /&gt;
                                    + DateString(timelist) + &amp;quot; at &amp;quot; + TimeString(timelist)&lt;br /&gt;
                                    + &amp;quot; from &amp;quot; + address &lt;br /&gt;
                                    + &amp;quot; with the subject &amp;quot; + subject);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        SendHome(&amp;quot;FW: &amp;quot; + subject, &amp;quot;Received at: &amp;quot; + DateString(timelist) + &amp;quot; &amp;quot; + TimeString(timelist) + &amp;quot;\nFrom: &amp;quot; +  address &lt;br /&gt;
                    + &amp;quot;\nBegin message body:\n-------------------\n&amp;quot; + body + &amp;quot;\n-------------------\nEnd message body.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ResetOtherScripts() //////////////////////&lt;br /&gt;
&lt;br /&gt;
ResetOtherScripts()&lt;br /&gt;
{&lt;br /&gt;
    string     name;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(ScriptList);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        name = llList2String(ScriptList,i);&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(name) == INVENTORY_SCRIPT)&lt;br /&gt;
        {&lt;br /&gt;
            llResetOtherScript(name);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Error - script &#039;&amp;quot; + name + &amp;quot;&#039; not found.&amp;quot;);&lt;br /&gt;
            ErrorFlag = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
// default &lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ////////////////////// state_entry() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Welcome to SL Mail, released under GNU software licence.&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Version &amp;quot; + SL_MAIL_VERSION + &amp;quot; &amp;quot; + SL_MAIL_DATE);&lt;br /&gt;
        llOwnerSay(&amp;quot;Produced by Logic Scripted Products &amp;amp; Product Services&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Free memory: &amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
        ResetOtherScripts();&lt;br /&gt;
        &lt;br /&gt;
        if (ErrorFlag)&lt;br /&gt;
            state Error;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// on_rez() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// changed() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_LOADED)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_ERROR)&lt;br /&gt;
        {&lt;br /&gt;
            state Error;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() //////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(MAIL_FETCH_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //////////////////////// on_rez() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// listen() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string trimmessage=llStringTrim(message,STRING_TRIM);&lt;br /&gt;
        list   parse = llParseStringKeepNulls(trimmessage, [ &amp;quot; &amp;quot;], []);&lt;br /&gt;
        string command = llToUpper(llList2String(parse,0));&lt;br /&gt;
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        integer nargs  = llGetListLength(parse);&lt;br /&gt;
        string argstr=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (nargs &amp;gt; 1) argstr=llGetSubString(message, llSubStringIndex(message, &amp;quot; &amp;quot;) + 1, -1);&lt;br /&gt;
            &lt;br /&gt;
        if (Recording)&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Recording stopped. Type @SHOW to see the message you have entered,&amp;quot;&lt;br /&gt;
                            + &amp;quot; or @SEND to send it.&amp;quot;);&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                &lt;br /&gt;
                SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];&lt;br /&gt;
                ++NumLines;&lt;br /&gt;
                Length += llStringLength(message) + 2;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_RECORD)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Start recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                ChatRecording = [];&lt;br /&gt;
                NumLines=0;&lt;br /&gt;
                Length=0;&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CONTINUE)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Continue recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_REPLY)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    string address=llList2String(AddressList,CurrentMessage);&lt;br /&gt;
                    string subject=&amp;quot;Re: &amp;quot; + llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, address, NULL_KEY);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, subject, NULL_KEY);&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines=0;&lt;br /&gt;
                    Length=0;&lt;br /&gt;
                    Recording = TRUE;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_MAIL)&lt;br /&gt;
            {&lt;br /&gt;
                string mailaddress=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailaddress != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, mailaddress, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETADDRESS, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SUBJECT)&lt;br /&gt;
            {&lt;br /&gt;
                string mailsubject=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailsubject != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, mailsubject, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETSUBJECT, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Not recording.&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    if (NumLines == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND_NOTECARD, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_IGNORE)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines = 0;&lt;br /&gt;
                    Length = 0;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Show();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_READ)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumMessages == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Read();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        ++CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        --CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_FIRST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = 0;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LAST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LIST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    List();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SELECT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;Need to supply a message number.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    integer msgnum = (integer)arg;&lt;br /&gt;
                     &lt;br /&gt;
                    if (msgnum &amp;lt; 0 || msgnum &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Message number &amp;quot; + arg + &amp;quot; not in mail buffer.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = msgnum;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_DELETE)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    --NumMessages;&lt;br /&gt;
                     &lt;br /&gt;
                    if (NumMessages == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = -1;&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (CurrentMessage &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CLEAR)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList=[];&lt;br /&gt;
                    AddressList=[];&lt;br /&gt;
                    SubjectList=[];&lt;br /&gt;
                    BodyList=[];&lt;br /&gt;
                    NumMessages=0;&lt;br /&gt;
                    CurrentMessage=-1;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_HELP, arg, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_INFO)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                Show();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_RESET)&lt;br /&gt;
            {&lt;br /&gt;
                llResetScript();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                state not_running;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HOME)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs==1)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETHOME, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETHOME, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// email() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    email(string time, string address, string subject, string body, integer queued)&lt;br /&gt;
    {&lt;br /&gt;
        NotifyNewMail(time, address, subject, body);&lt;br /&gt;
        TimeList = (TimeList=[]) + TimeList + [time];&lt;br /&gt;
        AddressList = (AddressList=[]) + AddressList + [address];&lt;br /&gt;
        SubjectList = (SubjectList=[]) + SubjectList + [subject];&lt;br /&gt;
        BodyList = (BodyList=[]) + BodyList + [body];&lt;br /&gt;
        ++NumMessages;&lt;br /&gt;
        &lt;br /&gt;
        if (CurrentMessage == -1)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = NumMessages - 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_REPLY)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state not_running&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state not_running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;SL Mailbox switched OFF. Say @ON to switch it back on.&amp;quot;);&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// on_rez() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// listen() ////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer chan, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string command=llToUpper(message);&lt;br /&gt;
        &lt;br /&gt;
        if (command == COMMAND_ON)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state Error&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state Error&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Error in SL Mail: not all component scripts found.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// End SL Mail V1.2.lsl&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Address Book V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Read and interpret the contents of the Address Book.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail AddressBook V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// &lt;br /&gt;
//  Read the Address Book from a notecard named &amp;quot;Address Book&amp;quot;.&lt;br /&gt;
//&lt;br /&gt;
//  The Address Book has the following format:&lt;br /&gt;
//  &lt;br /&gt;
//  [ADDRESS BOOK]&lt;br /&gt;
//  Name1=username@yourdomain.com&lt;br /&gt;
//  Name2=otheruser@otherdomain.com&lt;br /&gt;
//  ...&lt;br /&gt;
//  [GROUP]&lt;br /&gt;
//  group1=Name1, Name2&lt;br /&gt;
//  ...&lt;br /&gt;
//&lt;br /&gt;
//  Notes:&lt;br /&gt;
//  1. Group and Name share the same namespace, and must be unique.&lt;br /&gt;
//  2. It is allowed to have a name in the addressbook with multiple addresses, seperated by comma&#039;s.&lt;br /&gt;
// &lt;br /&gt;
/////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string  CurrentMailAddress = &amp;quot;&amp;quot;;&lt;br /&gt;
string  CurrentMailSubject = &amp;quot;&amp;quot;;&lt;br /&gt;
integer StatusOnline = FALSE;&lt;br /&gt;
&lt;br /&gt;
// Fetch or Send notecard&lt;br /&gt;
&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Names&lt;br /&gt;
&lt;br /&gt;
list    AddressBookList=[];&lt;br /&gt;
list    MailAddressList=[];&lt;br /&gt;
&lt;br /&gt;
string  STRING_HOME=&amp;quot;HOME&amp;quot;;&lt;br /&gt;
string  STRING_SELF=&amp;quot;SELF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Groups&lt;br /&gt;
&lt;br /&gt;
list   GroupList=[];&lt;br /&gt;
list   GroupNameList=[];&lt;br /&gt;
&lt;br /&gt;
string LSL_DOMAIN = &amp;quot;lsl.secondlife.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Read Address Book notecard&lt;br /&gt;
&lt;br /&gt;
string  ADDRESSBOOK_NOTECARD=&amp;quot;Address Book&amp;quot;;&lt;br /&gt;
integer Line=0;&lt;br /&gt;
key     reqAddressBook=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
integer Section=0;&lt;br /&gt;
integer SECTION_ADDRESS_BOOK=1;&lt;br /&gt;
integer SECTION_GROUP=2;&lt;br /&gt;
string  STRING_ADDRESS_BOOK=&amp;quot;ADDRESS BOOK&amp;quot;;&lt;br /&gt;
string  STRING_GROUP=&amp;quot;GROUP&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Links messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
integer MSG_MESSAGE_NOTIFY              = 90900;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED            = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR            = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// GetSelfAddress() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
string GetSelfAddress()&lt;br /&gt;
{&lt;br /&gt;
    return (string)llGetKey() + &amp;quot;@&amp;quot; + LSL_DOMAIN;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Info() /////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Info()&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;The mail address for this object is: &amp;quot; &lt;br /&gt;
                    + GetSelfAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// IsValidKeyFormat() //////////////////////&lt;br /&gt;
&lt;br /&gt;
integer IsValidKeyFormat(string str)&lt;br /&gt;
{&lt;br /&gt;
    string keychars = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    if (llStringLength(str) != 36)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    if( (llGetSubString( str, 8, 8 )   != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 13, 13 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 18, 18 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 23, 23 )  != &amp;quot;-&amp;quot; ) )&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 9; i &amp;lt; 13; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 14; i &amp;lt; 18; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 19; i &amp;lt; 23; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 24; i &amp;lt; 36; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// ValidMailAddress() ////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer ValidMailAddress(string arg)&lt;br /&gt;
{&lt;br /&gt;
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));&lt;br /&gt;
    &lt;br /&gt;
    if (adress == &amp;quot;&amp;quot;)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    list parse = llParseStringKeepNulls(adress, [ &amp;quot;@&amp;quot; ], []);&lt;br /&gt;
    string account = llList2String(parse,0);&lt;br /&gt;
    string domain  = llList2String(parse,1);&lt;br /&gt;
    &lt;br /&gt;
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    &lt;br /&gt;
    if (domain == LSL_DOMAIN)&lt;br /&gt;
    {&lt;br /&gt;
        return IsValidKeyFormat(account);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list parsedomain = llParseString2List(domain, [ &amp;quot;.&amp;quot; ], []);&lt;br /&gt;
    &lt;br /&gt;
        if (llGetListLength(parsedomain) &amp;lt; 2)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        &lt;br /&gt;
        integer num = llGetListLength(parsedomain);&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llStringLength(llList2String(parsedomain,i)) &amp;lt; 2)&lt;br /&gt;
            {&lt;br /&gt;
                return FALSE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetAddressStr() ///////////////////&lt;br /&gt;
&lt;br /&gt;
string GetAndCheckAddressStr(string address)&lt;br /&gt;
{&lt;br /&gt;
    list addresslist = llCSV2List(address);&lt;br /&gt;
    integer num=llGetListLength(addresslist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    string addressstr=&amp;quot;&amp;quot;;&lt;br /&gt;
    string curaddress=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        curaddress=llList2String(addresslist,i);&lt;br /&gt;
        &lt;br /&gt;
        if (ValidMailAddress(curaddress))&lt;br /&gt;
        {&lt;br /&gt;
            addressstr = (addressstr=&amp;quot;&amp;quot;) + addressstr + curaddress + &amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address string: &#039;&amp;quot; &lt;br /&gt;
                            + curaddress + &amp;quot;&#039;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return llGetSubString(addressstr, 0, -2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ProcessLine() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
ProcessLine(string rawline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(rawline,STRING_TRIM);&lt;br /&gt;
    string first=llGetSubString(line,0,0);&lt;br /&gt;
    string last=llGetSubString(line,-1,-1);&lt;br /&gt;
    &lt;br /&gt;
    // Ignore a blank line or comment line&lt;br /&gt;
    if (line == &amp;quot;&amp;quot; || first == &amp;quot;#&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // Check for the right section&lt;br /&gt;
    &lt;br /&gt;
    if (first == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; last == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        string sectionstr=llToUpper(llStringTrim(llGetSubString(line,1,-2),STRING_TRIM));&lt;br /&gt;
        &lt;br /&gt;
        if (sectionstr == STRING_ADDRESS_BOOK)&lt;br /&gt;
        {&lt;br /&gt;
            Section = SECTION_ADDRESS_BOOK;&lt;br /&gt;
        }&lt;br /&gt;
        else if (sectionstr == STRING_GROUP)&lt;br /&gt;
        {&lt;br /&gt;
            if (Section == 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                        + &amp;quot;. Group section defined before Address Book section.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Section = SECTION_GROUP;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid section header &#039;&amp;quot; + sectionstr &lt;br /&gt;
                        + &amp;quot;&#039; in &amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Must be in a section&lt;br /&gt;
    &lt;br /&gt;
    if (Section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;. No section header.&amp;quot;, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    list     parse=llParseString2List(line, [ &amp;quot;=&amp;quot; ], []);&lt;br /&gt;
    integer  num=llGetListLength(parse);&lt;br /&gt;
    &lt;br /&gt;
    // Format must be correct&lt;br /&gt;
    &lt;br /&gt;
    if (num != 2)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; +  (string)(Line+1) + &amp;quot;:\n&amp;quot; + rawline, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (Section == SECTION_ADDRESS_BOOK)&lt;br /&gt;
    {&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(name) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + name &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ name ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            string address=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
            string addressstr=GetAndCheckAddressStr(address);&lt;br /&gt;
            &lt;br /&gt;
            if (addressstr != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                AddressBookList     = (AddressBookList=[])     + AddressBookList     + [ name ];&lt;br /&gt;
                MailAddressList     = (MailAddressList=[])     + MailAddressList     + [ addressstr ];&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;No valid mail address for &#039;&amp;quot; + name &lt;br /&gt;
                    + &amp;quot;&#039;. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                    + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name &lt;br /&gt;
                + &amp;quot;&#039; already defined. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // Group&lt;br /&gt;
    {&lt;br /&gt;
        string group=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(group) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + group &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ group ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(GroupList, [ group ]) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                string names=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
                list   namelist=llCSV2List(names);&lt;br /&gt;
                integer num=llGetListLength(namelist);&lt;br /&gt;
                integer i;&lt;br /&gt;
                integer index;&lt;br /&gt;
                string  name;&lt;br /&gt;
                string  namestr=&amp;quot;&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
                for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                    name=llList2String(namelist,i);&lt;br /&gt;
                    index=llListFindList(AddressBookList, [ name ]);&lt;br /&gt;
            &lt;br /&gt;
                    if (index == -1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name + &amp;quot;&#039; defined in Group &#039;&amp;quot; &lt;br /&gt;
                                + group + &amp;quot;&#039; not found in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY); &lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        namestr = (namestr=&amp;quot;&amp;quot;) + namestr + name + &amp;quot;,&amp;quot;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (namestr != &amp;quot;&amp;quot;)&lt;br /&gt;
                {    &lt;br /&gt;
                    namestr=llGetSubString(namestr,0,-2);&lt;br /&gt;
                    GroupList         = (GroupList=[])         + GroupList     + [ group ];&lt;br /&gt;
                    GroupNameList     = (GroupNameList=[])    + GroupNameList + [ namestr ];&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                        + &amp;quot;&#039; has no valid names. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                        + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                    + &amp;quot;&#039; already defined in Group. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                    + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group&lt;br /&gt;
                + &amp;quot;&#039; already defined in Address Book. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// GetGroupAddressList ///////////////&lt;br /&gt;
&lt;br /&gt;
string GetGroupAddressList(string group)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(GroupList, [ group ]);&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(GroupList);&lt;br /&gt;
    string  grouplist=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        for (i = index; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2String(GroupList,i) == group)&lt;br /&gt;
            {&lt;br /&gt;
                grouplist = (grouplist=&amp;quot;&amp;quot;) + grouplist + llList2String(GroupNameList,i) + &amp;quot;,&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (grouplist != &amp;quot;&amp;quot;) grouplist=llGetSubString(grouplist,0,-2);   // remove last &amp;quot;,&amp;quot;&lt;br /&gt;
        return grouplist;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// SetMailAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetMailAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ address ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        index=llListFindList(GroupList, [ address ]);&lt;br /&gt;
        &lt;br /&gt;
        if (index == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llToUpper(address) == STRING_SELF)&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = GetSelfAddress();&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if(ValidMailAddress(address))&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = address;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Mail adress &amp;quot; + address &lt;br /&gt;
                            + &amp;quot; : not found in adress book or invalid format.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailAddress = GetGroupAddressList(address);&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        CurrentMailAddress = llList2String(MailAddressList,index);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                        + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string message)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No mail address defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No subject defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list mailaddresslist=llCSV2List(CurrentMailAddress);&lt;br /&gt;
        integer num=llGetListLength(mailaddresslist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(mailaddresslist,i);&lt;br /&gt;
            llEmail(address, CurrentMailSubject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMailHome() ////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMailHome(string message, string subject)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, STRING_HOME &lt;br /&gt;
                + &amp;quot; not set. Set your home adress with @HOME &amp;lt;address&amp;gt;.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        string homeaddress=llList2String(AddressBookList,index);&lt;br /&gt;
        list   homelist=llCSV2List(homeaddress);&lt;br /&gt;
        integer num=llGetListLength(homelist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(homelist,i);&lt;br /&gt;
            llEmail(address, subject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
string GetHomeAddress()&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;not set&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2String(MailAddressList,index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetHomeAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        AddressBookList     = (AddressBookList=[]) + [ STRING_HOME ] + AddressBookList;&lt;br /&gt;
        MailAddressList     = (MailAddressList=[]) + [ GetAndCheckAddressStr(address) ]  + MailAddressList;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MailAddressList = llListReplaceList(MailAddressList, [ GetAndCheckAddressStr(address) ], index, index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        Line=0;&lt;br /&gt;
        Section=0;&lt;br /&gt;
        llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// dataserver() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqAddressBook)&lt;br /&gt;
        {&lt;br /&gt;
            reqAddressBook = NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                ProcessLine(data);&lt;br /&gt;
                reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Address Book loaded.&amp;quot;, NULL_KEY);&lt;br /&gt;
                state running;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// timer() ///////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_ERROR, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Could not read Address Book: &amp;quot; &lt;br /&gt;
                            + ADDRESSBOOK_NOTECARD + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// link_message() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_MESSAGE_GETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is empty.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailSubject = message;&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is empty.&amp;quot;, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            SetMailAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Body of message to send is empty. &amp;quot; &lt;br /&gt;
                                +  &amp;quot;No mail is send.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SENDHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SendMailHome(message, (string)id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetInventoryType(message) == INVENTORY_NOTECARD)&lt;br /&gt;
            {&lt;br /&gt;
                Notecard2Fetch = message;                &lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_READ, message, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + message + &amp;quot; not found.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_NOTECARD_FETCHED)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + Notecard2Fetch &lt;br /&gt;
                            + &amp;quot; was empty or could not be read.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Home address is: &amp;quot; + GetHomeAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SetHomeAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_INFO)&lt;br /&gt;
        {&lt;br /&gt;
            Info();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
// End SL Mail AddressBook V1.2.lsl&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail FetchNotecard V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch the contents of a notecard and return it via link message as a string.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Notecard&lt;br /&gt;
&lt;br /&gt;
integer Line=0;&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
key     reqNotecard=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=10.0;&lt;br /&gt;
integer Fetched=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Lines&lt;br /&gt;
&lt;br /&gt;
list LineList=[];&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    /////////////////////// dataserver() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqNotecard)&lt;br /&gt;
        {&lt;br /&gt;
            reqNotecard=NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                LineList = (LineList=[]) + LineList + [ data ];&lt;br /&gt;
                reqNotecard = llGetNotecardLine(Notecard2Fetch, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Fetched=TRUE;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, llDumpList2String(LineList, &amp;quot;\n&amp;quot;), NULL_KEY);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /////////////////////// timer() ///////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        if (!Fetched)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            llSetTimerEvent(0.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer send, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_NOTECARD_READ)&lt;br /&gt;
        {&lt;br /&gt;
            Line=0;&lt;br /&gt;
            Notecard2Fetch=message;&lt;br /&gt;
            LineList=[];&lt;br /&gt;
            Fetched=FALSE;&lt;br /&gt;
            reqNotecard=llGetNotecardLine(Notecard2Fetch, Line);&lt;br /&gt;
            llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL OnlineStatus V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch online status of owner.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Online status&lt;br /&gt;
&lt;br /&gt;
key     reqOnlineStatus=NULL_KEY;&lt;br /&gt;
float   STATUS_INTERVAL=2.0;&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_STATUS_ONLINE       = 30000;&lt;br /&gt;
integer MS_STATUS_OFFLINE       = 30100;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus=llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
        llSetTimerEvent(STATUS_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// dataserver() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqOnlineStatus)&lt;br /&gt;
        {&lt;br /&gt;
            reqOnlineStatus = NULL_KEY;&lt;br /&gt;
        &lt;br /&gt;
            if (data==&amp;quot;1&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_STATUS_ONLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if (data==&amp;quot;0&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MS_STATUS_OFFLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus = llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Help V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Display help information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail Help V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP    = 10000;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Help() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Help()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;HELP for SL Mail V1.2.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;COMMANDS:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HELP               - displays help info.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@INFO               - display mailaddress of this object.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RECORD             - start recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CONTINUE           - continue recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@STOP               - stop recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@IGNORE             - ignore the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SHOW               - show what your recorded.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SEND               - send the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@MAIL &amp;lt;mailadress&amp;gt;  - set the mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SUBJECT subject    - set the mail subject.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LIST               - list messages in mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SELECT &amp;lt;message&amp;gt;   - select message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@READ               - read current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@NEXT               - read next message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@PREV               - read previous message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@FIRST              - read first message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LAST               - read last message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@DELETE             - delete current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CLEAR              - clear the mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@REPLY              - reply to current message.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RESET              - reset the script.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HOME               - set the home mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@OFF                - switch mailbox OFF.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@ON                 - switch mailbox ON.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_HELP)&lt;br /&gt;
        {&lt;br /&gt;
            Help();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail Help V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}&lt;/div&gt;</description>
			<pubDate>Tue, 25 Jan 2011 23:56:47 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:SL_Mail_V1.2</comments>
		</item>
		<item>
			<title>SL Mail V1.2</title>
			<link>https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=1132582</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=1132582</guid>
			<description>&lt;p&gt;Flennan Roffo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}} __NOTOC__&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=&#039;&#039;&#039;Second Life mail client&#039;&#039;&#039;=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Send and receive email from within Second Life from and to any address.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implemented with Address Book function (in a notecard named &#039;Address Book&#039;) to stores addresses by name  and to compile groups of named addresses. Current version is stand-alone (no server functionality) and uses chat commands only.&lt;br /&gt;
&lt;br /&gt;
[[Image:BannerSLMail.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.slmail.info slmail.info] &amp;lt;strike&amp;gt;(website coming soon!)&amp;lt;/strike&amp;gt; &amp;lt;bold&amp;gt;url slmail.info no longer used for SL Mail, and was taken for some other purpose.&amp;lt;/bold&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Release Notes V1.2=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 Release notes (edition 2, 4 sept 2007)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LICENCE INFO&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is released under GNU free software licence&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;PRODUCTION &amp;amp; MAINTANENCE&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
by Logic Scripted Products and Script Services&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.logicscripts.org logicscripts.org] (website coming soon!)&lt;br /&gt;
&lt;br /&gt;
SLurl:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Contact: [[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
&lt;br /&gt;
Email: [mailto:info@slmail.info &#039;&#039;&#039;info&#039;&#039;&#039;] or [mailto:Flennan.Roffo@slmail.info &#039;&#039;&#039;Flennan Roffo&#039;&#039;&#039;]&lt;br /&gt;
&#039;&#039;&#039;* The slmail.info URL appears to not be registered and this information appears to be out of date. *&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;DESCRIPTION&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is a simple tool to send and receive mail from within SL.&lt;br /&gt;
You can either compose a message yourself using chat recording, or choose a notecard from inventory to send. The Address Book functionality allows you to use short names for mail recipients stored in a notecard. The current version does not have a persisent mail address. Watch out for the upcoming next release (V1.3) which will facilitate persisent in-world mail addresses and will be enhanced with many new features (See: Requests For Change (RFC).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;COMMANDS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Help&#039;&#039;&#039;&lt;br /&gt;
||Show Help about available commands&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Record&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording (for owner only).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Stop&#039;&#039;&#039;&lt;br /&gt;
||Stops the chat recording without sending&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Continue&#039;&#039;&#039;&lt;br /&gt;
||Continues a previously stopped chat recording. Lines will be appended to you recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Show&#039;&#039;&#039;&lt;br /&gt;
||Shows the content of the recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send&#039;&#039;&#039;&lt;br /&gt;
||If recording, stops the recording, and sends the mail (need to supply mail address and subject first!)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send &amp;lt;notecard&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Sends the content of the notecard, instead of the chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Ignore&#039;&#039;&#039;&lt;br /&gt;
||Ignores your current chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject &amp;lt;subject&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the subject of the mail.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail subject.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Set the HOME address of the owner (mail will be forwarder to this address when offline).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home&#039;&#039;&#039;&lt;br /&gt;
||Show the HOME address.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Info&#039;&#039;&#039;&lt;br /&gt;
||Shows the mail address the object this script is running in uses (e.g. &amp;lt;object-key&amp;gt;@lsl.secondlife.com).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Read&#039;&#039;&#039;&lt;br /&gt;
||Reads the current message from the mail buffer (the mail buffer gets filled with mail you receive)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Select &amp;lt;msg&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Select a message number from the availabe messages in the mail buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Next&#039;&#039;&#039;&lt;br /&gt;
||Make next message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Prev&#039;&#039;&#039;&lt;br /&gt;
||Make previous message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@First&#039;&#039;&#039;&lt;br /&gt;
||Make the first message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Last&#039;&#039;&#039;&lt;br /&gt;
||Make the last message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Clear&#039;&#039;&#039;&lt;br /&gt;
||Clear the mail buffer&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Delete&#039;&#039;&#039;&lt;br /&gt;
||Deletes only the current message&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Reply&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording to reply to the current message. Mail adress and subject are filled in automatically.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* Commands are case insensitive (&amp;quot;@read&amp;quot; == &amp;quot;@READ&amp;quot;). Arguments might not be case insensitive.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;ADDRESS BOOK FORMAT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
A notecard of the name &#039;Address Book&#039; is read during initialization which may contain Address Book items and Groups.&lt;br /&gt;
The notecard is split in two sections, which need to be defined in that particular order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[ADDRESS BOOK]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Defines the section in which you can put names for mail addresses,  like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name1=account@thisdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name2=user@otherdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[GROUP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define groups of previously defined names under a new name, like for instance:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyGroup=Name1, Name2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note that names of groups and individual mail adresses share the same namespace and must be unique.&lt;br /&gt;
&lt;br /&gt;
So when you filled in your mail adresses in the Address Book, you can now use:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail Name1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to  &amp;lt;account@thisdomain.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail MyGroup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to &amp;lt;account@thisdomain.com&amp;gt; and &amp;lt;user@otherdomain.com&amp;gt;&lt;br /&gt;
Mails will be sent one after another.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* Names for Addreses and Groups are case insensitive (e.g. &amp;quot;mary&amp;quot;  == &amp;quot;MARY&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* The special address &#039;Self&#039; can be used in commands where otherwise an address specification can be used. &#039;Self&#039; is case insensitive (e.g. &amp;quot;self&amp;quot; == &amp;quot;SELF&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LIMITATIONS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
The current version is limited by the following:&lt;br /&gt;
&lt;br /&gt;
* Chat recording lines are limited by the 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Output of lines from the mail buffer are also limited by this 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Incoming mail is limited to a 1000 (1024?) byte limit&lt;br /&gt;
&lt;br /&gt;
* Outgoing mai is limited by a 4096 byte limit, which includes the standard mail header (region/location info on the first two lines)&lt;br /&gt;
&lt;br /&gt;
We are making adjustments to this release to help overcome these limitations. At least the line lenght limit can be overcome by introducing a line continuation character (for example a hyphen &#039;-&#039;) that when used at the end of a line appends the next line, so lines longer then 255 bytes are possible then.&lt;br /&gt;
&lt;br /&gt;
To overcome the outgoing mail length limit, the mail can be broken textualy into parts, and each part can be send seperatedely, with an indication in the subject or in an introduced primary line of the mail body to indicate that the mail was split into parts.&lt;br /&gt;
For incoming mail and at least to receive mail from other SL Mail programs, a protocol will be introduced to receive mail in parts that are joined together after receiving them to form a single mail.&lt;br /&gt;
&lt;br /&gt;
These enhancements will be made available in the next release (V1.3) of SL Mail &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;BUGS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Report any bugs you find in this release to Logic (IM: Flennan Roffo).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;REQUEST FOR CHANGE (RFC)&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Do you have additional wishes for enhancement of this product?&lt;br /&gt;
Contact Flennan Roffo and we will see if they can be implemented in the next release.&lt;br /&gt;
&lt;br /&gt;
Existing RFC&#039;s are:&lt;br /&gt;
&lt;br /&gt;
* Menu support for commands.&lt;br /&gt;
&lt;br /&gt;
* Lines on incoming/outgoing mail longer than 255 bytes.&lt;br /&gt;
&lt;br /&gt;
* Send messages longer than 4096 (minus SL mail header) bytes.&lt;br /&gt;
&lt;br /&gt;
* Receive messages longer than 1024 bytes.&lt;br /&gt;
&lt;br /&gt;
* Permanent mail addresses for the SL Mail client (like: &amp;lt;Flennan.Roffo@somedomain.sl&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Add your RFC!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In-world join the group &amp;quot;SL Mail&amp;quot; for bug reports, feature requests, the latest SL Mail release, and notices about development issues.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scripts=&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==Script: SL Mail v1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail core module which scans for incoming mail messages and executes commands used by the owner.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail V1.2.lsl&lt;br /&gt;
// (c) 2007 Logic Scripted Products and Script Services&lt;br /&gt;
// Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
// VERSION&lt;br /&gt;
// Version: 1.2&lt;br /&gt;
&lt;br /&gt;
// HISTORY&lt;br /&gt;
// Date         Version     Author              Comment&lt;br /&gt;
// --------------------------------------------------------------------------------------&lt;br /&gt;
// 28 aug 2007  V 1.0       Flennan Roffo       Created&lt;br /&gt;
//&lt;br /&gt;
//  1 sep 2007  V 1.1       Flennan Roffo       @Reply empties the recording buffer.&lt;br /&gt;
//                                                @Send while recording ends recording&lt;br /&gt;
//                                                and sends the mail if a mail address&lt;br /&gt;
//                                                and subject are supplied.&lt;br /&gt;
//                                                Fixed incorrect date in Unix2DateTime.&lt;br /&gt;
//  3 sep 2007  V 1.2       Flennan Roffo       Notification options:&lt;br /&gt;
//                                              - When online, send an IM when mail is received.&lt;br /&gt;
//                                              - When offline, send to HOME mail adress.&lt;br /&gt;
//                                              Adressbook&lt;br /&gt;
//                                              - Read adress book from config notecard.&lt;br /&gt;
&lt;br /&gt;
// LICENCE&lt;br /&gt;
// This program is free software; you can redistribute it and/or&lt;br /&gt;
// modify it under the terms of the GNU General Public License&lt;br /&gt;
// as published by the Free Software Foundation; either version 2&lt;br /&gt;
// of the License, or (at your option) any later version.&lt;br /&gt;
// &lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
// &lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program; if not, write to the Free Software&lt;br /&gt;
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
// (Also available at http://www.gnu.org/copyleft/gpl.html) &lt;br /&gt;
&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// Let&#039;s you record a message and sent to email and get messages and reply to messages.&lt;br /&gt;
// Must supply a valid mail adress and non-empty subject using chat commands.&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
// 1) Check for the maximum length of an email message (including newline and header).&lt;br /&gt;
// 2) Read adress book from notecard.                                    *DONE*&lt;br /&gt;
// 3) Send incoming mail to personal mail adress when offline.            *DONE*&lt;br /&gt;
// 4) Alert with an IM when online upon receiving new mail.                *DONE*&lt;br /&gt;
&lt;br /&gt;
string   SL_MAIL_VERSION = &amp;quot;V 1.2&amp;quot;;&lt;br /&gt;
string   SL_MAIL_DATE    = &amp;quot; 2 sep 2007&amp;quot;;&lt;br /&gt;
integer  ErrorFlag         = FALSE;&lt;br /&gt;
list     ScriptList        = [ &amp;quot;SL Mail Help V1.2&amp;quot;, &amp;quot;SL Mail AddressBook V1.2&amp;quot;, &lt;br /&gt;
                                &amp;quot;SL Mail OnlineStatus V1.2&amp;quot;, &amp;quot;SL Mail FetchNotecard V1.2&amp;quot; ];    &lt;br /&gt;
string   LSL_DOMAIN=&amp;quot;lsl.secondlife.com&amp;quot;; &lt;br /&gt;
integer  StatusOnline=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Commands&lt;br /&gt;
&lt;br /&gt;
string  COMMAND_RECORD     = &amp;quot;@RECORD&amp;quot;;&lt;br /&gt;
string  COMMAND_CONTINUE   = &amp;quot;@CONTINUE&amp;quot;;&lt;br /&gt;
string  COMMAND_STOP       = &amp;quot;@STOP&amp;quot;;&lt;br /&gt;
string  COMMAND_MAIL       = &amp;quot;@MAIL&amp;quot;;&lt;br /&gt;
string  COMMAND_SUBJECT    = &amp;quot;@SUBJECT&amp;quot;;&lt;br /&gt;
string  COMMAND_SEND       = &amp;quot;@SEND&amp;quot;;&lt;br /&gt;
string  COMMAND_SEE        = &amp;quot;@SEE&amp;quot;;&lt;br /&gt;
string  COMMAND_IGNORE     = &amp;quot;@IGNORE&amp;quot;;&lt;br /&gt;
string  COMMAND_READ       = &amp;quot;@READ&amp;quot;;&lt;br /&gt;
string  COMMAND_DELETE     = &amp;quot;@DELETE&amp;quot;;&lt;br /&gt;
string  COMMAND_CLEAR      = &amp;quot;@CLEAR&amp;quot;;&lt;br /&gt;
string  COMMAND_REPLY      = &amp;quot;@REPLY&amp;quot;;&lt;br /&gt;
string  COMMAND_NEXT       = &amp;quot;@NEXT&amp;quot;;&lt;br /&gt;
string  COMMAND_PREV       = &amp;quot;@PREV&amp;quot;;&lt;br /&gt;
string  COMMAND_FIRST      = &amp;quot;@FIRST&amp;quot;;&lt;br /&gt;
string  COMMAND_LAST       = &amp;quot;@LAST&amp;quot;;&lt;br /&gt;
string  COMMAND_LIST       = &amp;quot;@LIST&amp;quot;;&lt;br /&gt;
string  COMMAND_SELECT     = &amp;quot;@SELECT&amp;quot;;&lt;br /&gt;
string  COMMAND_HELP       = &amp;quot;@HELP&amp;quot;;&lt;br /&gt;
string  COMMAND_INFO       = &amp;quot;@INFO&amp;quot;;&lt;br /&gt;
string  COMMAND_RESET      = &amp;quot;@RESET&amp;quot;;&lt;br /&gt;
string  COMMAND_SHOW       = &amp;quot;@SHOW&amp;quot;;&lt;br /&gt;
string  COMMAND_ON         = &amp;quot;@ON&amp;quot;;&lt;br /&gt;
string  COMMAND_OFF        = &amp;quot;@OFF&amp;quot;;&lt;br /&gt;
string  COMMAND_HOME       = &amp;quot;@HOME&amp;quot;;&lt;br /&gt;
string  COMMAND_LOAD       = &amp;quot;@LOAD&amp;quot;;&lt;br /&gt;
string  COMMAND_ADDRESS    = &amp;quot;@ADDRESS&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Recording&lt;br /&gt;
&lt;br /&gt;
integer Recording = FALSE;&lt;br /&gt;
&lt;br /&gt;
list    ChatRecording=[];&lt;br /&gt;
integer NumLines=0;&lt;br /&gt;
integer Length=0;&lt;br /&gt;
&lt;br /&gt;
list     TimeList=[];&lt;br /&gt;
list     AddressList=[];&lt;br /&gt;
list     SubjectList=[];&lt;br /&gt;
list     BodyList=[];&lt;br /&gt;
integer  NumMessages=0;&lt;br /&gt;
integer  CurrentMessage=-1;&lt;br /&gt;
&lt;br /&gt;
float    MAIL_FETCH_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
// Link Messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP                        = 10000;&lt;br /&gt;
integer MSG_STATUS_ONLINE               = 30000;&lt;br /&gt;
integer MSG_STATUS_OFFLINE              = 30100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED          = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR           = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Unix Time conversion //////////////////&lt;br /&gt;
&lt;br /&gt;
integer DAYS_PER_YEAR        = 365;                // Non leap year&lt;br /&gt;
integer SECONDS_PER_YEAR     = 31536000;          // Non leap year&lt;br /&gt;
integer SECONDS_PER_DAY      = 86400;&lt;br /&gt;
integer SECONDS_PER_HOUR     = 3600;&lt;br /&gt;
integer SECONDS_PER_MINUTE   = 60;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// LeapYear() /////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer LeapYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (year % 4 == 0)&lt;br /&gt;
    {&lt;br /&gt;
        if (year % 100 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (year % 400 == 0)&lt;br /&gt;
            {&lt;br /&gt;
                return 1;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// DaysPerMonth() ///////////////////////////////////////&lt;br /&gt;
                &lt;br /&gt;
integer DaysPerMonth(integer year,integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;lt; 8)&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (month == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if (LeapYear(year))&lt;br /&gt;
                {&lt;br /&gt;
                    return 29;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    return 28;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 30;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 30;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////// DaysPerYear() ////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DaysPerYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (LeapYear(year))&lt;br /&gt;
        return DAYS_PER_YEAR + 1;&lt;br /&gt;
    else&lt;br /&gt;
        return DAYS_PER_YEAR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Unix2DataTime() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list Unix2DateTime(integer unixtime)&lt;br /&gt;
{&lt;br /&gt;
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;&lt;br /&gt;
    integer day = days_since_1_1_1970 + 1;&lt;br /&gt;
    integer year  = 1970;&lt;br /&gt;
    integer days_per_year = DaysPerYear(year);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_year)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_year;&lt;br /&gt;
        ++year;&lt;br /&gt;
        days_per_year = DaysPerYear(year);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer month = 1;&lt;br /&gt;
    integer days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_month)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_month;&lt;br /&gt;
        &lt;br /&gt;
        if (++month &amp;gt; 12)&lt;br /&gt;
        {    &lt;br /&gt;
            ++year;&lt;br /&gt;
            month = 1;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;&lt;br /&gt;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;&lt;br /&gt;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;&lt;br /&gt;
    integer minute      = second / SECONDS_PER_MINUTE;&lt;br /&gt;
    second               = second % SECONDS_PER_MINUTE;&lt;br /&gt;
    &lt;br /&gt;
    return [ year, month, day, hour, minute, second ];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// MonthName() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list MonthNameList = [     &amp;quot;JAN&amp;quot;, &amp;quot;FEB&amp;quot;, &amp;quot;MAR&amp;quot;, &amp;quot;APR&amp;quot;, &amp;quot;MAY&amp;quot;, &amp;quot;JUN&amp;quot;, &lt;br /&gt;
                        &amp;quot;JUL&amp;quot;, &amp;quot;AUG&amp;quot;, &amp;quot;SEP&amp;quot;, &amp;quot;OCT&amp;quot; , &amp;quot;NOV&amp;quot;, &amp;quot;DEC&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
string MonthName(integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;gt;= 0 &amp;amp;&amp;amp; month &amp;lt; 12)&lt;br /&gt;
        return llList2String(MonthNameList, month);&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// DateString() ///////////////////////////&lt;br /&gt;
&lt;br /&gt;
string DateString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer year       = llList2Integer(timelist,0);&lt;br /&gt;
    integer month      = llList2Integer(timelist,1);&lt;br /&gt;
    integer day        = llList2Integer(timelist,2);&lt;br /&gt;
    &lt;br /&gt;
    return (string)day + &amp;quot;-&amp;quot; + MonthName(month - 1) + &amp;quot;-&amp;quot; + (string)year;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// TimeString() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string TimeString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer hour          = llList2Integer(timelist,3);&lt;br /&gt;
    integer minute         = llList2Integer(timelist,4);&lt;br /&gt;
    integer second         = llList2Integer(timelist,5);&lt;br /&gt;
    string  hourstr     = (string)hour;&lt;br /&gt;
    string  minutestr   = (string)minute;&lt;br /&gt;
    string  secondstr   = (string)second;&lt;br /&gt;
    &lt;br /&gt;
    if (hour &amp;lt; 10)         hourstr     = &amp;quot;0&amp;quot; + hourstr;&lt;br /&gt;
    if (minute &amp;lt; 10)     minutestr     = &amp;quot;0&amp;quot; + minutestr;&lt;br /&gt;
    if (second &amp;lt; 10)    secondstr    = &amp;quot;0&amp;quot; + secondstr;&lt;br /&gt;
    return hourstr + &amp;quot;:&amp;quot; + minutestr + &amp;quot;:&amp;quot; + secondstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() /////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string body)&lt;br /&gt;
{&lt;br /&gt;
    // llOwnerSay(&amp;quot;Sending message to &#039;&amp;quot; + address + &amp;quot;&#039; with subject &#039;&amp;quot; + subject +&amp;quot;&#039;.&amp;quot;);&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND, body, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// SendHome() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendHome(string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SENDHOME, body, (key)subject);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Show() ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Show()&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;Current chat recording is:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; NumLines; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(ChatRecording,i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;Lines is &amp;quot; + (string)NumLines);&lt;br /&gt;
    llOwnerSay(&amp;quot;Message length is &amp;quot; + (string)Length);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Read() /////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Read()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;Reading message &amp;quot; + (string)CurrentMessage + &amp;quot; from mail buffer.&amp;quot;);&lt;br /&gt;
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);&lt;br /&gt;
    list timelist=Unix2DateTime(time);&lt;br /&gt;
    string Address = llList2String(AddressList,CurrentMessage);&lt;br /&gt;
    string Subject = llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
    string Body    = llList2String(BodyList,CurrentMessage);&lt;br /&gt;
    llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Address: &amp;quot; + Address);&lt;br /&gt;
    llOwnerSay(&amp;quot;Subject: &amp;quot; + Subject);&lt;br /&gt;
    llOwnerSay(&amp;quot;Begin of message body:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    list bodylist=llParseStringKeepNulls(Body, [ &amp;quot;\n&amp;quot; ], []);&lt;br /&gt;
    integer num=llGetListLength(bodylist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(bodylist,i));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;End of message body.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////// List ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
List()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;The mail buffer contains the following messages:\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; NumMessages; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer time=llList2Integer(TimeList,i);&lt;br /&gt;
        list timelist=Unix2DateTime(time);&lt;br /&gt;
        if (i &amp;gt; 0) llOwnerSay(&amp;quot;+-+-+-+-+-+-+-+-+-+-+-+-&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Message: &amp;quot; + (string)i);&lt;br /&gt;
        llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;From:    &amp;quot; + llList2String(AddressList,i));&lt;br /&gt;
        llOwnerSay(&amp;quot;Subject: &amp;quot; + llList2String(SubjectList,i));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////// NotifyNewMail() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
NotifyNewMail(string time, string address, string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    list timelist=Unix2DateTime((integer)time);&lt;br /&gt;
&lt;br /&gt;
    if (StatusOnline)&lt;br /&gt;
    {&lt;br /&gt;
        llInstantMessage(llGetOwner(), &amp;quot;You received a new mail message on &amp;quot; &lt;br /&gt;
                                    + DateString(timelist) + &amp;quot; at &amp;quot; + TimeString(timelist)&lt;br /&gt;
                                    + &amp;quot; from &amp;quot; + address &lt;br /&gt;
                                    + &amp;quot; with the subject &amp;quot; + subject);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        SendHome(&amp;quot;FW: &amp;quot; + subject, &amp;quot;Received at: &amp;quot; + DateString(timelist) + &amp;quot; &amp;quot; + TimeString(timelist) + &amp;quot;\nFrom: &amp;quot; +  address &lt;br /&gt;
                    + &amp;quot;\nBegin message body:\n-------------------\n&amp;quot; + body + &amp;quot;\n-------------------\nEnd message body.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ResetOtherScripts() //////////////////////&lt;br /&gt;
&lt;br /&gt;
ResetOtherScripts()&lt;br /&gt;
{&lt;br /&gt;
    string     name;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(ScriptList);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        name = llList2String(ScriptList,i);&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(name) == INVENTORY_SCRIPT)&lt;br /&gt;
        {&lt;br /&gt;
            llResetOtherScript(name);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Error - script &#039;&amp;quot; + name + &amp;quot;&#039; not found.&amp;quot;);&lt;br /&gt;
            ErrorFlag = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
// default &lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ////////////////////// state_entry() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Welcome to SL Mail, released under GNU software licence.&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Version &amp;quot; + SL_MAIL_VERSION + &amp;quot; &amp;quot; + SL_MAIL_DATE);&lt;br /&gt;
        llOwnerSay(&amp;quot;Produced by Logic Scripted Products &amp;amp; Product Services&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Free memory: &amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
        ResetOtherScripts();&lt;br /&gt;
        &lt;br /&gt;
        if (ErrorFlag)&lt;br /&gt;
            state Error;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// on_rez() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// changed() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_LOADED)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_ERROR)&lt;br /&gt;
        {&lt;br /&gt;
            state Error;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() //////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(MAIL_FETCH_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //////////////////////// on_rez() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// listen() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string trimmessage=llStringTrim(message,STRING_TRIM);&lt;br /&gt;
        list   parse = llParseStringKeepNulls(trimmessage, [ &amp;quot; &amp;quot;], []);&lt;br /&gt;
        string command = llToUpper(llList2String(parse,0));&lt;br /&gt;
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        integer nargs  = llGetListLength(parse);&lt;br /&gt;
        string argstr=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (nargs &amp;gt; 1) argstr=llGetSubString(message, llSubStringIndex(message, &amp;quot; &amp;quot;) + 1, -1);&lt;br /&gt;
            &lt;br /&gt;
        if (Recording)&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Recording stopped. Type @SHOW to see the message you have entered,&amp;quot;&lt;br /&gt;
                            + &amp;quot; or @SEND to send it.&amp;quot;);&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                &lt;br /&gt;
                SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];&lt;br /&gt;
                ++NumLines;&lt;br /&gt;
                Length += llStringLength(message) + 2;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_RECORD)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Start recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                ChatRecording = [];&lt;br /&gt;
                NumLines=0;&lt;br /&gt;
                Length=0;&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CONTINUE)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Continue recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_REPLY)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    string address=llList2String(AddressList,CurrentMessage);&lt;br /&gt;
                    string subject=&amp;quot;Re: &amp;quot; + llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, address, NULL_KEY);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, subject, NULL_KEY);&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines=0;&lt;br /&gt;
                    Length=0;&lt;br /&gt;
                    Recording = TRUE;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_MAIL)&lt;br /&gt;
            {&lt;br /&gt;
                string mailaddress=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailaddress != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, mailaddress, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETADDRESS, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SUBJECT)&lt;br /&gt;
            {&lt;br /&gt;
                string mailsubject=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailsubject != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, mailsubject, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETSUBJECT, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Not recording.&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    if (NumLines == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND_NOTECARD, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_IGNORE)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines = 0;&lt;br /&gt;
                    Length = 0;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Show();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_READ)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumMessages == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Read();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        ++CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        --CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_FIRST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = 0;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LAST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LIST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    List();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SELECT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;Need to supply a message number.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    integer msgnum = (integer)arg;&lt;br /&gt;
                     &lt;br /&gt;
                    if (msgnum &amp;lt; 0 || msgnum &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Message number &amp;quot; + arg + &amp;quot; not in mail buffer.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = msgnum;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_DELETE)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    --NumMessages;&lt;br /&gt;
                     &lt;br /&gt;
                    if (NumMessages == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = -1;&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (CurrentMessage &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CLEAR)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList=[];&lt;br /&gt;
                    AddressList=[];&lt;br /&gt;
                    SubjectList=[];&lt;br /&gt;
                    BodyList=[];&lt;br /&gt;
                    NumMessages=0;&lt;br /&gt;
                    CurrentMessage=-1;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_HELP, arg, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_INFO)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                Show();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_RESET)&lt;br /&gt;
            {&lt;br /&gt;
                llResetScript();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                state not_running;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HOME)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs==1)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETHOME, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETHOME, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// email() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    email(string time, string address, string subject, string body, integer queued)&lt;br /&gt;
    {&lt;br /&gt;
        NotifyNewMail(time, address, subject, body);&lt;br /&gt;
        TimeList = (TimeList=[]) + TimeList + [time];&lt;br /&gt;
        AddressList = (AddressList=[]) + AddressList + [address];&lt;br /&gt;
        SubjectList = (SubjectList=[]) + SubjectList + [subject];&lt;br /&gt;
        BodyList = (BodyList=[]) + BodyList + [body];&lt;br /&gt;
        ++NumMessages;&lt;br /&gt;
        &lt;br /&gt;
        if (CurrentMessage == -1)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = NumMessages - 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_REPLY)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state not_running&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state not_running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;SL Mailbox switched OFF. Say @ON to switch it back on.&amp;quot;);&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// on_rez() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// listen() ////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer chan, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string command=llToUpper(message);&lt;br /&gt;
        &lt;br /&gt;
        if (command == COMMAND_ON)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state Error&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state Error&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Error in SL Mail: not all component scripts found.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// End SL Mail V1.2.lsl&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Address Book V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Read and interpret the contents of the Address Book.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail AddressBook V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// &lt;br /&gt;
//  Read the Address Book from a notecard named &amp;quot;Address Book&amp;quot;.&lt;br /&gt;
//&lt;br /&gt;
//  The Address Book has the following format:&lt;br /&gt;
//  &lt;br /&gt;
//  [ADDRESS BOOK]&lt;br /&gt;
//  Name1=username@yourdomain.com&lt;br /&gt;
//  Name2=otheruser@otherdomain.com&lt;br /&gt;
//  ...&lt;br /&gt;
//  [GROUP]&lt;br /&gt;
//  group1=Name1, Name2&lt;br /&gt;
//  ...&lt;br /&gt;
//&lt;br /&gt;
//  Notes:&lt;br /&gt;
//  1. Group and Name share the same namespace, and must be unique.&lt;br /&gt;
//  2. It is allowed to have a name in the addressbook with multiple addresses, seperated by comma&#039;s.&lt;br /&gt;
// &lt;br /&gt;
/////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string  CurrentMailAddress = &amp;quot;&amp;quot;;&lt;br /&gt;
string  CurrentMailSubject = &amp;quot;&amp;quot;;&lt;br /&gt;
integer StatusOnline = FALSE;&lt;br /&gt;
&lt;br /&gt;
// Fetch or Send notecard&lt;br /&gt;
&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Names&lt;br /&gt;
&lt;br /&gt;
list    AddressBookList=[];&lt;br /&gt;
list    MailAddressList=[];&lt;br /&gt;
&lt;br /&gt;
string  STRING_HOME=&amp;quot;HOME&amp;quot;;&lt;br /&gt;
string  STRING_SELF=&amp;quot;SELF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Groups&lt;br /&gt;
&lt;br /&gt;
list   GroupList=[];&lt;br /&gt;
list   GroupNameList=[];&lt;br /&gt;
&lt;br /&gt;
string LSL_DOMAIN = &amp;quot;lsl.secondlife.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Read Address Book notecard&lt;br /&gt;
&lt;br /&gt;
string  ADDRESSBOOK_NOTECARD=&amp;quot;Address Book&amp;quot;;&lt;br /&gt;
integer Line=0;&lt;br /&gt;
key     reqAddressBook=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
integer Section=0;&lt;br /&gt;
integer SECTION_ADDRESS_BOOK=1;&lt;br /&gt;
integer SECTION_GROUP=2;&lt;br /&gt;
string  STRING_ADDRESS_BOOK=&amp;quot;ADDRESS BOOK&amp;quot;;&lt;br /&gt;
string  STRING_GROUP=&amp;quot;GROUP&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Links messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
integer MSG_MESSAGE_NOTIFY              = 90900;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED            = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR            = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// GetSelfAddress() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
string GetSelfAddress()&lt;br /&gt;
{&lt;br /&gt;
    return (string)llGetKey() + &amp;quot;@&amp;quot; + LSL_DOMAIN;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Info() /////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Info()&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;The mail address for this object is: &amp;quot; &lt;br /&gt;
                    + GetSelfAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// IsValidKeyFormat() //////////////////////&lt;br /&gt;
&lt;br /&gt;
integer IsValidKeyFormat(string str)&lt;br /&gt;
{&lt;br /&gt;
    string keychars = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    if (llStringLength(str) != 36)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    if( (llGetSubString( str, 8, 8 )   != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 13, 13 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 18, 18 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 23, 23 )  != &amp;quot;-&amp;quot; ) )&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 9; i &amp;lt; 13; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 14; i &amp;lt; 18; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 19; i &amp;lt; 23; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 24; i &amp;lt; 36; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// ValidMailAddress() ////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer ValidMailAddress(string arg)&lt;br /&gt;
{&lt;br /&gt;
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));&lt;br /&gt;
    &lt;br /&gt;
    if (adress == &amp;quot;&amp;quot;)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    list parse = llParseStringKeepNulls(adress, [ &amp;quot;@&amp;quot; ], []);&lt;br /&gt;
    string account = llList2String(parse,0);&lt;br /&gt;
    string domain  = llList2String(parse,1);&lt;br /&gt;
    &lt;br /&gt;
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    &lt;br /&gt;
    if (domain == LSL_DOMAIN)&lt;br /&gt;
    {&lt;br /&gt;
        return IsValidKeyFormat(account);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list parsedomain = llParseString2List(domain, [ &amp;quot;.&amp;quot; ], []);&lt;br /&gt;
    &lt;br /&gt;
        if (llGetListLength(parsedomain) &amp;lt; 2)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        &lt;br /&gt;
        integer num = llGetListLength(parsedomain);&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llStringLength(llList2String(parsedomain,i)) &amp;lt; 2)&lt;br /&gt;
            {&lt;br /&gt;
                return FALSE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetAddressStr() ///////////////////&lt;br /&gt;
&lt;br /&gt;
string GetAndCheckAddressStr(string address)&lt;br /&gt;
{&lt;br /&gt;
    list addresslist = llCSV2List(address);&lt;br /&gt;
    integer num=llGetListLength(addresslist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    string addressstr=&amp;quot;&amp;quot;;&lt;br /&gt;
    string curaddress=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        curaddress=llList2String(addresslist,i);&lt;br /&gt;
        &lt;br /&gt;
        if (ValidMailAddress(curaddress))&lt;br /&gt;
        {&lt;br /&gt;
            addressstr = (addressstr=&amp;quot;&amp;quot;) + addressstr + curaddress + &amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address string: &#039;&amp;quot; &lt;br /&gt;
                            + curaddress + &amp;quot;&#039;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return llGetSubString(addressstr, 0, -2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ProcessLine() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
ProcessLine(string rawline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(rawline,STRING_TRIM);&lt;br /&gt;
    string first=llGetSubString(line,0,0);&lt;br /&gt;
    string last=llGetSubString(line,-1,-1);&lt;br /&gt;
    &lt;br /&gt;
    // Ignore a blank line or comment line&lt;br /&gt;
    if (line == &amp;quot;&amp;quot; || first == &amp;quot;#&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // Check for the right section&lt;br /&gt;
    &lt;br /&gt;
    if (first == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; last == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        string sectionstr=llToUpper(llStringTrim(llGetSubString(line,1,-2),STRING_TRIM));&lt;br /&gt;
        &lt;br /&gt;
        if (sectionstr == STRING_ADDRESS_BOOK)&lt;br /&gt;
        {&lt;br /&gt;
            Section = SECTION_ADDRESS_BOOK;&lt;br /&gt;
        }&lt;br /&gt;
        else if (sectionstr == STRING_GROUP)&lt;br /&gt;
        {&lt;br /&gt;
            if (Section == 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                        + &amp;quot;. Group section defined before Address Book section.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Section = SECTION_GROUP;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid section header &#039;&amp;quot; + sectionstr &lt;br /&gt;
                        + &amp;quot;&#039; in &amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Must be in a section&lt;br /&gt;
    &lt;br /&gt;
    if (Section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;. No section header.&amp;quot;, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    list     parse=llParseString2List(line, [ &amp;quot;=&amp;quot; ], []);&lt;br /&gt;
    integer  num=llGetListLength(parse);&lt;br /&gt;
    &lt;br /&gt;
    // Format must be correct&lt;br /&gt;
    &lt;br /&gt;
    if (num != 2)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; +  (string)(Line+1) + &amp;quot;:\n&amp;quot; + rawline, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (Section == SECTION_ADDRESS_BOOK)&lt;br /&gt;
    {&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(name) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + name &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ name ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            string address=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
            string addressstr=GetAndCheckAddressStr(address);&lt;br /&gt;
            &lt;br /&gt;
            if (addressstr != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                AddressBookList     = (AddressBookList=[])     + AddressBookList     + [ name ];&lt;br /&gt;
                MailAddressList     = (MailAddressList=[])     + MailAddressList     + [ addressstr ];&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;No valid mail address for &#039;&amp;quot; + name &lt;br /&gt;
                    + &amp;quot;&#039;. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                    + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name &lt;br /&gt;
                + &amp;quot;&#039; already defined. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // Group&lt;br /&gt;
    {&lt;br /&gt;
        string group=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(group) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + group &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ group ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(GroupList, [ group ]) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                string names=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
                list   namelist=llCSV2List(names);&lt;br /&gt;
                integer num=llGetListLength(namelist);&lt;br /&gt;
                integer i;&lt;br /&gt;
                integer index;&lt;br /&gt;
                string  name;&lt;br /&gt;
                string  namestr=&amp;quot;&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
                for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                    name=llList2String(namelist,i);&lt;br /&gt;
                    index=llListFindList(AddressBookList, [ name ]);&lt;br /&gt;
            &lt;br /&gt;
                    if (index == -1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name + &amp;quot;&#039; defined in Group &#039;&amp;quot; &lt;br /&gt;
                                + group + &amp;quot;&#039; not found in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY); &lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        namestr = (namestr=&amp;quot;&amp;quot;) + namestr + name + &amp;quot;,&amp;quot;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (namestr != &amp;quot;&amp;quot;)&lt;br /&gt;
                {    &lt;br /&gt;
                    namestr=llGetSubString(namestr,0,-2);&lt;br /&gt;
                    GroupList         = (GroupList=[])         + GroupList     + [ group ];&lt;br /&gt;
                    GroupNameList     = (GroupNameList=[])    + GroupNameList + [ namestr ];&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                        + &amp;quot;&#039; has no valid names. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                        + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                    + &amp;quot;&#039; already defined in Group. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                    + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group&lt;br /&gt;
                + &amp;quot;&#039; already defined in Address Book. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// GetGroupAddressList ///////////////&lt;br /&gt;
&lt;br /&gt;
string GetGroupAddressList(string group)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(GroupList, [ group ]);&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(GroupList);&lt;br /&gt;
    string  grouplist=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        for (i = index; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2String(GroupList,i) == group)&lt;br /&gt;
            {&lt;br /&gt;
                grouplist = (grouplist=&amp;quot;&amp;quot;) + grouplist + llList2String(GroupNameList,i) + &amp;quot;,&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (grouplist != &amp;quot;&amp;quot;) grouplist=llGetSubString(grouplist,0,-2);   // remove last &amp;quot;,&amp;quot;&lt;br /&gt;
        return grouplist;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// SetMailAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetMailAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ address ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        index=llListFindList(GroupList, [ address ]);&lt;br /&gt;
        &lt;br /&gt;
        if (index == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llToUpper(address) == STRING_SELF)&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = GetSelfAddress();&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if(ValidMailAddress(address))&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = address;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Mail adress &amp;quot; + address &lt;br /&gt;
                            + &amp;quot; : not found in adress book or invalid format.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailAddress = GetGroupAddressList(address);&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        CurrentMailAddress = llList2String(MailAddressList,index);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                        + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string message)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No mail address defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No subject defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list mailaddresslist=llCSV2List(CurrentMailAddress);&lt;br /&gt;
        integer num=llGetListLength(mailaddresslist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(mailaddresslist,i);&lt;br /&gt;
            llEmail(address, CurrentMailSubject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMailHome() ////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMailHome(string message, string subject)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, STRING_HOME &lt;br /&gt;
                + &amp;quot; not set. Set your home adress with @HOME &amp;lt;address&amp;gt;.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        string homeaddress=llList2String(AddressBookList,index);&lt;br /&gt;
        list   homelist=llCSV2List(homeaddress);&lt;br /&gt;
        integer num=llGetListLength(homelist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(homelist,i);&lt;br /&gt;
            llEmail(address, subject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
string GetHomeAddress()&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;not set&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2String(MailAddressList,index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetHomeAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        AddressBookList     = (AddressBookList=[]) + [ STRING_HOME ] + AddressBookList;&lt;br /&gt;
        MailAddressList     = (MailAddressList=[]) + [ GetAndCheckAddressStr(address) ]  + MailAddressList;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MailAddressList = llListReplaceList(MailAddressList, [ GetAndCheckAddressStr(address) ], index, index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        Line=0;&lt;br /&gt;
        Section=0;&lt;br /&gt;
        llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// dataserver() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqAddressBook)&lt;br /&gt;
        {&lt;br /&gt;
            reqAddressBook = NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                ProcessLine(data);&lt;br /&gt;
                reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Address Book loaded.&amp;quot;, NULL_KEY);&lt;br /&gt;
                state running;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// timer() ///////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_ERROR, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Could not read Address Book: &amp;quot; &lt;br /&gt;
                            + ADDRESSBOOK_NOTECARD + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// link_message() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_MESSAGE_GETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is empty.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailSubject = message;&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is empty.&amp;quot;, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            SetMailAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Body of message to send is empty. &amp;quot; &lt;br /&gt;
                                +  &amp;quot;No mail is send.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SENDHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SendMailHome(message, (string)id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetInventoryType(message) == INVENTORY_NOTECARD)&lt;br /&gt;
            {&lt;br /&gt;
                Notecard2Fetch = message;                &lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_READ, message, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + message + &amp;quot; not found.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_NOTECARD_FETCHED)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + Notecard2Fetch &lt;br /&gt;
                            + &amp;quot; was empty or could not be read.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Home address is: &amp;quot; + GetHomeAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SetHomeAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_INFO)&lt;br /&gt;
        {&lt;br /&gt;
            Info();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
// End SL Mail AddressBook V1.2.lsl&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail FetchNotecard V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch the contents of a notecard and return it via link message as a string.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Notecard&lt;br /&gt;
&lt;br /&gt;
integer Line=0;&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
key     reqNotecard=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=10.0;&lt;br /&gt;
integer Fetched=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Lines&lt;br /&gt;
&lt;br /&gt;
list LineList=[];&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    /////////////////////// dataserver() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqNotecard)&lt;br /&gt;
        {&lt;br /&gt;
            reqNotecard=NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                LineList = (LineList=[]) + LineList + [ data ];&lt;br /&gt;
                reqNotecard = llGetNotecardLine(Notecard2Fetch, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Fetched=TRUE;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, llDumpList2String(LineList, &amp;quot;\n&amp;quot;), NULL_KEY);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /////////////////////// timer() ///////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        if (!Fetched)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            llSetTimerEvent(0.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer send, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_NOTECARD_READ)&lt;br /&gt;
        {&lt;br /&gt;
            Line=0;&lt;br /&gt;
            Notecard2Fetch=message;&lt;br /&gt;
            LineList=[];&lt;br /&gt;
            Fetched=FALSE;&lt;br /&gt;
            reqNotecard=llGetNotecardLine(Notecard2Fetch, Line);&lt;br /&gt;
            llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL OnlineStatus V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch online status of owner.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Online status&lt;br /&gt;
&lt;br /&gt;
key     reqOnlineStatus=NULL_KEY;&lt;br /&gt;
float   STATUS_INTERVAL=2.0;&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_STATUS_ONLINE       = 30000;&lt;br /&gt;
integer MS_STATUS_OFFLINE       = 30100;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus=llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
        llSetTimerEvent(STATUS_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// dataserver() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqOnlineStatus)&lt;br /&gt;
        {&lt;br /&gt;
            reqOnlineStatus = NULL_KEY;&lt;br /&gt;
        &lt;br /&gt;
            if (data==&amp;quot;1&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_STATUS_ONLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if (data==&amp;quot;0&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MS_STATUS_OFFLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus = llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Help V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Display help information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail Help V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP    = 10000;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Help() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Help()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;HELP for SL Mail V1.2.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;COMMANDS:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HELP               - displays help info.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@INFO               - display mailaddress of this object.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RECORD             - start recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CONTINUE           - continue recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@STOP               - stop recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@IGNORE             - ignore the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SHOW               - show what your recorded.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SEND               - send the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@MAIL &amp;lt;mailadress&amp;gt;  - set the mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SUBJECT subject    - set the mail subject.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LIST               - list messages in mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SELECT &amp;lt;message&amp;gt;   - select message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@READ               - read current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@NEXT               - read next message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@PREV               - read previous message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@FIRST              - read first message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LAST               - read last message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@DELETE             - delete current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CLEAR              - clear the mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@REPLY              - reply to current message.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RESET              - reset the script.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HOME               - set the home mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@OFF                - switch mailbox OFF.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@ON                 - switch mailbox ON.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_HELP)&lt;br /&gt;
        {&lt;br /&gt;
            Help();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail Help V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}&lt;/div&gt;</description>
			<pubDate>Tue, 25 Jan 2011 23:56:16 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:SL_Mail_V1.2</comments>
		</item>
		<item>
			<title>SL Mail V1.2</title>
			<link>https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=66758</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=66758</guid>
			<description>&lt;p&gt;Flennan Roffo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}} __NOTOC__&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=&#039;&#039;&#039;Second Life mail client&#039;&#039;&#039;=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Send and receive email from within Second Life from and to any address.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implemented with Address Book function (in a notecard named &#039;Address Book&#039;) to stores addresses by name  and to compile groups of named addresses. Current version is stand-alone (no server functionality) and uses chat commands only.&lt;br /&gt;
&lt;br /&gt;
[[Image:BannerSLMail.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.slmail.info slmail.info] (website coming soon!)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Release Notes V1.2=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 Release notes (edition 2, 4 sept 2007)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LICENCE INFO&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is released under GNU free software licence&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;PRODUCTION &amp;amp; MAINTANENCE&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
by Logic Scripted Products and Script Services&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.logicscripts.org logicscripts.org] (website coming soon!)&lt;br /&gt;
&lt;br /&gt;
SLurl:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Contact: [[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
&lt;br /&gt;
Email: [mailto:info@slmail.info &#039;&#039;&#039;info&#039;&#039;&#039;] or [mailto:Flennan.Roffo@slmail.info &#039;&#039;&#039;Flennan Roffo&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;DESCRIPTION&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is a simple tool to send and receive mail from within SL.&lt;br /&gt;
You can either compose a message yourself using chat recording, or choose a notecard from inventory to send. The Address Book functionality allows you to use short names for mail recipients stored in a notecard. The current version does not have a persisent mail address. Watch out for the upcoming next release (V1.3) which will facilitate persisent in-world mail addresses and will be enhanced with many new features (See: Requests For Change (RFC).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;COMMANDS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Help&#039;&#039;&#039;&lt;br /&gt;
||Show Help about available commands&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Record&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording (for owner only).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Stop&#039;&#039;&#039;&lt;br /&gt;
||Stops the chat recording without sending&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Continue&#039;&#039;&#039;&lt;br /&gt;
||Continues a previously stopped chat recording. Lines will be appended to you recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Show&#039;&#039;&#039;&lt;br /&gt;
||Shows the content of the recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send&#039;&#039;&#039;&lt;br /&gt;
||If recording, stops the recording, and sends the mail (need to supply mail address and subject first!)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send &amp;lt;notecard&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Sends the content of the notecard, instead of the chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Ignore&#039;&#039;&#039;&lt;br /&gt;
||Ignores your current chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject &amp;lt;subject&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the subject of the mail.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail subject.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Set the HOME address of the owner (mail will be forwarder to this address when offline).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home&#039;&#039;&#039;&lt;br /&gt;
||Show the HOME address.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Info&#039;&#039;&#039;&lt;br /&gt;
||Shows the mail address the object this script is running in uses (e.g. &amp;lt;object-key&amp;gt;@lsl.secondlife.com).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Read&#039;&#039;&#039;&lt;br /&gt;
||Reads the current message from the mail buffer (the mail buffer gets filled with mail you receive)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Select &amp;lt;msg&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Select a message number from the availabe messages in the mail buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Next&#039;&#039;&#039;&lt;br /&gt;
||Make next message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Prev&#039;&#039;&#039;&lt;br /&gt;
||Make previous message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@First&#039;&#039;&#039;&lt;br /&gt;
||Make the first message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Last&#039;&#039;&#039;&lt;br /&gt;
||Make the last message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Clear&#039;&#039;&#039;&lt;br /&gt;
||Clear the mail buffer&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Delete&#039;&#039;&#039;&lt;br /&gt;
||Deletes only the current message&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Reply&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording to reply to the current message. Mail adress and subject are filled in automatically.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* Commands are case insensitive (&amp;quot;@read&amp;quot; == &amp;quot;@READ&amp;quot;). Arguments might not be case insensitive.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;ADDRESS BOOK FORMAT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
A notecard of the name &#039;Address Book&#039; is read during initialization which may contain Address Book items and Groups.&lt;br /&gt;
The notecard is split in two sections, which need to be defined in that particular order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[ADDRESS BOOK]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Defines the section in which you can put names for mail addresses,  like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name1=account@thisdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name2=user@otherdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[GROUP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define groups of previously defined names under a new name, like for instance:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyGroup=Name1, Name2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note that names of groups and individual mail adresses share the same namespace and must be unique.&lt;br /&gt;
&lt;br /&gt;
So when you filled in your mail adresses in the Address Book, you can now use:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail Name1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to  &amp;lt;account@thisdomain.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail MyGroup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to &amp;lt;account@thisdomain.com&amp;gt; and &amp;lt;user@otherdomain.com&amp;gt;&lt;br /&gt;
Mails will be sent one after another.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* Names for Addreses and Groups are case insensitive (e.g. &amp;quot;mary&amp;quot;  == &amp;quot;MARY&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* The special address &#039;Self&#039; can be used in commands where otherwise an address specification can be used. &#039;Self&#039; is case insensitive (e.g. &amp;quot;self&amp;quot; == &amp;quot;SELF&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LIMITATIONS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
The current version is limited by the following:&lt;br /&gt;
&lt;br /&gt;
* Chat recording lines are limited by the 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Output of lines from the mail buffer are also limited by this 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Incoming mail is limited to a 1000 (1024?) byte limit&lt;br /&gt;
&lt;br /&gt;
* Outgoing mai is limited by a 4096 byte limit, which includes the standard mail header (region/location info on the first two lines)&lt;br /&gt;
&lt;br /&gt;
We are making adjustments to this release to help overcome these limitations. At least the line lenght limit can be overcome by introducing a line continuation character (for example a hyphen &#039;-&#039;) that when used at the end of a line appends the next line, so lines longer then 255 bytes are possible then.&lt;br /&gt;
&lt;br /&gt;
To overcome the outgoing mail length limit, the mail can be broken textualy into parts, and each part can be send seperatedely, with an indication in the subject or in an introduced primary line of the mail body to indicate that the mail was split into parts.&lt;br /&gt;
For incoming mail and at least to receive mail from other SL Mail programs, a protocol will be introduced to receive mail in parts that are joined together after receiving them to form a single mail.&lt;br /&gt;
&lt;br /&gt;
These enhancements will be made available in the next release (V1.3) of SL Mail &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;BUGS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Report any bugs you find in this release to Logic (IM: Flennan Roffo).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;REQUEST FOR CHANGE (RFC)&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Do you have additional wishes for enhancement of this product?&lt;br /&gt;
Contact Flennan Roffo and we will see if they can be implemented in the next release.&lt;br /&gt;
&lt;br /&gt;
Existing RFC&#039;s are:&lt;br /&gt;
&lt;br /&gt;
* Menu support for commands.&lt;br /&gt;
&lt;br /&gt;
* Lines on incoming/outgoing mail longer than 255 bytes.&lt;br /&gt;
&lt;br /&gt;
* Send messages longer than 4096 (minus SL mail header) bytes.&lt;br /&gt;
&lt;br /&gt;
* Receive messages longer than 1024 bytes.&lt;br /&gt;
&lt;br /&gt;
* Permanent mail addresses for the SL Mail client (like: &amp;lt;Flennan.Roffo@somedomain.sl&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Add your RFC!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In-world join the group &amp;quot;SL Mail&amp;quot; for bug reports, feature requests, the latest SL Mail release, and notices about development issues.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scripts=&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==Script: SL Mail v1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail core module which scans for incoming mail messages and executes commands used by the owner.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail V1.2.lsl&lt;br /&gt;
// (c) 2007 Logic Scripted Products and Script Services&lt;br /&gt;
// Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
// VERSION&lt;br /&gt;
// Version: 1.2&lt;br /&gt;
&lt;br /&gt;
// HISTORY&lt;br /&gt;
// Date         Version     Author              Comment&lt;br /&gt;
// --------------------------------------------------------------------------------------&lt;br /&gt;
// 28 aug 2007  V 1.0       Flennan Roffo       Created&lt;br /&gt;
//&lt;br /&gt;
//  1 sep 2007  V 1.1       Flennan Roffo       @Reply empties the recording buffer.&lt;br /&gt;
//                                                @Send while recording ends recording&lt;br /&gt;
//                                                and sends the mail if a mail address&lt;br /&gt;
//                                                and subject are supplied.&lt;br /&gt;
//                                                Fixed incorrect date in Unix2DateTime.&lt;br /&gt;
//  3 sep 2007  V 1.2       Flennan Roffo       Notification options:&lt;br /&gt;
//                                              - When online, send an IM when mail is received.&lt;br /&gt;
//                                              - When offline, send to HOME mail adress.&lt;br /&gt;
//                                              Adressbook&lt;br /&gt;
//                                              - Read adress book from config notecard.&lt;br /&gt;
&lt;br /&gt;
// LICENCE&lt;br /&gt;
// This program is free software; you can redistribute it and/or&lt;br /&gt;
// modify it under the terms of the GNU General Public License&lt;br /&gt;
// as published by the Free Software Foundation; either version 2&lt;br /&gt;
// of the License, or (at your option) any later version.&lt;br /&gt;
// &lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
// &lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program; if not, write to the Free Software&lt;br /&gt;
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
// (Also available at http://www.gnu.org/copyleft/gpl.html) &lt;br /&gt;
&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// Let&#039;s you record a message and sent to email and get messages and reply to messages.&lt;br /&gt;
// Must supply a valid mail adress and non-empty subject using chat commands.&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
// 1) Check for the maximum length of an email message (including newline and header).&lt;br /&gt;
// 2) Read adress book from notecard.                                    *DONE*&lt;br /&gt;
// 3) Send incoming mail to personal mail adress when offline.            *DONE*&lt;br /&gt;
// 4) Alert with an IM when online upon receiving new mail.                *DONE*&lt;br /&gt;
&lt;br /&gt;
string   SL_MAIL_VERSION = &amp;quot;V 1.2&amp;quot;;&lt;br /&gt;
string   SL_MAIL_DATE    = &amp;quot; 2 sep 2007&amp;quot;;&lt;br /&gt;
integer  ErrorFlag         = FALSE;&lt;br /&gt;
list     ScriptList        = [ &amp;quot;SL Mail Help V1.2&amp;quot;, &amp;quot;SL Mail AddressBook V1.2&amp;quot;, &lt;br /&gt;
                                &amp;quot;SL Mail OnlineStatus V1.2&amp;quot;, &amp;quot;SL Mail FetchNotecard V1.2&amp;quot; ];    &lt;br /&gt;
string   LSL_DOMAIN=&amp;quot;lsl.secondlife.com&amp;quot;; &lt;br /&gt;
integer  StatusOnline=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Commands&lt;br /&gt;
&lt;br /&gt;
string  COMMAND_RECORD     = &amp;quot;@RECORD&amp;quot;;&lt;br /&gt;
string  COMMAND_CONTINUE   = &amp;quot;@CONTINUE&amp;quot;;&lt;br /&gt;
string  COMMAND_STOP       = &amp;quot;@STOP&amp;quot;;&lt;br /&gt;
string  COMMAND_MAIL       = &amp;quot;@MAIL&amp;quot;;&lt;br /&gt;
string  COMMAND_SUBJECT    = &amp;quot;@SUBJECT&amp;quot;;&lt;br /&gt;
string  COMMAND_SEND       = &amp;quot;@SEND&amp;quot;;&lt;br /&gt;
string  COMMAND_SEE        = &amp;quot;@SEE&amp;quot;;&lt;br /&gt;
string  COMMAND_IGNORE     = &amp;quot;@IGNORE&amp;quot;;&lt;br /&gt;
string  COMMAND_READ       = &amp;quot;@READ&amp;quot;;&lt;br /&gt;
string  COMMAND_DELETE     = &amp;quot;@DELETE&amp;quot;;&lt;br /&gt;
string  COMMAND_CLEAR      = &amp;quot;@CLEAR&amp;quot;;&lt;br /&gt;
string  COMMAND_REPLY      = &amp;quot;@REPLY&amp;quot;;&lt;br /&gt;
string  COMMAND_NEXT       = &amp;quot;@NEXT&amp;quot;;&lt;br /&gt;
string  COMMAND_PREV       = &amp;quot;@PREV&amp;quot;;&lt;br /&gt;
string  COMMAND_FIRST      = &amp;quot;@FIRST&amp;quot;;&lt;br /&gt;
string  COMMAND_LAST       = &amp;quot;@LAST&amp;quot;;&lt;br /&gt;
string  COMMAND_LIST       = &amp;quot;@LIST&amp;quot;;&lt;br /&gt;
string  COMMAND_SELECT     = &amp;quot;@SELECT&amp;quot;;&lt;br /&gt;
string  COMMAND_HELP       = &amp;quot;@HELP&amp;quot;;&lt;br /&gt;
string  COMMAND_INFO       = &amp;quot;@INFO&amp;quot;;&lt;br /&gt;
string  COMMAND_RESET      = &amp;quot;@RESET&amp;quot;;&lt;br /&gt;
string  COMMAND_SHOW       = &amp;quot;@SHOW&amp;quot;;&lt;br /&gt;
string  COMMAND_ON         = &amp;quot;@ON&amp;quot;;&lt;br /&gt;
string  COMMAND_OFF        = &amp;quot;@OFF&amp;quot;;&lt;br /&gt;
string  COMMAND_HOME       = &amp;quot;@HOME&amp;quot;;&lt;br /&gt;
string  COMMAND_LOAD       = &amp;quot;@LOAD&amp;quot;;&lt;br /&gt;
string  COMMAND_ADDRESS    = &amp;quot;@ADDRESS&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Recording&lt;br /&gt;
&lt;br /&gt;
integer Recording = FALSE;&lt;br /&gt;
&lt;br /&gt;
list    ChatRecording=[];&lt;br /&gt;
integer NumLines=0;&lt;br /&gt;
integer Length=0;&lt;br /&gt;
&lt;br /&gt;
list     TimeList=[];&lt;br /&gt;
list     AddressList=[];&lt;br /&gt;
list     SubjectList=[];&lt;br /&gt;
list     BodyList=[];&lt;br /&gt;
integer  NumMessages=0;&lt;br /&gt;
integer  CurrentMessage=-1;&lt;br /&gt;
&lt;br /&gt;
float    MAIL_FETCH_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
// Link Messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP                        = 10000;&lt;br /&gt;
integer MSG_STATUS_ONLINE               = 30000;&lt;br /&gt;
integer MSG_STATUS_OFFLINE              = 30100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED          = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR           = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Unix Time conversion //////////////////&lt;br /&gt;
&lt;br /&gt;
integer DAYS_PER_YEAR        = 365;                // Non leap year&lt;br /&gt;
integer SECONDS_PER_YEAR     = 31536000;          // Non leap year&lt;br /&gt;
integer SECONDS_PER_DAY      = 86400;&lt;br /&gt;
integer SECONDS_PER_HOUR     = 3600;&lt;br /&gt;
integer SECONDS_PER_MINUTE   = 60;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// LeapYear() /////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer LeapYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (year % 4 == 0)&lt;br /&gt;
    {&lt;br /&gt;
        if (year % 100 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (year % 400 == 0)&lt;br /&gt;
            {&lt;br /&gt;
                return 1;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// DaysPerMonth() ///////////////////////////////////////&lt;br /&gt;
                &lt;br /&gt;
integer DaysPerMonth(integer year,integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;lt; 8)&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (month == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if (LeapYear(year))&lt;br /&gt;
                {&lt;br /&gt;
                    return 29;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    return 28;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 30;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 30;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////// DaysPerYear() ////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DaysPerYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (LeapYear(year))&lt;br /&gt;
        return DAYS_PER_YEAR + 1;&lt;br /&gt;
    else&lt;br /&gt;
        return DAYS_PER_YEAR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Unix2DataTime() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list Unix2DateTime(integer unixtime)&lt;br /&gt;
{&lt;br /&gt;
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;&lt;br /&gt;
    integer day = days_since_1_1_1970 + 1;&lt;br /&gt;
    integer year  = 1970;&lt;br /&gt;
    integer days_per_year = DaysPerYear(year);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_year)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_year;&lt;br /&gt;
        ++year;&lt;br /&gt;
        days_per_year = DaysPerYear(year);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer month = 1;&lt;br /&gt;
    integer days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_month)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_month;&lt;br /&gt;
        &lt;br /&gt;
        if (++month &amp;gt; 12)&lt;br /&gt;
        {    &lt;br /&gt;
            ++year;&lt;br /&gt;
            month = 1;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;&lt;br /&gt;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;&lt;br /&gt;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;&lt;br /&gt;
    integer minute      = second / SECONDS_PER_MINUTE;&lt;br /&gt;
    second               = second % SECONDS_PER_MINUTE;&lt;br /&gt;
    &lt;br /&gt;
    return [ year, month, day, hour, minute, second ];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// MonthName() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list MonthNameList = [     &amp;quot;JAN&amp;quot;, &amp;quot;FEB&amp;quot;, &amp;quot;MAR&amp;quot;, &amp;quot;APR&amp;quot;, &amp;quot;MAY&amp;quot;, &amp;quot;JUN&amp;quot;, &lt;br /&gt;
                        &amp;quot;JUL&amp;quot;, &amp;quot;AUG&amp;quot;, &amp;quot;SEP&amp;quot;, &amp;quot;OCT&amp;quot; , &amp;quot;NOV&amp;quot;, &amp;quot;DEC&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
string MonthName(integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;gt;= 0 &amp;amp;&amp;amp; month &amp;lt; 12)&lt;br /&gt;
        return llList2String(MonthNameList, month);&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// DateString() ///////////////////////////&lt;br /&gt;
&lt;br /&gt;
string DateString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer year       = llList2Integer(timelist,0);&lt;br /&gt;
    integer month      = llList2Integer(timelist,1);&lt;br /&gt;
    integer day        = llList2Integer(timelist,2);&lt;br /&gt;
    &lt;br /&gt;
    return (string)day + &amp;quot;-&amp;quot; + MonthName(month - 1) + &amp;quot;-&amp;quot; + (string)year;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// TimeString() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string TimeString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer hour          = llList2Integer(timelist,3);&lt;br /&gt;
    integer minute         = llList2Integer(timelist,4);&lt;br /&gt;
    integer second         = llList2Integer(timelist,5);&lt;br /&gt;
    string  hourstr     = (string)hour;&lt;br /&gt;
    string  minutestr   = (string)minute;&lt;br /&gt;
    string  secondstr   = (string)second;&lt;br /&gt;
    &lt;br /&gt;
    if (hour &amp;lt; 10)         hourstr     = &amp;quot;0&amp;quot; + hourstr;&lt;br /&gt;
    if (minute &amp;lt; 10)     minutestr     = &amp;quot;0&amp;quot; + minutestr;&lt;br /&gt;
    if (second &amp;lt; 10)    secondstr    = &amp;quot;0&amp;quot; + secondstr;&lt;br /&gt;
    return hourstr + &amp;quot;:&amp;quot; + minutestr + &amp;quot;:&amp;quot; + secondstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() /////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string body)&lt;br /&gt;
{&lt;br /&gt;
    // llOwnerSay(&amp;quot;Sending message to &#039;&amp;quot; + address + &amp;quot;&#039; with subject &#039;&amp;quot; + subject +&amp;quot;&#039;.&amp;quot;);&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND, body, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// SendHome() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendHome(string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SENDHOME, body, (key)subject);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Show() ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Show()&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;Current chat recording is:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; NumLines; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(ChatRecording,i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;Lines is &amp;quot; + (string)NumLines);&lt;br /&gt;
    llOwnerSay(&amp;quot;Message length is &amp;quot; + (string)Length);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Read() /////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Read()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;Reading message &amp;quot; + (string)CurrentMessage + &amp;quot; from mail buffer.&amp;quot;);&lt;br /&gt;
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);&lt;br /&gt;
    list timelist=Unix2DateTime(time);&lt;br /&gt;
    string Address = llList2String(AddressList,CurrentMessage);&lt;br /&gt;
    string Subject = llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
    string Body    = llList2String(BodyList,CurrentMessage);&lt;br /&gt;
    llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Address: &amp;quot; + Address);&lt;br /&gt;
    llOwnerSay(&amp;quot;Subject: &amp;quot; + Subject);&lt;br /&gt;
    llOwnerSay(&amp;quot;Begin of message body:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    list bodylist=llParseStringKeepNulls(Body, [ &amp;quot;\n&amp;quot; ], []);&lt;br /&gt;
    integer num=llGetListLength(bodylist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(bodylist,i));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;End of message body.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////// List ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
List()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;The mail buffer contains the following messages:\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; NumMessages; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer time=llList2Integer(TimeList,i);&lt;br /&gt;
        list timelist=Unix2DateTime(time);&lt;br /&gt;
        if (i &amp;gt; 0) llOwnerSay(&amp;quot;+-+-+-+-+-+-+-+-+-+-+-+-&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Message: &amp;quot; + (string)i);&lt;br /&gt;
        llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;From:    &amp;quot; + llList2String(AddressList,i));&lt;br /&gt;
        llOwnerSay(&amp;quot;Subject: &amp;quot; + llList2String(SubjectList,i));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////// NotifyNewMail() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
NotifyNewMail(string time, string address, string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    list timelist=Unix2DateTime((integer)time);&lt;br /&gt;
&lt;br /&gt;
    if (StatusOnline)&lt;br /&gt;
    {&lt;br /&gt;
        llInstantMessage(llGetOwner(), &amp;quot;You received a new mail message on &amp;quot; &lt;br /&gt;
                                    + DateString(timelist) + &amp;quot; at &amp;quot; + TimeString(timelist)&lt;br /&gt;
                                    + &amp;quot; from &amp;quot; + address &lt;br /&gt;
                                    + &amp;quot; with the subject &amp;quot; + subject);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        SendHome(&amp;quot;FW: &amp;quot; + subject, &amp;quot;Received at: &amp;quot; + DateString(timelist) + &amp;quot; &amp;quot; + TimeString(timelist) + &amp;quot;\nFrom: &amp;quot; +  address &lt;br /&gt;
                    + &amp;quot;\nBegin message body:\n-------------------\n&amp;quot; + body + &amp;quot;\n-------------------\nEnd message body.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ResetOtherScripts() //////////////////////&lt;br /&gt;
&lt;br /&gt;
ResetOtherScripts()&lt;br /&gt;
{&lt;br /&gt;
    string     name;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(ScriptList);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        name = llList2String(ScriptList,i);&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(name) == INVENTORY_SCRIPT)&lt;br /&gt;
        {&lt;br /&gt;
            llResetOtherScript(name);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Error - script &#039;&amp;quot; + name + &amp;quot;&#039; not found.&amp;quot;);&lt;br /&gt;
            ErrorFlag = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
// default &lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ////////////////////// state_entry() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Welcome to SL Mail, released under GNU software licence.&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Version &amp;quot; + SL_MAIL_VERSION + &amp;quot; &amp;quot; + SL_MAIL_DATE);&lt;br /&gt;
        llOwnerSay(&amp;quot;Produced by Logic Scripted Products &amp;amp; Product Services&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Free memory: &amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
        ResetOtherScripts();&lt;br /&gt;
        &lt;br /&gt;
        if (ErrorFlag)&lt;br /&gt;
            state Error;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// on_rez() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// changed() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_LOADED)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_ERROR)&lt;br /&gt;
        {&lt;br /&gt;
            state Error;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() //////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(MAIL_FETCH_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //////////////////////// on_rez() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// listen() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string trimmessage=llStringTrim(message,STRING_TRIM);&lt;br /&gt;
        list   parse = llParseStringKeepNulls(trimmessage, [ &amp;quot; &amp;quot;], []);&lt;br /&gt;
        string command = llToUpper(llList2String(parse,0));&lt;br /&gt;
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        integer nargs  = llGetListLength(parse);&lt;br /&gt;
        string argstr=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (nargs &amp;gt; 1) argstr=llGetSubString(message, llSubStringIndex(message, &amp;quot; &amp;quot;) + 1, -1);&lt;br /&gt;
            &lt;br /&gt;
        if (Recording)&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Recording stopped. Type @SHOW to see the message you have entered,&amp;quot;&lt;br /&gt;
                            + &amp;quot; or @SEND to send it.&amp;quot;);&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                &lt;br /&gt;
                SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];&lt;br /&gt;
                ++NumLines;&lt;br /&gt;
                Length += llStringLength(message) + 2;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_RECORD)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Start recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                ChatRecording = [];&lt;br /&gt;
                NumLines=0;&lt;br /&gt;
                Length=0;&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CONTINUE)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Continue recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_REPLY)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    string address=llList2String(AddressList,CurrentMessage);&lt;br /&gt;
                    string subject=&amp;quot;Re: &amp;quot; + llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, address, NULL_KEY);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, subject, NULL_KEY);&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines=0;&lt;br /&gt;
                    Length=0;&lt;br /&gt;
                    Recording = TRUE;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_MAIL)&lt;br /&gt;
            {&lt;br /&gt;
                string mailaddress=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailaddress != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, mailaddress, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETADDRESS, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SUBJECT)&lt;br /&gt;
            {&lt;br /&gt;
                string mailsubject=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailsubject != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, mailsubject, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETSUBJECT, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Not recording.&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    if (NumLines == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND_NOTECARD, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_IGNORE)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines = 0;&lt;br /&gt;
                    Length = 0;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Show();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_READ)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumMessages == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Read();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        ++CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        --CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_FIRST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = 0;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LAST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LIST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    List();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SELECT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;Need to supply a message number.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    integer msgnum = (integer)arg;&lt;br /&gt;
                     &lt;br /&gt;
                    if (msgnum &amp;lt; 0 || msgnum &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Message number &amp;quot; + arg + &amp;quot; not in mail buffer.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = msgnum;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_DELETE)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    --NumMessages;&lt;br /&gt;
                     &lt;br /&gt;
                    if (NumMessages == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = -1;&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (CurrentMessage &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CLEAR)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList=[];&lt;br /&gt;
                    AddressList=[];&lt;br /&gt;
                    SubjectList=[];&lt;br /&gt;
                    BodyList=[];&lt;br /&gt;
                    NumMessages=0;&lt;br /&gt;
                    CurrentMessage=-1;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_HELP, arg, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_INFO)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                Show();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_RESET)&lt;br /&gt;
            {&lt;br /&gt;
                llResetScript();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                state not_running;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HOME)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs==1)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETHOME, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETHOME, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// email() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    email(string time, string address, string subject, string body, integer queued)&lt;br /&gt;
    {&lt;br /&gt;
        NotifyNewMail(time, address, subject, body);&lt;br /&gt;
        TimeList = (TimeList=[]) + TimeList + [time];&lt;br /&gt;
        AddressList = (AddressList=[]) + AddressList + [address];&lt;br /&gt;
        SubjectList = (SubjectList=[]) + SubjectList + [subject];&lt;br /&gt;
        BodyList = (BodyList=[]) + BodyList + [body];&lt;br /&gt;
        ++NumMessages;&lt;br /&gt;
        &lt;br /&gt;
        if (CurrentMessage == -1)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = NumMessages - 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_REPLY)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state not_running&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state not_running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;SL Mailbox switched OFF. Say @ON to switch it back on.&amp;quot;);&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// on_rez() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// listen() ////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer chan, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string command=llToUpper(message);&lt;br /&gt;
        &lt;br /&gt;
        if (command == COMMAND_ON)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state Error&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state Error&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Error in SL Mail: not all component scripts found.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// End SL Mail V1.2.lsl&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Address Book V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Read and interpret the contents of the Address Book.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail AddressBook V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// &lt;br /&gt;
//  Read the Address Book from a notecard named &amp;quot;Address Book&amp;quot;.&lt;br /&gt;
//&lt;br /&gt;
//  The Address Book has the following format:&lt;br /&gt;
//  &lt;br /&gt;
//  [ADDRESS BOOK]&lt;br /&gt;
//  Name1=username@yourdomain.com&lt;br /&gt;
//  Name2=otheruser@otherdomain.com&lt;br /&gt;
//  ...&lt;br /&gt;
//  [GROUP]&lt;br /&gt;
//  group1=Name1, Name2&lt;br /&gt;
//  ...&lt;br /&gt;
//&lt;br /&gt;
//  Notes:&lt;br /&gt;
//  1. Group and Name share the same namespace, and must be unique.&lt;br /&gt;
//  2. It is allowed to have a name in the addressbook with multiple addresses, seperated by comma&#039;s.&lt;br /&gt;
// &lt;br /&gt;
/////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string  CurrentMailAddress = &amp;quot;&amp;quot;;&lt;br /&gt;
string  CurrentMailSubject = &amp;quot;&amp;quot;;&lt;br /&gt;
integer StatusOnline = FALSE;&lt;br /&gt;
&lt;br /&gt;
// Fetch or Send notecard&lt;br /&gt;
&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Names&lt;br /&gt;
&lt;br /&gt;
list    AddressBookList=[];&lt;br /&gt;
list    MailAddressList=[];&lt;br /&gt;
&lt;br /&gt;
string  STRING_HOME=&amp;quot;HOME&amp;quot;;&lt;br /&gt;
string  STRING_SELF=&amp;quot;SELF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Groups&lt;br /&gt;
&lt;br /&gt;
list   GroupList=[];&lt;br /&gt;
list   GroupNameList=[];&lt;br /&gt;
&lt;br /&gt;
string LSL_DOMAIN = &amp;quot;lsl.secondlife.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Read Address Book notecard&lt;br /&gt;
&lt;br /&gt;
string  ADDRESSBOOK_NOTECARD=&amp;quot;Address Book&amp;quot;;&lt;br /&gt;
integer Line=0;&lt;br /&gt;
key     reqAddressBook=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
integer Section=0;&lt;br /&gt;
integer SECTION_ADDRESS_BOOK=1;&lt;br /&gt;
integer SECTION_GROUP=2;&lt;br /&gt;
string  STRING_ADDRESS_BOOK=&amp;quot;ADDRESS BOOK&amp;quot;;&lt;br /&gt;
string  STRING_GROUP=&amp;quot;GROUP&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Links messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
integer MSG_MESSAGE_NOTIFY              = 90900;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED            = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR            = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// GetSelfAddress() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
string GetSelfAddress()&lt;br /&gt;
{&lt;br /&gt;
    return (string)llGetKey() + &amp;quot;@&amp;quot; + LSL_DOMAIN;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Info() /////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Info()&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;The mail address for this object is: &amp;quot; &lt;br /&gt;
                    + GetSelfAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// IsValidKeyFormat() //////////////////////&lt;br /&gt;
&lt;br /&gt;
integer IsValidKeyFormat(string str)&lt;br /&gt;
{&lt;br /&gt;
    string keychars = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    if (llStringLength(str) != 36)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    if( (llGetSubString( str, 8, 8 )   != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 13, 13 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 18, 18 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 23, 23 )  != &amp;quot;-&amp;quot; ) )&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 9; i &amp;lt; 13; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 14; i &amp;lt; 18; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 19; i &amp;lt; 23; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 24; i &amp;lt; 36; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// ValidMailAddress() ////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer ValidMailAddress(string arg)&lt;br /&gt;
{&lt;br /&gt;
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));&lt;br /&gt;
    &lt;br /&gt;
    if (adress == &amp;quot;&amp;quot;)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    list parse = llParseStringKeepNulls(adress, [ &amp;quot;@&amp;quot; ], []);&lt;br /&gt;
    string account = llList2String(parse,0);&lt;br /&gt;
    string domain  = llList2String(parse,1);&lt;br /&gt;
    &lt;br /&gt;
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    &lt;br /&gt;
    if (domain == LSL_DOMAIN)&lt;br /&gt;
    {&lt;br /&gt;
        return IsValidKeyFormat(account);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list parsedomain = llParseString2List(domain, [ &amp;quot;.&amp;quot; ], []);&lt;br /&gt;
    &lt;br /&gt;
        if (llGetListLength(parsedomain) &amp;lt; 2)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        &lt;br /&gt;
        integer num = llGetListLength(parsedomain);&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llStringLength(llList2String(parsedomain,i)) &amp;lt; 2)&lt;br /&gt;
            {&lt;br /&gt;
                return FALSE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetAddressStr() ///////////////////&lt;br /&gt;
&lt;br /&gt;
string GetAndCheckAddressStr(string address)&lt;br /&gt;
{&lt;br /&gt;
    list addresslist = llCSV2List(address);&lt;br /&gt;
    integer num=llGetListLength(addresslist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    string addressstr=&amp;quot;&amp;quot;;&lt;br /&gt;
    string curaddress=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        curaddress=llList2String(addresslist,i);&lt;br /&gt;
        &lt;br /&gt;
        if (ValidMailAddress(curaddress))&lt;br /&gt;
        {&lt;br /&gt;
            addressstr = (addressstr=&amp;quot;&amp;quot;) + addressstr + curaddress + &amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address string: &#039;&amp;quot; &lt;br /&gt;
                            + curaddress + &amp;quot;&#039;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return llGetSubString(addressstr, 0, -2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ProcessLine() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
ProcessLine(string rawline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(rawline,STRING_TRIM);&lt;br /&gt;
    string first=llGetSubString(line,0,0);&lt;br /&gt;
    string last=llGetSubString(line,-1,-1);&lt;br /&gt;
    &lt;br /&gt;
    // Ignore a blank line or comment line&lt;br /&gt;
    if (line == &amp;quot;&amp;quot; || first == &amp;quot;#&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // Check for the right section&lt;br /&gt;
    &lt;br /&gt;
    if (first == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; last == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        string sectionstr=llToUpper(llStringTrim(llGetSubString(line,1,-2),STRING_TRIM));&lt;br /&gt;
        &lt;br /&gt;
        if (sectionstr == STRING_ADDRESS_BOOK)&lt;br /&gt;
        {&lt;br /&gt;
            Section = SECTION_ADDRESS_BOOK;&lt;br /&gt;
        }&lt;br /&gt;
        else if (sectionstr == STRING_GROUP)&lt;br /&gt;
        {&lt;br /&gt;
            if (Section == 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                        + &amp;quot;. Group section defined before Address Book section.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Section = SECTION_GROUP;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid section header &#039;&amp;quot; + sectionstr &lt;br /&gt;
                        + &amp;quot;&#039; in &amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Must be in a section&lt;br /&gt;
    &lt;br /&gt;
    if (Section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;. No section header.&amp;quot;, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    list     parse=llParseString2List(line, [ &amp;quot;=&amp;quot; ], []);&lt;br /&gt;
    integer  num=llGetListLength(parse);&lt;br /&gt;
    &lt;br /&gt;
    // Format must be correct&lt;br /&gt;
    &lt;br /&gt;
    if (num != 2)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; +  (string)(Line+1) + &amp;quot;:\n&amp;quot; + rawline, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (Section == SECTION_ADDRESS_BOOK)&lt;br /&gt;
    {&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(name) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + name &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ name ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            string address=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
            string addressstr=GetAndCheckAddressStr(address);&lt;br /&gt;
            &lt;br /&gt;
            if (addressstr != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                AddressBookList     = (AddressBookList=[])     + AddressBookList     + [ name ];&lt;br /&gt;
                MailAddressList     = (MailAddressList=[])     + MailAddressList     + [ addressstr ];&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;No valid mail address for &#039;&amp;quot; + name &lt;br /&gt;
                    + &amp;quot;&#039;. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                    + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name &lt;br /&gt;
                + &amp;quot;&#039; already defined. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // Group&lt;br /&gt;
    {&lt;br /&gt;
        string group=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(group) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + group &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ group ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(GroupList, [ group ]) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                string names=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
                list   namelist=llCSV2List(names);&lt;br /&gt;
                integer num=llGetListLength(namelist);&lt;br /&gt;
                integer i;&lt;br /&gt;
                integer index;&lt;br /&gt;
                string  name;&lt;br /&gt;
                string  namestr=&amp;quot;&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
                for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                    name=llList2String(namelist,i);&lt;br /&gt;
                    index=llListFindList(AddressBookList, [ name ]);&lt;br /&gt;
            &lt;br /&gt;
                    if (index == -1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name + &amp;quot;&#039; defined in Group &#039;&amp;quot; &lt;br /&gt;
                                + group + &amp;quot;&#039; not found in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY); &lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        namestr = (namestr=&amp;quot;&amp;quot;) + namestr + name + &amp;quot;,&amp;quot;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (namestr != &amp;quot;&amp;quot;)&lt;br /&gt;
                {    &lt;br /&gt;
                    namestr=llGetSubString(namestr,0,-2);&lt;br /&gt;
                    GroupList         = (GroupList=[])         + GroupList     + [ group ];&lt;br /&gt;
                    GroupNameList     = (GroupNameList=[])    + GroupNameList + [ namestr ];&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                        + &amp;quot;&#039; has no valid names. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                        + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                    + &amp;quot;&#039; already defined in Group. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                    + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group&lt;br /&gt;
                + &amp;quot;&#039; already defined in Address Book. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// GetGroupAddressList ///////////////&lt;br /&gt;
&lt;br /&gt;
string GetGroupAddressList(string group)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(GroupList, [ group ]);&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(GroupList);&lt;br /&gt;
    string  grouplist=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        for (i = index; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2String(GroupList,i) == group)&lt;br /&gt;
            {&lt;br /&gt;
                grouplist = (grouplist=&amp;quot;&amp;quot;) + grouplist + llList2String(GroupNameList,i) + &amp;quot;,&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (grouplist != &amp;quot;&amp;quot;) grouplist=llGetSubString(grouplist,0,-2);   // remove last &amp;quot;,&amp;quot;&lt;br /&gt;
        return grouplist;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// SetMailAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetMailAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ address ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        index=llListFindList(GroupList, [ address ]);&lt;br /&gt;
        &lt;br /&gt;
        if (index == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llToUpper(address) == STRING_SELF)&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = GetSelfAddress();&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if(ValidMailAddress(address))&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = address;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Mail adress &amp;quot; + address &lt;br /&gt;
                            + &amp;quot; : not found in adress book or invalid format.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailAddress = GetGroupAddressList(address);&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        CurrentMailAddress = llList2String(MailAddressList,index);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                        + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string message)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No mail address defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No subject defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list mailaddresslist=llCSV2List(CurrentMailAddress);&lt;br /&gt;
        integer num=llGetListLength(mailaddresslist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(mailaddresslist,i);&lt;br /&gt;
            llEmail(address, CurrentMailSubject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMailHome() ////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMailHome(string message, string subject)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, STRING_HOME &lt;br /&gt;
                + &amp;quot; not set. Set your home adress with @HOME &amp;lt;address&amp;gt;.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        string homeaddress=llList2String(AddressBookList,index);&lt;br /&gt;
        list   homelist=llCSV2List(homeaddress);&lt;br /&gt;
        integer num=llGetListLength(homelist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(homelist,i);&lt;br /&gt;
            llEmail(address, subject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
string GetHomeAddress()&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;not set&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2String(MailAddressList,index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetHomeAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        AddressBookList     = (AddressBookList=[]) + [ STRING_HOME ] + AddressBookList;&lt;br /&gt;
        MailAddressList     = (MailAddressList=[]) + [ GetAndCheckAddressStr(address) ]  + MailAddressList;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MailAddressList = llListReplaceList(MailAddressList, [ GetAndCheckAddressStr(address) ], index, index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        Line=0;&lt;br /&gt;
        Section=0;&lt;br /&gt;
        llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// dataserver() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqAddressBook)&lt;br /&gt;
        {&lt;br /&gt;
            reqAddressBook = NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                ProcessLine(data);&lt;br /&gt;
                reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Address Book loaded.&amp;quot;, NULL_KEY);&lt;br /&gt;
                state running;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// timer() ///////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_ERROR, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Could not read Address Book: &amp;quot; &lt;br /&gt;
                            + ADDRESSBOOK_NOTECARD + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// link_message() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_MESSAGE_GETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is empty.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailSubject = message;&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is empty.&amp;quot;, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            SetMailAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Body of message to send is empty. &amp;quot; &lt;br /&gt;
                                +  &amp;quot;No mail is send.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SENDHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SendMailHome(message, (string)id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetInventoryType(message) == INVENTORY_NOTECARD)&lt;br /&gt;
            {&lt;br /&gt;
                Notecard2Fetch = message;                &lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_READ, message, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + message + &amp;quot; not found.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_NOTECARD_FETCHED)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + Notecard2Fetch &lt;br /&gt;
                            + &amp;quot; was empty or could not be read.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Home address is: &amp;quot; + GetHomeAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SetHomeAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_INFO)&lt;br /&gt;
        {&lt;br /&gt;
            Info();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
// End SL Mail AddressBook V1.2.lsl&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail FetchNotecard V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch the contents of a notecard and return it via link message as a string.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Notecard&lt;br /&gt;
&lt;br /&gt;
integer Line=0;&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
key     reqNotecard=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=10.0;&lt;br /&gt;
integer Fetched=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Lines&lt;br /&gt;
&lt;br /&gt;
list LineList=[];&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    /////////////////////// dataserver() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqNotecard)&lt;br /&gt;
        {&lt;br /&gt;
            reqNotecard=NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                LineList = (LineList=[]) + LineList + [ data ];&lt;br /&gt;
                reqNotecard = llGetNotecardLine(Notecard2Fetch, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Fetched=TRUE;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, llDumpList2String(LineList, &amp;quot;\n&amp;quot;), NULL_KEY);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /////////////////////// timer() ///////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        if (!Fetched)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            llSetTimerEvent(0.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer send, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_NOTECARD_READ)&lt;br /&gt;
        {&lt;br /&gt;
            Line=0;&lt;br /&gt;
            Notecard2Fetch=message;&lt;br /&gt;
            LineList=[];&lt;br /&gt;
            Fetched=FALSE;&lt;br /&gt;
            reqNotecard=llGetNotecardLine(Notecard2Fetch, Line);&lt;br /&gt;
            llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL OnlineStatus V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch online status of owner.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Online status&lt;br /&gt;
&lt;br /&gt;
key     reqOnlineStatus=NULL_KEY;&lt;br /&gt;
float   STATUS_INTERVAL=2.0;&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_STATUS_ONLINE       = 30000;&lt;br /&gt;
integer MS_STATUS_OFFLINE       = 30100;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus=llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
        llSetTimerEvent(STATUS_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// dataserver() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqOnlineStatus)&lt;br /&gt;
        {&lt;br /&gt;
            reqOnlineStatus = NULL_KEY;&lt;br /&gt;
        &lt;br /&gt;
            if (data==&amp;quot;1&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_STATUS_ONLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if (data==&amp;quot;0&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MS_STATUS_OFFLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus = llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Help V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Display help information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail Help V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP    = 10000;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Help() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Help()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;HELP for SL Mail V1.2.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;COMMANDS:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HELP               - displays help info.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@INFO               - display mailaddress of this object.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RECORD             - start recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CONTINUE           - continue recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@STOP               - stop recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@IGNORE             - ignore the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SHOW               - show what your recorded.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SEND               - send the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@MAIL &amp;lt;mailadress&amp;gt;  - set the mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SUBJECT subject    - set the mail subject.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LIST               - list messages in mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SELECT &amp;lt;message&amp;gt;   - select message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@READ               - read current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@NEXT               - read next message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@PREV               - read previous message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@FIRST              - read first message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LAST               - read last message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@DELETE             - delete current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CLEAR              - clear the mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@REPLY              - reply to current message.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RESET              - reset the script.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HOME               - set the home mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@OFF                - switch mailbox OFF.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@ON                 - switch mailbox ON.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_HELP)&lt;br /&gt;
        {&lt;br /&gt;
            Help();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail Help V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}&lt;/div&gt;</description>
			<pubDate>Fri, 09 May 2008 11:13:45 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:SL_Mail_V1.2</comments>
		</item>
		<item>
			<title>SL Mail V1.2</title>
			<link>https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=66757</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=66757</guid>
			<description>&lt;p&gt;Flennan Roffo: added &amp;lt;lsl&amp;gt; tag&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}} __NOTOC__&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=&#039;&#039;&#039;Second Life mail client&#039;&#039;&#039;=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Send and receive email from within Second Life from and to any address.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implemented with Address Book function (in a notecard named &#039;Address Book&#039;) to stores addresses by name  and to compile groups of named addresses. Current version is stand-alone (no server functionality) and uses chat commands only.&lt;br /&gt;
&lt;br /&gt;
[[Image:BannerSLMail.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.slmail.info slmail.info] (website coming soon!)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Release Notes V1.2=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 Release notes (edition 2, 4 sept 2007)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LICENCE INFO&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is released under GNU free software licence&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;PRODUCTION &amp;amp; MAINTANENCE&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
by Logic Scripted Products and Script Services&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.logicscripts.org logicscripts.org] (website coming soon!)&lt;br /&gt;
&lt;br /&gt;
SLurl:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Contact: [[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
&lt;br /&gt;
Email: [mailto:info@slmail.info &#039;&#039;&#039;info&#039;&#039;&#039;] or [mailto:Flennan.Roffo@slmail.info &#039;&#039;&#039;Flennan Roffo&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;DESCRIPTION&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is a simple tool to send and receive mail from within SL.&lt;br /&gt;
You can either compose a message yourself using chat recording, or choose a notecard from inventory to send. The Address Book functionality allows you to use short names for mail recipients stored in a notecard. The current version does not have a persisent mail address. Watch out for the upcoming next release (V1.3) which will facilitate persisent in-world mail addresses and will be enhanced with many new features (See: Requests For Change (RFC).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;COMMANDS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Help&#039;&#039;&#039;&lt;br /&gt;
||Show Help about available commands&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Record&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording (for owner only).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Stop&#039;&#039;&#039;&lt;br /&gt;
||Stops the chat recording without sending&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Continue&#039;&#039;&#039;&lt;br /&gt;
||Continues a previously stopped chat recording. Lines will be appended to you recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Show&#039;&#039;&#039;&lt;br /&gt;
||Shows the content of the recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send&#039;&#039;&#039;&lt;br /&gt;
||If recording, stops the recording, and sends the mail (need to supply mail address and subject first!)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send &amp;lt;notecard&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Sends the content of the notecard, instead of the chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Ignore&#039;&#039;&#039;&lt;br /&gt;
||Ignores your current chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject &amp;lt;subject&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the subject of the mail.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail subject.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Set the HOME address of the owner (mail will be forwarder to this address when offline).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home&#039;&#039;&#039;&lt;br /&gt;
||Show the HOME address.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Info&#039;&#039;&#039;&lt;br /&gt;
||Shows the mail address the object this script is running in uses (e.g. &amp;lt;object-key&amp;gt;@lsl.secondlife.com).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Read&#039;&#039;&#039;&lt;br /&gt;
||Reads the current message from the mail buffer (the mail buffer gets filled with mail you receive)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Select &amp;lt;msg&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Select a message number from the availabe messages in the mail buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Next&#039;&#039;&#039;&lt;br /&gt;
||Make next message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Prev&#039;&#039;&#039;&lt;br /&gt;
||Make previous message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@First&#039;&#039;&#039;&lt;br /&gt;
||Make the first message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Last&#039;&#039;&#039;&lt;br /&gt;
||Make the last message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Clear&#039;&#039;&#039;&lt;br /&gt;
||Clear the mail buffer&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Delete&#039;&#039;&#039;&lt;br /&gt;
||Deletes only the current message&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Reply&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording to reply to the current message. Mail adress and subject are filled in automatically.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* Commands are case insensitive (&amp;quot;@read&amp;quot; == &amp;quot;@READ&amp;quot;). Arguments might not be case insensitive.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;ADDRESS BOOK FORMAT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
A notecard of the name &#039;Address Book&#039; is read during initialization which may contain Address Book items and Groups.&lt;br /&gt;
The notecard is split in two sections, which need to be defined in that particular order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[ADDRESS BOOK]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Defines the section in which you can put names for mail addresses,  like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name1=account@thisdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name2=user@otherdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[GROUP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define groups of previously defined names under a new name, like for instance:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyGroup=Name1, Name2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note that names of groups and individual mail adresses share the same namespace and must be unique.&lt;br /&gt;
&lt;br /&gt;
So when you filled in your mail adresses in the Address Book, you can now use:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail Name1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to  &amp;lt;account@thisdomain.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail MyGroup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to &amp;lt;account@thisdomain.com&amp;gt; and &amp;lt;user@otherdomain.com&amp;gt;&lt;br /&gt;
Mails will be sent one after another.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* Names for Addreses and Groups are case insensitive (e.g. &amp;quot;mary&amp;quot;  == &amp;quot;MARY&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* The special address &#039;Self&#039; can be used in commands where otherwise an address specification can be used. &#039;Self&#039; is case insensitive (e.g. &amp;quot;self&amp;quot; == &amp;quot;SELF&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LIMITATIONS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
The current version is limited by the following:&lt;br /&gt;
&lt;br /&gt;
* Chat recording lines are limited by the 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Output of lines from the mail buffer are also limited by this 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Incoming mail is limited to a 1000 (1024?) byte limit&lt;br /&gt;
&lt;br /&gt;
* Outgoing mai is limited by a 4096 byte limit, which includes the standard mail header (region/location info on the first two lines)&lt;br /&gt;
&lt;br /&gt;
We are making adjustments to this release to help overcome these limitations. At least the line lenght limit can be overcome by introducing a line continuation character (for example a hyphen &#039;-&#039;) that when used at the end of a line appends the next line, so lines longer then 255 bytes are possible then.&lt;br /&gt;
&lt;br /&gt;
To overcome the outgoing mail length limit, the mail can be broken textualy into parts, and each part can be send seperatedely, with an indication in the subject or in an introduced primary line of the mail body to indicate that the mail was split into parts.&lt;br /&gt;
For incoming mail and at least to receive mail from other SL Mail programs, a protocol will be introduced to receive mail in parts that are joined together after receiving them to form a single mail.&lt;br /&gt;
&lt;br /&gt;
These enhancements will be made available in the next release (V1.3) of SL Mail &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;BUGS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Report any bugs you find in this release to Logic (IM: Flennan Roffo).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;REQUEST FOR CHANGE (RFC)&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Do you have additional wishes for enhancement of this product?&lt;br /&gt;
Contact Flennan Roffo and we will see if they can be implemented in the next release.&lt;br /&gt;
&lt;br /&gt;
Existing RFC&#039;s are:&lt;br /&gt;
&lt;br /&gt;
* Menu support for commands.&lt;br /&gt;
&lt;br /&gt;
* Lines on incoming/outgoing mail longer than 255 bytes.&lt;br /&gt;
&lt;br /&gt;
* Send messages longer than 4096 (minus SL mail header) bytes.&lt;br /&gt;
&lt;br /&gt;
* Receive messages longer than 1024 bytes.&lt;br /&gt;
&lt;br /&gt;
* Permanent mail addresses for the SL Mail client (like: &amp;lt;Flennan.Roffo@somedomain.sl&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Add your RFC!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In-world join the group &amp;quot;SL Mail&amp;quot; for bug reports, feature requests, the latest SL Mail release, and notices about development issues.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scripts=&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==Script: SL Mail v1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail core module which scans for incoming mail messages and executes commands used by the owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail V1.2.lsl&lt;br /&gt;
// (c) 2007 Logic Scripted Products and Script Services&lt;br /&gt;
// Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
// VERSION&lt;br /&gt;
// Version: 1.2&lt;br /&gt;
&lt;br /&gt;
// HISTORY&lt;br /&gt;
// Date         Version     Author              Comment&lt;br /&gt;
// --------------------------------------------------------------------------------------&lt;br /&gt;
// 28 aug 2007  V 1.0       Flennan Roffo       Created&lt;br /&gt;
//&lt;br /&gt;
//  1 sep 2007  V 1.1       Flennan Roffo       @Reply empties the recording buffer.&lt;br /&gt;
//                                                @Send while recording ends recording&lt;br /&gt;
//                                                and sends the mail if a mail address&lt;br /&gt;
//                                                and subject are supplied.&lt;br /&gt;
//                                                Fixed incorrect date in Unix2DateTime.&lt;br /&gt;
//  3 sep 2007  V 1.2       Flennan Roffo       Notification options:&lt;br /&gt;
//                                              - When online, send an IM when mail is received.&lt;br /&gt;
//                                              - When offline, send to HOME mail adress.&lt;br /&gt;
//                                              Adressbook&lt;br /&gt;
//                                              - Read adress book from config notecard.&lt;br /&gt;
&lt;br /&gt;
// LICENCE&lt;br /&gt;
// This program is free software; you can redistribute it and/or&lt;br /&gt;
// modify it under the terms of the GNU General Public License&lt;br /&gt;
// as published by the Free Software Foundation; either version 2&lt;br /&gt;
// of the License, or (at your option) any later version.&lt;br /&gt;
// &lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
// &lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program; if not, write to the Free Software&lt;br /&gt;
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
// (Also available at http://www.gnu.org/copyleft/gpl.html) &lt;br /&gt;
&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// Let&#039;s you record a message and sent to email and get messages and reply to messages.&lt;br /&gt;
// Must supply a valid mail adress and non-empty subject using chat commands.&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
// 1) Check for the maximum length of an email message (including newline and header).&lt;br /&gt;
// 2) Read adress book from notecard.                                    *DONE*&lt;br /&gt;
// 3) Send incoming mail to personal mail adress when offline.            *DONE*&lt;br /&gt;
// 4) Alert with an IM when online upon receiving new mail.                *DONE*&lt;br /&gt;
&lt;br /&gt;
string   SL_MAIL_VERSION = &amp;quot;V 1.2&amp;quot;;&lt;br /&gt;
string   SL_MAIL_DATE    = &amp;quot; 2 sep 2007&amp;quot;;&lt;br /&gt;
integer  ErrorFlag         = FALSE;&lt;br /&gt;
list     ScriptList        = [ &amp;quot;SL Mail Help V1.2&amp;quot;, &amp;quot;SL Mail AddressBook V1.2&amp;quot;, &lt;br /&gt;
                                &amp;quot;SL Mail OnlineStatus V1.2&amp;quot;, &amp;quot;SL Mail FetchNotecard V1.2&amp;quot; ];    &lt;br /&gt;
string   LSL_DOMAIN=&amp;quot;lsl.secondlife.com&amp;quot;; &lt;br /&gt;
integer  StatusOnline=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Commands&lt;br /&gt;
&lt;br /&gt;
string  COMMAND_RECORD     = &amp;quot;@RECORD&amp;quot;;&lt;br /&gt;
string  COMMAND_CONTINUE   = &amp;quot;@CONTINUE&amp;quot;;&lt;br /&gt;
string  COMMAND_STOP       = &amp;quot;@STOP&amp;quot;;&lt;br /&gt;
string  COMMAND_MAIL       = &amp;quot;@MAIL&amp;quot;;&lt;br /&gt;
string  COMMAND_SUBJECT    = &amp;quot;@SUBJECT&amp;quot;;&lt;br /&gt;
string  COMMAND_SEND       = &amp;quot;@SEND&amp;quot;;&lt;br /&gt;
string  COMMAND_SEE        = &amp;quot;@SEE&amp;quot;;&lt;br /&gt;
string  COMMAND_IGNORE     = &amp;quot;@IGNORE&amp;quot;;&lt;br /&gt;
string  COMMAND_READ       = &amp;quot;@READ&amp;quot;;&lt;br /&gt;
string  COMMAND_DELETE     = &amp;quot;@DELETE&amp;quot;;&lt;br /&gt;
string  COMMAND_CLEAR      = &amp;quot;@CLEAR&amp;quot;;&lt;br /&gt;
string  COMMAND_REPLY      = &amp;quot;@REPLY&amp;quot;;&lt;br /&gt;
string  COMMAND_NEXT       = &amp;quot;@NEXT&amp;quot;;&lt;br /&gt;
string  COMMAND_PREV       = &amp;quot;@PREV&amp;quot;;&lt;br /&gt;
string  COMMAND_FIRST      = &amp;quot;@FIRST&amp;quot;;&lt;br /&gt;
string  COMMAND_LAST       = &amp;quot;@LAST&amp;quot;;&lt;br /&gt;
string  COMMAND_LIST       = &amp;quot;@LIST&amp;quot;;&lt;br /&gt;
string  COMMAND_SELECT     = &amp;quot;@SELECT&amp;quot;;&lt;br /&gt;
string  COMMAND_HELP       = &amp;quot;@HELP&amp;quot;;&lt;br /&gt;
string  COMMAND_INFO       = &amp;quot;@INFO&amp;quot;;&lt;br /&gt;
string  COMMAND_RESET      = &amp;quot;@RESET&amp;quot;;&lt;br /&gt;
string  COMMAND_SHOW       = &amp;quot;@SHOW&amp;quot;;&lt;br /&gt;
string  COMMAND_ON         = &amp;quot;@ON&amp;quot;;&lt;br /&gt;
string  COMMAND_OFF        = &amp;quot;@OFF&amp;quot;;&lt;br /&gt;
string  COMMAND_HOME       = &amp;quot;@HOME&amp;quot;;&lt;br /&gt;
string  COMMAND_LOAD       = &amp;quot;@LOAD&amp;quot;;&lt;br /&gt;
string  COMMAND_ADDRESS    = &amp;quot;@ADDRESS&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Recording&lt;br /&gt;
&lt;br /&gt;
integer Recording = FALSE;&lt;br /&gt;
&lt;br /&gt;
list    ChatRecording=[];&lt;br /&gt;
integer NumLines=0;&lt;br /&gt;
integer Length=0;&lt;br /&gt;
&lt;br /&gt;
list     TimeList=[];&lt;br /&gt;
list     AddressList=[];&lt;br /&gt;
list     SubjectList=[];&lt;br /&gt;
list     BodyList=[];&lt;br /&gt;
integer  NumMessages=0;&lt;br /&gt;
integer  CurrentMessage=-1;&lt;br /&gt;
&lt;br /&gt;
float    MAIL_FETCH_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
// Link Messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP                        = 10000;&lt;br /&gt;
integer MSG_STATUS_ONLINE               = 30000;&lt;br /&gt;
integer MSG_STATUS_OFFLINE              = 30100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED          = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR           = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Unix Time conversion //////////////////&lt;br /&gt;
&lt;br /&gt;
integer DAYS_PER_YEAR        = 365;                // Non leap year&lt;br /&gt;
integer SECONDS_PER_YEAR     = 31536000;          // Non leap year&lt;br /&gt;
integer SECONDS_PER_DAY      = 86400;&lt;br /&gt;
integer SECONDS_PER_HOUR     = 3600;&lt;br /&gt;
integer SECONDS_PER_MINUTE   = 60;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// LeapYear() /////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer LeapYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (year % 4 == 0)&lt;br /&gt;
    {&lt;br /&gt;
        if (year % 100 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (year % 400 == 0)&lt;br /&gt;
            {&lt;br /&gt;
                return 1;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// DaysPerMonth() ///////////////////////////////////////&lt;br /&gt;
                &lt;br /&gt;
integer DaysPerMonth(integer year,integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;lt; 8)&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (month == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if (LeapYear(year))&lt;br /&gt;
                {&lt;br /&gt;
                    return 29;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    return 28;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 30;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 30;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////// DaysPerYear() ////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DaysPerYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (LeapYear(year))&lt;br /&gt;
        return DAYS_PER_YEAR + 1;&lt;br /&gt;
    else&lt;br /&gt;
        return DAYS_PER_YEAR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Unix2DataTime() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list Unix2DateTime(integer unixtime)&lt;br /&gt;
{&lt;br /&gt;
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;&lt;br /&gt;
    integer day = days_since_1_1_1970 + 1;&lt;br /&gt;
    integer year  = 1970;&lt;br /&gt;
    integer days_per_year = DaysPerYear(year);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_year)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_year;&lt;br /&gt;
        ++year;&lt;br /&gt;
        days_per_year = DaysPerYear(year);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer month = 1;&lt;br /&gt;
    integer days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_month)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_month;&lt;br /&gt;
        &lt;br /&gt;
        if (++month &amp;gt; 12)&lt;br /&gt;
        {    &lt;br /&gt;
            ++year;&lt;br /&gt;
            month = 1;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;&lt;br /&gt;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;&lt;br /&gt;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;&lt;br /&gt;
    integer minute      = second / SECONDS_PER_MINUTE;&lt;br /&gt;
    second               = second % SECONDS_PER_MINUTE;&lt;br /&gt;
    &lt;br /&gt;
    return [ year, month, day, hour, minute, second ];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// MonthName() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list MonthNameList = [     &amp;quot;JAN&amp;quot;, &amp;quot;FEB&amp;quot;, &amp;quot;MAR&amp;quot;, &amp;quot;APR&amp;quot;, &amp;quot;MAY&amp;quot;, &amp;quot;JUN&amp;quot;, &lt;br /&gt;
                        &amp;quot;JUL&amp;quot;, &amp;quot;AUG&amp;quot;, &amp;quot;SEP&amp;quot;, &amp;quot;OCT&amp;quot; , &amp;quot;NOV&amp;quot;, &amp;quot;DEC&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
string MonthName(integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;gt;= 0 &amp;amp;&amp;amp; month &amp;lt; 12)&lt;br /&gt;
        return llList2String(MonthNameList, month);&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// DateString() ///////////////////////////&lt;br /&gt;
&lt;br /&gt;
string DateString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer year       = llList2Integer(timelist,0);&lt;br /&gt;
    integer month      = llList2Integer(timelist,1);&lt;br /&gt;
    integer day        = llList2Integer(timelist,2);&lt;br /&gt;
    &lt;br /&gt;
    return (string)day + &amp;quot;-&amp;quot; + MonthName(month - 1) + &amp;quot;-&amp;quot; + (string)year;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// TimeString() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string TimeString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer hour          = llList2Integer(timelist,3);&lt;br /&gt;
    integer minute         = llList2Integer(timelist,4);&lt;br /&gt;
    integer second         = llList2Integer(timelist,5);&lt;br /&gt;
    string  hourstr     = (string)hour;&lt;br /&gt;
    string  minutestr   = (string)minute;&lt;br /&gt;
    string  secondstr   = (string)second;&lt;br /&gt;
    &lt;br /&gt;
    if (hour &amp;lt; 10)         hourstr     = &amp;quot;0&amp;quot; + hourstr;&lt;br /&gt;
    if (minute &amp;lt; 10)     minutestr     = &amp;quot;0&amp;quot; + minutestr;&lt;br /&gt;
    if (second &amp;lt; 10)    secondstr    = &amp;quot;0&amp;quot; + secondstr;&lt;br /&gt;
    return hourstr + &amp;quot;:&amp;quot; + minutestr + &amp;quot;:&amp;quot; + secondstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() /////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string body)&lt;br /&gt;
{&lt;br /&gt;
    // llOwnerSay(&amp;quot;Sending message to &#039;&amp;quot; + address + &amp;quot;&#039; with subject &#039;&amp;quot; + subject +&amp;quot;&#039;.&amp;quot;);&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND, body, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// SendHome() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendHome(string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SENDHOME, body, (key)subject);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Show() ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Show()&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;Current chat recording is:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; NumLines; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(ChatRecording,i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;Lines is &amp;quot; + (string)NumLines);&lt;br /&gt;
    llOwnerSay(&amp;quot;Message length is &amp;quot; + (string)Length);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Read() /////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Read()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;Reading message &amp;quot; + (string)CurrentMessage + &amp;quot; from mail buffer.&amp;quot;);&lt;br /&gt;
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);&lt;br /&gt;
    list timelist=Unix2DateTime(time);&lt;br /&gt;
    string Address = llList2String(AddressList,CurrentMessage);&lt;br /&gt;
    string Subject = llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
    string Body    = llList2String(BodyList,CurrentMessage);&lt;br /&gt;
    llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Address: &amp;quot; + Address);&lt;br /&gt;
    llOwnerSay(&amp;quot;Subject: &amp;quot; + Subject);&lt;br /&gt;
    llOwnerSay(&amp;quot;Begin of message body:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    list bodylist=llParseStringKeepNulls(Body, [ &amp;quot;\n&amp;quot; ], []);&lt;br /&gt;
    integer num=llGetListLength(bodylist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(bodylist,i));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;End of message body.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////// List ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
List()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;The mail buffer contains the following messages:\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; NumMessages; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer time=llList2Integer(TimeList,i);&lt;br /&gt;
        list timelist=Unix2DateTime(time);&lt;br /&gt;
        if (i &amp;gt; 0) llOwnerSay(&amp;quot;+-+-+-+-+-+-+-+-+-+-+-+-&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Message: &amp;quot; + (string)i);&lt;br /&gt;
        llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;From:    &amp;quot; + llList2String(AddressList,i));&lt;br /&gt;
        llOwnerSay(&amp;quot;Subject: &amp;quot; + llList2String(SubjectList,i));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////// NotifyNewMail() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
NotifyNewMail(string time, string address, string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    list timelist=Unix2DateTime((integer)time);&lt;br /&gt;
&lt;br /&gt;
    if (StatusOnline)&lt;br /&gt;
    {&lt;br /&gt;
        llInstantMessage(llGetOwner(), &amp;quot;You received a new mail message on &amp;quot; &lt;br /&gt;
                                    + DateString(timelist) + &amp;quot; at &amp;quot; + TimeString(timelist)&lt;br /&gt;
                                    + &amp;quot; from &amp;quot; + address &lt;br /&gt;
                                    + &amp;quot; with the subject &amp;quot; + subject);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        SendHome(&amp;quot;FW: &amp;quot; + subject, &amp;quot;Received at: &amp;quot; + DateString(timelist) + &amp;quot; &amp;quot; + TimeString(timelist) + &amp;quot;\nFrom: &amp;quot; +  address &lt;br /&gt;
                    + &amp;quot;\nBegin message body:\n-------------------\n&amp;quot; + body + &amp;quot;\n-------------------\nEnd message body.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ResetOtherScripts() //////////////////////&lt;br /&gt;
&lt;br /&gt;
ResetOtherScripts()&lt;br /&gt;
{&lt;br /&gt;
    string     name;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(ScriptList);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        name = llList2String(ScriptList,i);&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(name) == INVENTORY_SCRIPT)&lt;br /&gt;
        {&lt;br /&gt;
            llResetOtherScript(name);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Error - script &#039;&amp;quot; + name + &amp;quot;&#039; not found.&amp;quot;);&lt;br /&gt;
            ErrorFlag = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
// default &lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ////////////////////// state_entry() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Welcome to SL Mail, released under GNU software licence.&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Version &amp;quot; + SL_MAIL_VERSION + &amp;quot; &amp;quot; + SL_MAIL_DATE);&lt;br /&gt;
        llOwnerSay(&amp;quot;Produced by Logic Scripted Products &amp;amp; Product Services&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Free memory: &amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
        ResetOtherScripts();&lt;br /&gt;
        &lt;br /&gt;
        if (ErrorFlag)&lt;br /&gt;
            state Error;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// on_rez() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// changed() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_LOADED)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_ERROR)&lt;br /&gt;
        {&lt;br /&gt;
            state Error;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() //////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(MAIL_FETCH_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //////////////////////// on_rez() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// listen() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string trimmessage=llStringTrim(message,STRING_TRIM);&lt;br /&gt;
        list   parse = llParseStringKeepNulls(trimmessage, [ &amp;quot; &amp;quot;], []);&lt;br /&gt;
        string command = llToUpper(llList2String(parse,0));&lt;br /&gt;
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        integer nargs  = llGetListLength(parse);&lt;br /&gt;
        string argstr=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (nargs &amp;gt; 1) argstr=llGetSubString(message, llSubStringIndex(message, &amp;quot; &amp;quot;) + 1, -1);&lt;br /&gt;
            &lt;br /&gt;
        if (Recording)&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Recording stopped. Type @SHOW to see the message you have entered,&amp;quot;&lt;br /&gt;
                            + &amp;quot; or @SEND to send it.&amp;quot;);&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                &lt;br /&gt;
                SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];&lt;br /&gt;
                ++NumLines;&lt;br /&gt;
                Length += llStringLength(message) + 2;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_RECORD)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Start recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                ChatRecording = [];&lt;br /&gt;
                NumLines=0;&lt;br /&gt;
                Length=0;&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CONTINUE)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Continue recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_REPLY)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    string address=llList2String(AddressList,CurrentMessage);&lt;br /&gt;
                    string subject=&amp;quot;Re: &amp;quot; + llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, address, NULL_KEY);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, subject, NULL_KEY);&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines=0;&lt;br /&gt;
                    Length=0;&lt;br /&gt;
                    Recording = TRUE;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_MAIL)&lt;br /&gt;
            {&lt;br /&gt;
                string mailaddress=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailaddress != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, mailaddress, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETADDRESS, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SUBJECT)&lt;br /&gt;
            {&lt;br /&gt;
                string mailsubject=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailsubject != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, mailsubject, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETSUBJECT, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Not recording.&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    if (NumLines == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND_NOTECARD, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_IGNORE)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines = 0;&lt;br /&gt;
                    Length = 0;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Show();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_READ)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumMessages == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Read();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        ++CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        --CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_FIRST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = 0;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LAST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LIST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    List();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SELECT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;Need to supply a message number.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    integer msgnum = (integer)arg;&lt;br /&gt;
                     &lt;br /&gt;
                    if (msgnum &amp;lt; 0 || msgnum &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Message number &amp;quot; + arg + &amp;quot; not in mail buffer.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = msgnum;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_DELETE)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    --NumMessages;&lt;br /&gt;
                     &lt;br /&gt;
                    if (NumMessages == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = -1;&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (CurrentMessage &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CLEAR)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList=[];&lt;br /&gt;
                    AddressList=[];&lt;br /&gt;
                    SubjectList=[];&lt;br /&gt;
                    BodyList=[];&lt;br /&gt;
                    NumMessages=0;&lt;br /&gt;
                    CurrentMessage=-1;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_HELP, arg, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_INFO)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                Show();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_RESET)&lt;br /&gt;
            {&lt;br /&gt;
                llResetScript();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                state not_running;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HOME)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs==1)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETHOME, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETHOME, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// email() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    email(string time, string address, string subject, string body, integer queued)&lt;br /&gt;
    {&lt;br /&gt;
        NotifyNewMail(time, address, subject, body);&lt;br /&gt;
        TimeList = (TimeList=[]) + TimeList + [time];&lt;br /&gt;
        AddressList = (AddressList=[]) + AddressList + [address];&lt;br /&gt;
        SubjectList = (SubjectList=[]) + SubjectList + [subject];&lt;br /&gt;
        BodyList = (BodyList=[]) + BodyList + [body];&lt;br /&gt;
        ++NumMessages;&lt;br /&gt;
        &lt;br /&gt;
        if (CurrentMessage == -1)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = NumMessages - 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_REPLY)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state not_running&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state not_running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;SL Mailbox switched OFF. Say @ON to switch it back on.&amp;quot;);&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// on_rez() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// listen() ////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer chan, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string command=llToUpper(message);&lt;br /&gt;
        &lt;br /&gt;
        if (command == COMMAND_ON)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state Error&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state Error&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Error in SL Mail: not all component scripts found.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// End SL Mail V1.2.lsl&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Address Book V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Read and interpret the contents of the Address Book.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail AddressBook V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// &lt;br /&gt;
//  Read the Address Book from a notecard named &amp;quot;Address Book&amp;quot;.&lt;br /&gt;
//&lt;br /&gt;
//  The Address Book has the following format:&lt;br /&gt;
//  &lt;br /&gt;
//  [ADDRESS BOOK]&lt;br /&gt;
//  Name1=username@yourdomain.com&lt;br /&gt;
//  Name2=otheruser@otherdomain.com&lt;br /&gt;
//  ...&lt;br /&gt;
//  [GROUP]&lt;br /&gt;
//  group1=Name1, Name2&lt;br /&gt;
//  ...&lt;br /&gt;
//&lt;br /&gt;
//  Notes:&lt;br /&gt;
//  1. Group and Name share the same namespace, and must be unique.&lt;br /&gt;
//  2. It is allowed to have a name in the addressbook with multiple addresses, seperated by comma&#039;s.&lt;br /&gt;
// &lt;br /&gt;
/////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string  CurrentMailAddress = &amp;quot;&amp;quot;;&lt;br /&gt;
string  CurrentMailSubject = &amp;quot;&amp;quot;;&lt;br /&gt;
integer StatusOnline = FALSE;&lt;br /&gt;
&lt;br /&gt;
// Fetch or Send notecard&lt;br /&gt;
&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Names&lt;br /&gt;
&lt;br /&gt;
list    AddressBookList=[];&lt;br /&gt;
list    MailAddressList=[];&lt;br /&gt;
&lt;br /&gt;
string  STRING_HOME=&amp;quot;HOME&amp;quot;;&lt;br /&gt;
string  STRING_SELF=&amp;quot;SELF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Groups&lt;br /&gt;
&lt;br /&gt;
list   GroupList=[];&lt;br /&gt;
list   GroupNameList=[];&lt;br /&gt;
&lt;br /&gt;
string LSL_DOMAIN = &amp;quot;lsl.secondlife.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Read Address Book notecard&lt;br /&gt;
&lt;br /&gt;
string  ADDRESSBOOK_NOTECARD=&amp;quot;Address Book&amp;quot;;&lt;br /&gt;
integer Line=0;&lt;br /&gt;
key     reqAddressBook=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
integer Section=0;&lt;br /&gt;
integer SECTION_ADDRESS_BOOK=1;&lt;br /&gt;
integer SECTION_GROUP=2;&lt;br /&gt;
string  STRING_ADDRESS_BOOK=&amp;quot;ADDRESS BOOK&amp;quot;;&lt;br /&gt;
string  STRING_GROUP=&amp;quot;GROUP&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Links messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
integer MSG_MESSAGE_NOTIFY              = 90900;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED            = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR            = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// GetSelfAddress() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
string GetSelfAddress()&lt;br /&gt;
{&lt;br /&gt;
    return (string)llGetKey() + &amp;quot;@&amp;quot; + LSL_DOMAIN;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Info() /////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Info()&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;The mail address for this object is: &amp;quot; &lt;br /&gt;
                    + GetSelfAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// IsValidKeyFormat() //////////////////////&lt;br /&gt;
&lt;br /&gt;
integer IsValidKeyFormat(string str)&lt;br /&gt;
{&lt;br /&gt;
    string keychars = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    if (llStringLength(str) != 36)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    if( (llGetSubString( str, 8, 8 )   != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 13, 13 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 18, 18 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 23, 23 )  != &amp;quot;-&amp;quot; ) )&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 9; i &amp;lt; 13; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 14; i &amp;lt; 18; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 19; i &amp;lt; 23; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 24; i &amp;lt; 36; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// ValidMailAddress() ////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer ValidMailAddress(string arg)&lt;br /&gt;
{&lt;br /&gt;
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));&lt;br /&gt;
    &lt;br /&gt;
    if (adress == &amp;quot;&amp;quot;)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    list parse = llParseStringKeepNulls(adress, [ &amp;quot;@&amp;quot; ], []);&lt;br /&gt;
    string account = llList2String(parse,0);&lt;br /&gt;
    string domain  = llList2String(parse,1);&lt;br /&gt;
    &lt;br /&gt;
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    &lt;br /&gt;
    if (domain == LSL_DOMAIN)&lt;br /&gt;
    {&lt;br /&gt;
        return IsValidKeyFormat(account);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list parsedomain = llParseString2List(domain, [ &amp;quot;.&amp;quot; ], []);&lt;br /&gt;
    &lt;br /&gt;
        if (llGetListLength(parsedomain) &amp;lt; 2)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        &lt;br /&gt;
        integer num = llGetListLength(parsedomain);&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llStringLength(llList2String(parsedomain,i)) &amp;lt; 2)&lt;br /&gt;
            {&lt;br /&gt;
                return FALSE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetAddressStr() ///////////////////&lt;br /&gt;
&lt;br /&gt;
string GetAndCheckAddressStr(string address)&lt;br /&gt;
{&lt;br /&gt;
    list addresslist = llCSV2List(address);&lt;br /&gt;
    integer num=llGetListLength(addresslist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    string addressstr=&amp;quot;&amp;quot;;&lt;br /&gt;
    string curaddress=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        curaddress=llList2String(addresslist,i);&lt;br /&gt;
        &lt;br /&gt;
        if (ValidMailAddress(curaddress))&lt;br /&gt;
        {&lt;br /&gt;
            addressstr = (addressstr=&amp;quot;&amp;quot;) + addressstr + curaddress + &amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address string: &#039;&amp;quot; &lt;br /&gt;
                            + curaddress + &amp;quot;&#039;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return llGetSubString(addressstr, 0, -2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ProcessLine() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
ProcessLine(string rawline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(rawline,STRING_TRIM);&lt;br /&gt;
    string first=llGetSubString(line,0,0);&lt;br /&gt;
    string last=llGetSubString(line,-1,-1);&lt;br /&gt;
    &lt;br /&gt;
    // Ignore a blank line or comment line&lt;br /&gt;
    if (line == &amp;quot;&amp;quot; || first == &amp;quot;#&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // Check for the right section&lt;br /&gt;
    &lt;br /&gt;
    if (first == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; last == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        string sectionstr=llToUpper(llStringTrim(llGetSubString(line,1,-2),STRING_TRIM));&lt;br /&gt;
        &lt;br /&gt;
        if (sectionstr == STRING_ADDRESS_BOOK)&lt;br /&gt;
        {&lt;br /&gt;
            Section = SECTION_ADDRESS_BOOK;&lt;br /&gt;
        }&lt;br /&gt;
        else if (sectionstr == STRING_GROUP)&lt;br /&gt;
        {&lt;br /&gt;
            if (Section == 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                        + &amp;quot;. Group section defined before Address Book section.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Section = SECTION_GROUP;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid section header &#039;&amp;quot; + sectionstr &lt;br /&gt;
                        + &amp;quot;&#039; in &amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Must be in a section&lt;br /&gt;
    &lt;br /&gt;
    if (Section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;. No section header.&amp;quot;, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    list     parse=llParseString2List(line, [ &amp;quot;=&amp;quot; ], []);&lt;br /&gt;
    integer  num=llGetListLength(parse);&lt;br /&gt;
    &lt;br /&gt;
    // Format must be correct&lt;br /&gt;
    &lt;br /&gt;
    if (num != 2)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; +  (string)(Line+1) + &amp;quot;:\n&amp;quot; + rawline, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (Section == SECTION_ADDRESS_BOOK)&lt;br /&gt;
    {&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(name) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + name &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ name ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            string address=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
            string addressstr=GetAndCheckAddressStr(address);&lt;br /&gt;
            &lt;br /&gt;
            if (addressstr != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                AddressBookList     = (AddressBookList=[])     + AddressBookList     + [ name ];&lt;br /&gt;
                MailAddressList     = (MailAddressList=[])     + MailAddressList     + [ addressstr ];&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;No valid mail address for &#039;&amp;quot; + name &lt;br /&gt;
                    + &amp;quot;&#039;. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                    + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name &lt;br /&gt;
                + &amp;quot;&#039; already defined. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // Group&lt;br /&gt;
    {&lt;br /&gt;
        string group=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(group) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + group &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ group ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(GroupList, [ group ]) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                string names=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
                list   namelist=llCSV2List(names);&lt;br /&gt;
                integer num=llGetListLength(namelist);&lt;br /&gt;
                integer i;&lt;br /&gt;
                integer index;&lt;br /&gt;
                string  name;&lt;br /&gt;
                string  namestr=&amp;quot;&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
                for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                    name=llList2String(namelist,i);&lt;br /&gt;
                    index=llListFindList(AddressBookList, [ name ]);&lt;br /&gt;
            &lt;br /&gt;
                    if (index == -1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name + &amp;quot;&#039; defined in Group &#039;&amp;quot; &lt;br /&gt;
                                + group + &amp;quot;&#039; not found in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY); &lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        namestr = (namestr=&amp;quot;&amp;quot;) + namestr + name + &amp;quot;,&amp;quot;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (namestr != &amp;quot;&amp;quot;)&lt;br /&gt;
                {    &lt;br /&gt;
                    namestr=llGetSubString(namestr,0,-2);&lt;br /&gt;
                    GroupList         = (GroupList=[])         + GroupList     + [ group ];&lt;br /&gt;
                    GroupNameList     = (GroupNameList=[])    + GroupNameList + [ namestr ];&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                        + &amp;quot;&#039; has no valid names. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                        + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                    + &amp;quot;&#039; already defined in Group. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                    + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group&lt;br /&gt;
                + &amp;quot;&#039; already defined in Address Book. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// GetGroupAddressList ///////////////&lt;br /&gt;
&lt;br /&gt;
string GetGroupAddressList(string group)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(GroupList, [ group ]);&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(GroupList);&lt;br /&gt;
    string  grouplist=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        for (i = index; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2String(GroupList,i) == group)&lt;br /&gt;
            {&lt;br /&gt;
                grouplist = (grouplist=&amp;quot;&amp;quot;) + grouplist + llList2String(GroupNameList,i) + &amp;quot;,&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (grouplist != &amp;quot;&amp;quot;) grouplist=llGetSubString(grouplist,0,-2);   // remove last &amp;quot;,&amp;quot;&lt;br /&gt;
        return grouplist;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// SetMailAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetMailAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ address ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        index=llListFindList(GroupList, [ address ]);&lt;br /&gt;
        &lt;br /&gt;
        if (index == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llToUpper(address) == STRING_SELF)&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = GetSelfAddress();&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if(ValidMailAddress(address))&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = address;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Mail adress &amp;quot; + address &lt;br /&gt;
                            + &amp;quot; : not found in adress book or invalid format.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailAddress = GetGroupAddressList(address);&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        CurrentMailAddress = llList2String(MailAddressList,index);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                        + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string message)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No mail address defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No subject defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list mailaddresslist=llCSV2List(CurrentMailAddress);&lt;br /&gt;
        integer num=llGetListLength(mailaddresslist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(mailaddresslist,i);&lt;br /&gt;
            llEmail(address, CurrentMailSubject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMailHome() ////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMailHome(string message, string subject)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, STRING_HOME &lt;br /&gt;
                + &amp;quot; not set. Set your home adress with @HOME &amp;lt;address&amp;gt;.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        string homeaddress=llList2String(AddressBookList,index);&lt;br /&gt;
        list   homelist=llCSV2List(homeaddress);&lt;br /&gt;
        integer num=llGetListLength(homelist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(homelist,i);&lt;br /&gt;
            llEmail(address, subject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
string GetHomeAddress()&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;not set&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2String(MailAddressList,index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetHomeAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        AddressBookList     = (AddressBookList=[]) + [ STRING_HOME ] + AddressBookList;&lt;br /&gt;
        MailAddressList     = (MailAddressList=[]) + [ GetAndCheckAddressStr(address) ]  + MailAddressList;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MailAddressList = llListReplaceList(MailAddressList, [ GetAndCheckAddressStr(address) ], index, index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        Line=0;&lt;br /&gt;
        Section=0;&lt;br /&gt;
        llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// dataserver() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqAddressBook)&lt;br /&gt;
        {&lt;br /&gt;
            reqAddressBook = NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                ProcessLine(data);&lt;br /&gt;
                reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Address Book loaded.&amp;quot;, NULL_KEY);&lt;br /&gt;
                state running;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// timer() ///////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_ERROR, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Could not read Address Book: &amp;quot; &lt;br /&gt;
                            + ADDRESSBOOK_NOTECARD + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// link_message() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_MESSAGE_GETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is empty.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailSubject = message;&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is empty.&amp;quot;, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            SetMailAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Body of message to send is empty. &amp;quot; &lt;br /&gt;
                                +  &amp;quot;No mail is send.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SENDHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SendMailHome(message, (string)id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetInventoryType(message) == INVENTORY_NOTECARD)&lt;br /&gt;
            {&lt;br /&gt;
                Notecard2Fetch = message;                &lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_READ, message, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + message + &amp;quot; not found.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_NOTECARD_FETCHED)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + Notecard2Fetch &lt;br /&gt;
                            + &amp;quot; was empty or could not be read.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Home address is: &amp;quot; + GetHomeAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SetHomeAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_INFO)&lt;br /&gt;
        {&lt;br /&gt;
            Info();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
// End SL Mail AddressBook V1.2.lsl&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail FetchNotecard V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch the contents of a notecard and return it via link message as a string.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Notecard&lt;br /&gt;
&lt;br /&gt;
integer Line=0;&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
key     reqNotecard=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=10.0;&lt;br /&gt;
integer Fetched=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Lines&lt;br /&gt;
&lt;br /&gt;
list LineList=[];&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    /////////////////////// dataserver() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqNotecard)&lt;br /&gt;
        {&lt;br /&gt;
            reqNotecard=NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                LineList = (LineList=[]) + LineList + [ data ];&lt;br /&gt;
                reqNotecard = llGetNotecardLine(Notecard2Fetch, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Fetched=TRUE;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, llDumpList2String(LineList, &amp;quot;\n&amp;quot;), NULL_KEY);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /////////////////////// timer() ///////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        if (!Fetched)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            llSetTimerEvent(0.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer send, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_NOTECARD_READ)&lt;br /&gt;
        {&lt;br /&gt;
            Line=0;&lt;br /&gt;
            Notecard2Fetch=message;&lt;br /&gt;
            LineList=[];&lt;br /&gt;
            Fetched=FALSE;&lt;br /&gt;
            reqNotecard=llGetNotecardLine(Notecard2Fetch, Line);&lt;br /&gt;
            llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL OnlineStatus V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch online status of owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Online status&lt;br /&gt;
&lt;br /&gt;
key     reqOnlineStatus=NULL_KEY;&lt;br /&gt;
float   STATUS_INTERVAL=2.0;&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_STATUS_ONLINE       = 30000;&lt;br /&gt;
integer MS_STATUS_OFFLINE       = 30100;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus=llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
        llSetTimerEvent(STATUS_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// dataserver() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqOnlineStatus)&lt;br /&gt;
        {&lt;br /&gt;
            reqOnlineStatus = NULL_KEY;&lt;br /&gt;
        &lt;br /&gt;
            if (data==&amp;quot;1&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_STATUS_ONLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if (data==&amp;quot;0&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MS_STATUS_OFFLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus = llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Help V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Display help information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// SL Mail Help V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP    = 10000;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Help() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Help()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;HELP for SL Mail V1.2.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;COMMANDS:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HELP               - displays help info.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@INFO               - display mailaddress of this object.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RECORD             - start recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CONTINUE           - continue recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@STOP               - stop recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@IGNORE             - ignore the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SHOW               - show what your recorded.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SEND               - send the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@MAIL &amp;lt;mailadress&amp;gt;  - set the mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SUBJECT subject    - set the mail subject.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LIST               - list messages in mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SELECT &amp;lt;message&amp;gt;   - select message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@READ               - read current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@NEXT               - read next message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@PREV               - read previous message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@FIRST              - read first message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LAST               - read last message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@DELETE             - delete current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CLEAR              - clear the mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@REPLY              - reply to current message.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RESET              - reset the script.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HOME               - set the home mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@OFF                - switch mailbox OFF.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@ON                 - switch mailbox ON.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_HELP)&lt;br /&gt;
        {&lt;br /&gt;
            Help();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail Help V1.2.lsl&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}&lt;/div&gt;</description>
			<pubDate>Fri, 09 May 2008 11:10:08 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:SL_Mail_V1.2</comments>
		</item>
		<item>
			<title>User:Flennan Roffo</title>
			<link>https://wiki.secondlife.com/w/index.php?title=User:Flennan_Roffo&amp;diff=35078</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=User:Flennan_Roffo&amp;diff=35078</guid>
			<description>&lt;p&gt;Flennan Roffo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
=About Flennan Roffo=&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
||[[Image:FlennanRoffo80x80.jpg|frameless|100px|Flennan Roffo]]&lt;br /&gt;
||Second Life resident since 11 July 2007. Scripter and owner of Logic Scripted products and Script services. You can visit me at my office in Peacock Park (189, 226, 69):&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logic Scripted products and Script services=&lt;br /&gt;
[[Image:Logicscripts.org.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.logicscripts.org logiscripts.org]&lt;br /&gt;
&lt;br /&gt;
==ABOUT LOGIC==&lt;br /&gt;
Logic Scripted Products and Script Services is, as you might have already guessed, all about LSL scripts and script services. My goal is to provide many good quality scripts for every business.&lt;br /&gt;
&lt;br /&gt;
==PRODUCTS==&lt;br /&gt;
&lt;br /&gt;
I am in the process of developing some very usefull products. Note though that each of these products are in early development phase and that new feautures will be released in upcoming releases. Currently I have released the following products:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Logic Mailbox Basic V 1.0&#039;&#039;&#039;&lt;br /&gt;
Basic model for a mailbox that allows anyone to drop you a notecard. Comes with a standard skin. For skin customization, contact Mad Maddy Studio.&lt;br /&gt;
&lt;br /&gt;
[[Image:Slmailbox.jpg]]&lt;br /&gt;
&lt;br /&gt;
See the demo at Logic office: &lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Logic Vendor V 1.0&#039;&#039;&#039;&lt;br /&gt;
Vendor that allows you to display many sellable items (objects) and per item you can give a customer a notecard. The sell price is split amongst multiple authors. Set up is easy, since you have to enter the key of each author only once, and can reference any author by nick.&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicvendorv10.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
See the demo at Logic office:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;SL Mail V 1.2&#039;&#039;&#039;&lt;br /&gt;
SecondLife mail client, released under GNU GPL licence. You can send and receive mail from within SecondLife both from and to other mail clients or external mail adresses. Has many command options and comes with an adjustable address book that allows to enter addresses and address groups.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Get your free copy today at logic office:&#039;&#039;&#039;&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Or, alternatively, get it from the Second Life wiki [[SL Mail V1.2|here]]&lt;br /&gt;
&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.slmail.info slmail.info]&lt;br /&gt;
&lt;br /&gt;
==SERVICE CHARGING POLICY==&lt;br /&gt;
&lt;br /&gt;
The charging policy for script services depends on a number of factors:&lt;br /&gt;
* The usuability of the script. Simply stated, if the script does not provide what it is supposed to do no charge will be applied.&lt;br /&gt;
* The amount of work needed to create, adapt and test the script.&lt;br /&gt;
* The custumor. As a rule, the richer the customer, the higher the price, and the more the script or service I provide enhances business profits, the more is charged.&lt;br /&gt;
* The pricing will be based on the length of the service timeperiod.&lt;br /&gt;
* Prices are within reason.&lt;br /&gt;
* Part or whole price can be refunded if you have a well grounded complaint (script not behaving as specified or a large delay in delivering the scripts).&lt;br /&gt;
* Payment in advance for small projects are not necessary. For larger projects in which significant amount of time is invested advanced payment is asked for in the order of 10%-50% of the agreed price.&lt;br /&gt;
&lt;br /&gt;
==TERMS OF USE==&lt;br /&gt;
&lt;br /&gt;
The scripts I make available public will come with a Terms of Use or Fair Use policy.&lt;br /&gt;
&lt;br /&gt;
These terms of use include:&lt;br /&gt;
&lt;br /&gt;
* No selling or charging for free scripts&lt;br /&gt;
&lt;br /&gt;
Any script you purchase at Logic and/or is provided by Logic (either as a seperate script or as part of a Logic Scripted Product) MAY NOT BE RESOLD OR CHARGED FOR.&lt;br /&gt;
&lt;br /&gt;
If I find someone either selling Logic scripts or making a no-mod version of it, I will contact you about breaking this rule, and if necessary there will be made a public notice of this and take other measures if necessary.&lt;br /&gt;
&lt;br /&gt;
* No breaking of SL TOS&lt;br /&gt;
&lt;br /&gt;
You may not use any script or product (wether a Logic script or product or not) that breaks the Second Life Terms of Service (TOS). You can find the SL TOS on the official Second Life website:  [http://www.secondlife.com/tos.php Second Life Terms of Service]&lt;br /&gt;
&lt;br /&gt;
* Donate for free scripts/services&lt;br /&gt;
&lt;br /&gt;
If you found my scripts and/or other services quite usefull and got them free of charge, you might consider giving a donation. A donation box will be installed any time soon.&lt;br /&gt;
&lt;br /&gt;
==HIRING==&lt;br /&gt;
&lt;br /&gt;
Logic can be hired for diverse projects. This includes besised LSL scripts and also website interfaces (PHP/MySQL) that interface with a scripted product in Second Life. Examples: visitor statistics, detectors, security devices, vendors, rental boxes, and so on. &lt;br /&gt;
&lt;br /&gt;
==LOGIC &amp;amp; STUDIO MAD MADDY==&lt;br /&gt;
&lt;br /&gt;
Logic Scripted Products and Script Services cooperates with Mad Maddy Studio. Mad Maddy Studio is specialised in custom made Textures, Business Logo&#039;s and so on. &lt;br /&gt;
&lt;br /&gt;
For more information about Mad Maddy Studio, and for all your graphical design requests, contact: [[User:Madeliefste Oh|Madeliefste Oh]].&lt;br /&gt;
&lt;br /&gt;
[[Image:MMbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.madmaddy.com madmaddy.com]&lt;br /&gt;
&lt;br /&gt;
=LSL Scripts &amp;amp; Tutorials=&lt;br /&gt;
Logic Scripted products and Script services is serving the broad public domain also by providing a good resource for scripts and script tutorials. This webservice is starting somewhere in october or november 2007.&lt;br /&gt;
The plan is to both collect &amp;amp; document existing scripts that reside in the inventory of residents or circulate in script groups and also create some new scripts ourselves that serve the interest of the public domain at large, and which will complement existing LSL wiki&#039;s, website and script resources/tutorials around the world wide web.&lt;br /&gt;
The website will provide usefull resources for both scripters and non-scripters (script users) and will accomodate both the interests of those that are new to scripting as well as die-hard LSL scripters.&lt;br /&gt;
==SCRIPT &amp;amp; SCRIPT TUTORIAL LIBRARY==&lt;br /&gt;
Both scripts and script tutorials will be placed in a repository/database which facilitates easy access and good searching options and is open for contributions by anyone. To maintain a good quality level some form of moderation will be put in place. User feedback to the site will be encouraged strongly, as  also the sharing of script knowledge, tips &amp;amp; tricks, etc. Other planned part of the website will be a page to make requests for scripts, either for scripts that do not yet exist in the public domain, or for feature requests on existing scripts. Be aware though that this service is not meant to be a place for hiring scripters or to buy a script, and is not intended to replace companies that provide those services for fees, but only is meant to serve the interests of the public in improving high quality scripts that are available as open source.&lt;br /&gt;
&lt;br /&gt;
==SCRIPT USERS==&lt;br /&gt;
&lt;br /&gt;
For those that do not do scripting themselves, and have no interest in becoming a scripter, but do use scripts and/or buy scripts or script services, and want to know more about scripting at the user level, also those demands will be served on the &#039;&#039;&#039;lslscripts.org&#039;&#039;&#039; website. Documentation will be provided on issues like: &lt;br /&gt;
* How much can be charged for a script/script service or hiring of a scripter?&lt;br /&gt;
* What licence model is applicable for the scripts I need for my project?&lt;br /&gt;
etc. &lt;br /&gt;
Linked to this website a script group in-world will be founded under the name: &#039;&#039;&#039;lslscripts.org&#039;&#039;&#039;. This group will be open for anyone to join.&lt;br /&gt;
==SUPPORT LSLSCRIPTS.ORG. DONATE YOUR SCRIPTS OR SCRIPT TUTORIALS==&lt;br /&gt;
Donations to &#039;&#039;&#039;lslscripts.org&#039;&#039;&#039; are welcome, both in the form of scripts, tutorials and some Linden$ for supporting the site and cover its costs are welcome. Want to become actively involved in developing  this website, or just want to communicate your ideas about it? Don&#039;t hesitate to contact the founder of &#039;&#039;&#039;lslscripts.org&#039;&#039;&#039; Flennan Roffo. All contributions, small or large, are welcome.&lt;br /&gt;
Those that are interested in providing some usefull information about scripting, for example in the form of Blog entries or tutorials or other usefull stuff that fits the purpose of this webservice, please contact me. Also if you can support &#039;&#039;&#039;lslscripts.org&#039;&#039;&#039; by placing an advertise free of charge for this webservice on your parcel which connects to the &#039;&#039;&#039;lslscripts.org&#039;&#039;&#039; webservice, do not hesitate to contact me.&lt;br /&gt;
&lt;br /&gt;
Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Logic Scripted products and Script services&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Image:Lslscripts.org.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.lslscripts.org lslscripts.org]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;DONATE YOUR SCRIPTS &amp;amp; SCRIPT TUTORIALS TO LSLSCRIPTS.ORG. BECOME INVOLVED.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{visl&lt;br /&gt;
|name=&lt;br /&gt;
|Scripter=*&lt;br /&gt;
|}}&lt;/div&gt;</description>
			<pubDate>Thu, 11 Oct 2007 03:48:41 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/User_talk:Flennan_Roffo</comments>
		</item>
		<item>
			<title>User:Flennan Roffo</title>
			<link>https://wiki.secondlife.com/w/index.php?title=User:Flennan_Roffo&amp;diff=35000</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=User:Flennan_Roffo&amp;diff=35000</guid>
			<description>&lt;p&gt;Flennan Roffo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
=About Flennan Roffo=&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
||[[Image:FlennanRoffo80x80.jpg|frameless|100px|Flennan Roffo]]&lt;br /&gt;
||Second Life resident since 11 July 2007. Scripter and owner of Logic Scripted products and Script services. You can visit me at my office in Peacock Park (189, 226, 69):&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logic Scripted products and Script services=&lt;br /&gt;
[[Image:Logicscripts.org.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.logicscripts.org logiscripts.org]&lt;br /&gt;
&lt;br /&gt;
==ABOUT LOGIC==&lt;br /&gt;
Logic Scripted Products and Script Services is, as you might have already guessed, all about LSL scripts and script services. My goal is to provide many good quality scripts for every business.&lt;br /&gt;
&lt;br /&gt;
==PRODUCTS==&lt;br /&gt;
&lt;br /&gt;
I am in the process of developing some very usefull products. Note though that each of these products are in early development phase and that new feautures will be released in upcoming releases. Currently I have released the following products:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Logic Mailbox Basic V 1.0&#039;&#039;&#039;&lt;br /&gt;
Basic model for a mailbox that allows anyone to drop you a notecard. Comes with a standard skin. For skin customization, contact Mad Maddy Studio.&lt;br /&gt;
&lt;br /&gt;
[[Image:Slmailbox.jpg]]&lt;br /&gt;
&lt;br /&gt;
See the demo at Logic office: &lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Logic Vendor V 1.0&#039;&#039;&#039;&lt;br /&gt;
Vendor that allows you to display many sellable items (objects) and per item you can give a customer a notecard. The sell price is split amongst multiple authors. Set up is easy, since you have to enter the key of each author only once, and can reference any author by nick.&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicvendorv10.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
See the demo at Logic office:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;SL Mail V 1.2&#039;&#039;&#039;&lt;br /&gt;
SecondLife mail client, released under GNU GPL licence. You can send and receive mail from within SecondLife both from and to other mail clients or external mail adresses. Has many command options and comes with an adjustable address book that allows to enter addresses and address groups.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Get your free copy today at logic office:&#039;&#039;&#039;&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Or, alternatively, get it from the Second Life wiki [[SL Mail V1.2|here]]&lt;br /&gt;
&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.slmail.info slmail.info]&lt;br /&gt;
&lt;br /&gt;
==SERVICE CHARGING POLICY==&lt;br /&gt;
&lt;br /&gt;
The charging policy for script services depends on a number of factors:&lt;br /&gt;
* The usuability of the script. Simply stated, if the script does not provide what it is supposed to do no charge will be applied.&lt;br /&gt;
* The amount of work needed to create, adapt and test the script.&lt;br /&gt;
* The custumor. As a rule, the richer the customer, the higher the price, and the more the script or service I provide enhances business profits, the more is charged.&lt;br /&gt;
* The pricing will be based on the length of the service timeperiod.&lt;br /&gt;
* Prices are within reason.&lt;br /&gt;
* Part or whole price can be refunded if you have a well grounded complaint (script not behaving as specified or a large delay in delivering the scripts).&lt;br /&gt;
* Payment in advance for small projects are not necessary. For larger projects in which significant amount of time is invested advanced payment is asked for in the order of 10%-50% of the agreed price.&lt;br /&gt;
&lt;br /&gt;
==TERMS OF USE==&lt;br /&gt;
&lt;br /&gt;
The scripts I make available public will come with a Terms of Use or Fair Use policy.&lt;br /&gt;
&lt;br /&gt;
These terms of use include:&lt;br /&gt;
&lt;br /&gt;
* No selling or charging for free scripts&lt;br /&gt;
&lt;br /&gt;
Any script you purchase at Logic and/or is provided by Logic (either as a seperate script or as part of a Logic Scripted Product) MAY NOT BE RESOLD OR CHARGED FOR.&lt;br /&gt;
&lt;br /&gt;
If I find someone either selling Logic scripts or making a no-mod version of it, I will contact you about breaking this rule, and if necessary there will be made a public notice of this and take other measures if necessary.&lt;br /&gt;
&lt;br /&gt;
* No breaking of SL TOS&lt;br /&gt;
&lt;br /&gt;
You may not use any script or product (wether a Logic script or product or not) that breaks the Second Life Terms of Service (TOS). You can find the SL TOS on the official Second Life website:  http://www.secondlife.com&lt;br /&gt;
&lt;br /&gt;
* Donate for free scripts/services&lt;br /&gt;
&lt;br /&gt;
If you found my scripts and/or other services quite usefull and got them free of charge, you might consider giving a donation. A donation box will be installed any time soon.&lt;br /&gt;
&lt;br /&gt;
==HIRING==&lt;br /&gt;
&lt;br /&gt;
Logic can be hired for diverse projects. This includes besised LSL scripts and also website interfaces (PHP/MySQL) that interface with a scripted product in Second Life. Examples: visitor statistics, detectors, security devices, vendors, rental boxes, and so on. &lt;br /&gt;
&lt;br /&gt;
==LOGIC &amp;amp; STUDIO MAD MADDY==&lt;br /&gt;
&lt;br /&gt;
Logic Scripted Products and Script Services cooperates with Mad Maddy Studio. Mad Maddy Studio is specialised in custom made Textures, Business Logo&#039;s and so on. &lt;br /&gt;
&lt;br /&gt;
For more information about Mad Maddy Studio, and for all your graphical design requests, contact: [[User:Madeliefste Oh|Madeliefste Oh]].&lt;br /&gt;
&lt;br /&gt;
[[Image:MMbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.madmaddy.com madmaddy.com]&lt;br /&gt;
&lt;br /&gt;
=LSL Scripts &amp;amp; Tutorials=&lt;br /&gt;
Logic Scripted products and Script services is serving the broad public domain also by providing a good resource for scripts and script tutorials. This webservice is starting somewhere in october or november 2007.&lt;br /&gt;
The plan is to both collect &amp;amp; document existing scripts that reside in the inventory of residents or circulate in script groups and also create some new scripts ourselves that serve the interest of the public domain at large, and which will complement existing LSL wiki&#039;s, website and script resources/tutorials around the world wide web.&lt;br /&gt;
The website will provide usefull resources for both scripters and non-scripters (script users) and will accomodate both the interests of those that are new to scripting as well as die-hard LSL scripters.&lt;br /&gt;
==SCRIPT &amp;amp; SCRIPT TUTORIAL LIBRARY==&lt;br /&gt;
Both scripts and script tutorials will be placed in a repository/database which facilitates easy access and good searching options and is open for contributions by anyone. To maintain a good quality level some form of moderation will be put in place. User feedback to the site will be encouraged strongly, as  also the sharing of script knowledge, tips &amp;amp; tricks, etc. Other planned part of the website will be a page to make requests for scripts, either for scripts that do not yet exist in the public domain, or for feature requests on existing scripts. Be aware though that this service is not meant to be a place for hiring scripters or to buy a script, and is not intended to replace companies that provide those services for fees, but only is meant to serve the interests of the public in improving high quality scripts that are available as open source.&lt;br /&gt;
&lt;br /&gt;
==SCRIPT USERS==&lt;br /&gt;
&lt;br /&gt;
For those that do not do scripting themselves, and have no interest in becoming a scripter, but do use scripts and/or buy scripts or script services, and want to know more about scripting at the user level, also those demands will be served on the &#039;&#039;&#039;lslscripts.org&#039;&#039;&#039; website. Documentation will be provided on issues like: &lt;br /&gt;
* How much can be charged for a script/script service or hiring of a scripter?&lt;br /&gt;
* What licence model is applicable for the scripts I need for my project?&lt;br /&gt;
etc. &lt;br /&gt;
Linked to this website a script group in-world will be founded under the name: &#039;&#039;&#039;lslscripts.org&#039;&#039;&#039;. This group will be open for anyone to join.&lt;br /&gt;
==SUPPORT LSLSCRIPTS.ORG. DONATE YOUR SCRIPTS OR SCRIPT TUTORIALS==&lt;br /&gt;
Donations to &#039;&#039;&#039;lslscripts.org&#039;&#039;&#039; are welcome, both in the form of scripts, tutorials and some Linden$ for supporting the site and cover its costs are welcome. Want to become actively involved in developing  this website, or just want to communicate your ideas about it? Don&#039;t hesitate to contact the founder of &#039;&#039;&#039;lslscripts.org&#039;&#039;&#039; Flennan Roffo. All contributions, small or large, are welcome.&lt;br /&gt;
Those that are interested in providing some usefull information about scripting, for example in the form of Blog entries or tutorials or other usefull stuff that fits the purpose of this webservice, please contact me. Also if you can support &#039;&#039;&#039;lslscripts.org&#039;&#039;&#039; by placing an advertise free of charge for this webservice on your parcel which connects to the &#039;&#039;&#039;lslscripts.org&#039;&#039;&#039; webservice, do not hesitate to contact me.&lt;br /&gt;
&lt;br /&gt;
Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Logic Scripted products and Script services&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[Image:Lslscripts.org.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.lslscripts.org lslscripts.org]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;DONATE YOUR SCRIPTS &amp;amp; SCRIPT TUTORIALS TO LSLSCRIPTS.ORG. BECOME INVOLVED.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{visl&lt;br /&gt;
|name=&lt;br /&gt;
|Scripter=*&lt;br /&gt;
|}}&lt;/div&gt;</description>
			<pubDate>Wed, 10 Oct 2007 15:50:36 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/User_talk:Flennan_Roffo</comments>
		</item>
		<item>
			<title>SL Mail V1.2</title>
			<link>https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34600</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34600</guid>
			<description>&lt;p&gt;Flennan Roffo: /* &amp;#039;&amp;#039;&amp;#039;Second Life mail client&amp;#039;&amp;#039;&amp;#039; */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}} __NOTOC__&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=&#039;&#039;&#039;Second Life mail client&#039;&#039;&#039;=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Send and receive email from within Second Life from and to any address.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implemented with Address Book function (in a notecard named &#039;Address Book&#039;) to stores addresses by name  and to compile groups of named addresses. Current version is stand-alone (no server functionality) and uses chat commands only.&lt;br /&gt;
&lt;br /&gt;
[[Image:BannerSLMail.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.slmail.info slmail.info] (website coming soon!)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Release Notes V1.2=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 Release notes (edition 2, 4 sept 2007)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LICENCE INFO&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is released under GNU free software licence&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;PRODUCTION &amp;amp; MAINTANENCE&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
by Logic Scripted Products and Script Services&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.logicscripts.org logicscripts.org] (website coming soon!)&lt;br /&gt;
&lt;br /&gt;
SLurl:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Contact: [[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
&lt;br /&gt;
Email: [mailto:info@slmail.info &#039;&#039;&#039;info&#039;&#039;&#039;] or [mailto:Flennan.Roffo@slmail.info &#039;&#039;&#039;Flennan Roffo&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;DESCRIPTION&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is a simple tool to send and receive mail from within SL.&lt;br /&gt;
You can either compose a message yourself using chat recording, or choose a notecard from inventory to send. The Address Book functionality allows you to use short names for mail recipients stored in a notecard. The current version does not have a persisent mail address. Watch out for the upcoming next release (V1.3) which will facilitate persisent in-world mail addresses and will be enhanced with many new features (See: Requests For Change (RFC).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;COMMANDS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Help&#039;&#039;&#039;&lt;br /&gt;
||Show Help about available commands&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Record&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording (for owner only).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Stop&#039;&#039;&#039;&lt;br /&gt;
||Stops the chat recording without sending&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Continue&#039;&#039;&#039;&lt;br /&gt;
||Continues a previously stopped chat recording. Lines will be appended to you recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Show&#039;&#039;&#039;&lt;br /&gt;
||Shows the content of the recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send&#039;&#039;&#039;&lt;br /&gt;
||If recording, stops the recording, and sends the mail (need to supply mail address and subject first!)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send &amp;lt;notecard&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Sends the content of the notecard, instead of the chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Ignore&#039;&#039;&#039;&lt;br /&gt;
||Ignores your current chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject &amp;lt;subject&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the subject of the mail.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail subject.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Set the HOME address of the owner (mail will be forwarder to this address when offline).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home&#039;&#039;&#039;&lt;br /&gt;
||Show the HOME address.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Info&#039;&#039;&#039;&lt;br /&gt;
||Shows the mail address the object this script is running in uses (e.g. &amp;lt;object-key&amp;gt;@lsl.secondlife.com).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Read&#039;&#039;&#039;&lt;br /&gt;
||Reads the current message from the mail buffer (the mail buffer gets filled with mail you receive)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Select &amp;lt;msg&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Select a message number from the availabe messages in the mail buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Next&#039;&#039;&#039;&lt;br /&gt;
||Make next message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Prev&#039;&#039;&#039;&lt;br /&gt;
||Make previous message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@First&#039;&#039;&#039;&lt;br /&gt;
||Make the first message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Last&#039;&#039;&#039;&lt;br /&gt;
||Make the last message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Clear&#039;&#039;&#039;&lt;br /&gt;
||Clear the mail buffer&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Delete&#039;&#039;&#039;&lt;br /&gt;
||Deletes only the current message&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Reply&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording to reply to the current message. Mail adress and subject are filled in automatically.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* Commands are case insensitive (&amp;quot;@read&amp;quot; == &amp;quot;@READ&amp;quot;). Arguments might not be case insensitive.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;ADDRESS BOOK FORMAT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
A notecard of the name &#039;Address Book&#039; is read during initialization which may contain Address Book items and Groups.&lt;br /&gt;
The notecard is split in two sections, which need to be defined in that particular order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[ADDRESS BOOK]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Defines the section in which you can put names for mail addresses,  like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name1=account@thisdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name2=user@otherdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[GROUP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define groups of previously defined names under a new name, like for instance:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyGroup=Name1, Name2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note that names of groups and individual mail adresses share the same namespace and must be unique.&lt;br /&gt;
&lt;br /&gt;
So when you filled in your mail adresses in the Address Book, you can now use:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail Name1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to  &amp;lt;account@thisdomain.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail MyGroup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to &amp;lt;account@thisdomain.com&amp;gt; and &amp;lt;user@otherdomain.com&amp;gt;&lt;br /&gt;
Mails will be sent one after another.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* Names for Addreses and Groups are case insensitive (e.g. &amp;quot;mary&amp;quot;  == &amp;quot;MARY&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* The special address &#039;Self&#039; can be used in commands where otherwise an address specification can be used. &#039;Self&#039; is case insensitive (e.g. &amp;quot;self&amp;quot; == &amp;quot;SELF&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LIMITATIONS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
The current version is limited by the following:&lt;br /&gt;
&lt;br /&gt;
* Chat recording lines are limited by the 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Output of lines from the mail buffer are also limited by this 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Incoming mail is limited to a 1000 (1024?) byte limit&lt;br /&gt;
&lt;br /&gt;
* Outgoing mai is limited by a 4096 byte limit, which includes the standard mail header (region/location info on the first two lines)&lt;br /&gt;
&lt;br /&gt;
We are making adjustments to this release to help overcome these limitations. At least the line lenght limit can be overcome by introducing a line continuation character (for example a hyphen &#039;-&#039;) that when used at the end of a line appends the next line, so lines longer then 255 bytes are possible then.&lt;br /&gt;
&lt;br /&gt;
To overcome the outgoing mail length limit, the mail can be broken textualy into parts, and each part can be send seperatedely, with an indication in the subject or in an introduced primary line of the mail body to indicate that the mail was split into parts.&lt;br /&gt;
For incoming mail and at least to receive mail from other SL Mail programs, a protocol will be introduced to receive mail in parts that are joined together after receiving them to form a single mail.&lt;br /&gt;
&lt;br /&gt;
These enhancements will be made available in the next release (V1.3) of SL Mail &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;BUGS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Report any bugs you find in this release to Logic (IM: Flennan Roffo).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;REQUEST FOR CHANGE (RFC)&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Do you have additional wishes for enhancement of this product?&lt;br /&gt;
Contact Flennan Roffo and we will see if they can be implemented in the next release.&lt;br /&gt;
&lt;br /&gt;
Existing RFC&#039;s are:&lt;br /&gt;
&lt;br /&gt;
* Menu support for commands.&lt;br /&gt;
&lt;br /&gt;
* Lines on incoming/outgoing mail longer than 255 bytes.&lt;br /&gt;
&lt;br /&gt;
* Send messages longer than 4096 (minus SL mail header) bytes.&lt;br /&gt;
&lt;br /&gt;
* Receive messages longer than 1024 bytes.&lt;br /&gt;
&lt;br /&gt;
* Permanent mail addresses for the SL Mail client (like: &amp;lt;Flennan.Roffo@somedomain.sl&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Add your RFC!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In-world join the group &amp;quot;SL Mail&amp;quot; for bug reports, feature requests, the latest SL Mail release, and notices about development issues.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scripts=&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==Script: SL Mail v1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail core module which scans for incoming mail messages and executes commands used by the owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail V1.2.lsl&lt;br /&gt;
// (c) 2007 Logic Scripted Products and Script Services&lt;br /&gt;
// Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
// VERSION&lt;br /&gt;
// Version: 1.2&lt;br /&gt;
&lt;br /&gt;
// HISTORY&lt;br /&gt;
// Date         Version     Author              Comment&lt;br /&gt;
// --------------------------------------------------------------------------------------&lt;br /&gt;
// 28 aug 2007  V 1.0       Flennan Roffo       Created&lt;br /&gt;
//&lt;br /&gt;
//  1 sep 2007  V 1.1       Flennan Roffo       @Reply empties the recording buffer.&lt;br /&gt;
//                                                @Send while recording ends recording&lt;br /&gt;
//                                                and sends the mail if a mail address&lt;br /&gt;
//                                                and subject are supplied.&lt;br /&gt;
//                                                Fixed incorrect date in Unix2DateTime.&lt;br /&gt;
//  3 sep 2007  V 1.2       Flennan Roffo       Notification options:&lt;br /&gt;
//                                              - When online, send an IM when mail is received.&lt;br /&gt;
//                                              - When offline, send to HOME mail adress.&lt;br /&gt;
//                                              Adressbook&lt;br /&gt;
//                                              - Read adress book from config notecard.&lt;br /&gt;
&lt;br /&gt;
// LICENCE&lt;br /&gt;
// This program is free software; you can redistribute it and/or&lt;br /&gt;
// modify it under the terms of the GNU General Public License&lt;br /&gt;
// as published by the Free Software Foundation; either version 2&lt;br /&gt;
// of the License, or (at your option) any later version.&lt;br /&gt;
// &lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
// &lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program; if not, write to the Free Software&lt;br /&gt;
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
// (Also available at http://www.gnu.org/copyleft/gpl.html) &lt;br /&gt;
&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// Let&#039;s you record a message and sent to email and get messages and reply to messages.&lt;br /&gt;
// Must supply a valid mail adress and non-empty subject using chat commands.&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
// 1) Check for the maximum length of an email message (including newline and header).&lt;br /&gt;
// 2) Read adress book from notecard.                                    *DONE*&lt;br /&gt;
// 3) Send incoming mail to personal mail adress when offline.            *DONE*&lt;br /&gt;
// 4) Alert with an IM when online upon receiving new mail.                *DONE*&lt;br /&gt;
&lt;br /&gt;
string   SL_MAIL_VERSION = &amp;quot;V 1.2&amp;quot;;&lt;br /&gt;
string   SL_MAIL_DATE    = &amp;quot; 2 sep 2007&amp;quot;;&lt;br /&gt;
integer  ErrorFlag         = FALSE;&lt;br /&gt;
list     ScriptList        = [ &amp;quot;SL Mail Help V1.2&amp;quot;, &amp;quot;SL Mail AddressBook V1.2&amp;quot;, &lt;br /&gt;
                                &amp;quot;SL Mail OnlineStatus V1.2&amp;quot;, &amp;quot;SL Mail FetchNotecard V1.2&amp;quot; ];    &lt;br /&gt;
string   LSL_DOMAIN=&amp;quot;lsl.secondlife.com&amp;quot;; &lt;br /&gt;
integer  StatusOnline=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Commands&lt;br /&gt;
&lt;br /&gt;
string  COMMAND_RECORD     = &amp;quot;@RECORD&amp;quot;;&lt;br /&gt;
string  COMMAND_CONTINUE   = &amp;quot;@CONTINUE&amp;quot;;&lt;br /&gt;
string  COMMAND_STOP       = &amp;quot;@STOP&amp;quot;;&lt;br /&gt;
string  COMMAND_MAIL       = &amp;quot;@MAIL&amp;quot;;&lt;br /&gt;
string  COMMAND_SUBJECT    = &amp;quot;@SUBJECT&amp;quot;;&lt;br /&gt;
string  COMMAND_SEND       = &amp;quot;@SEND&amp;quot;;&lt;br /&gt;
string  COMMAND_SEE        = &amp;quot;@SEE&amp;quot;;&lt;br /&gt;
string  COMMAND_IGNORE     = &amp;quot;@IGNORE&amp;quot;;&lt;br /&gt;
string  COMMAND_READ       = &amp;quot;@READ&amp;quot;;&lt;br /&gt;
string  COMMAND_DELETE     = &amp;quot;@DELETE&amp;quot;;&lt;br /&gt;
string  COMMAND_CLEAR      = &amp;quot;@CLEAR&amp;quot;;&lt;br /&gt;
string  COMMAND_REPLY      = &amp;quot;@REPLY&amp;quot;;&lt;br /&gt;
string  COMMAND_NEXT       = &amp;quot;@NEXT&amp;quot;;&lt;br /&gt;
string  COMMAND_PREV       = &amp;quot;@PREV&amp;quot;;&lt;br /&gt;
string  COMMAND_FIRST      = &amp;quot;@FIRST&amp;quot;;&lt;br /&gt;
string  COMMAND_LAST       = &amp;quot;@LAST&amp;quot;;&lt;br /&gt;
string  COMMAND_LIST       = &amp;quot;@LIST&amp;quot;;&lt;br /&gt;
string  COMMAND_SELECT     = &amp;quot;@SELECT&amp;quot;;&lt;br /&gt;
string  COMMAND_HELP       = &amp;quot;@HELP&amp;quot;;&lt;br /&gt;
string  COMMAND_INFO       = &amp;quot;@INFO&amp;quot;;&lt;br /&gt;
string  COMMAND_RESET      = &amp;quot;@RESET&amp;quot;;&lt;br /&gt;
string  COMMAND_SHOW       = &amp;quot;@SHOW&amp;quot;;&lt;br /&gt;
string  COMMAND_ON         = &amp;quot;@ON&amp;quot;;&lt;br /&gt;
string  COMMAND_OFF        = &amp;quot;@OFF&amp;quot;;&lt;br /&gt;
string  COMMAND_HOME       = &amp;quot;@HOME&amp;quot;;&lt;br /&gt;
string  COMMAND_LOAD       = &amp;quot;@LOAD&amp;quot;;&lt;br /&gt;
string  COMMAND_ADDRESS    = &amp;quot;@ADDRESS&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Recording&lt;br /&gt;
&lt;br /&gt;
integer Recording = FALSE;&lt;br /&gt;
&lt;br /&gt;
list    ChatRecording=[];&lt;br /&gt;
integer NumLines=0;&lt;br /&gt;
integer Length=0;&lt;br /&gt;
&lt;br /&gt;
list     TimeList=[];&lt;br /&gt;
list     AddressList=[];&lt;br /&gt;
list     SubjectList=[];&lt;br /&gt;
list     BodyList=[];&lt;br /&gt;
integer  NumMessages=0;&lt;br /&gt;
integer  CurrentMessage=-1;&lt;br /&gt;
&lt;br /&gt;
float    MAIL_FETCH_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
// Link Messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP                        = 10000;&lt;br /&gt;
integer MSG_STATUS_ONLINE               = 30000;&lt;br /&gt;
integer MSG_STATUS_OFFLINE              = 30100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED          = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR           = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Unix Time conversion //////////////////&lt;br /&gt;
&lt;br /&gt;
integer DAYS_PER_YEAR        = 365;                // Non leap year&lt;br /&gt;
integer SECONDS_PER_YEAR     = 31536000;          // Non leap year&lt;br /&gt;
integer SECONDS_PER_DAY      = 86400;&lt;br /&gt;
integer SECONDS_PER_HOUR     = 3600;&lt;br /&gt;
integer SECONDS_PER_MINUTE   = 60;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// LeapYear() /////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer LeapYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (year % 4 == 0)&lt;br /&gt;
    {&lt;br /&gt;
        if (year % 100 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (year % 400 == 0)&lt;br /&gt;
            {&lt;br /&gt;
                return 1;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// DaysPerMonth() ///////////////////////////////////////&lt;br /&gt;
                &lt;br /&gt;
integer DaysPerMonth(integer year,integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;lt; 8)&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (month == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if (LeapYear(year))&lt;br /&gt;
                {&lt;br /&gt;
                    return 29;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    return 28;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 30;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 30;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////// DaysPerYear() ////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DaysPerYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (LeapYear(year))&lt;br /&gt;
        return DAYS_PER_YEAR + 1;&lt;br /&gt;
    else&lt;br /&gt;
        return DAYS_PER_YEAR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Unix2DataTime() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list Unix2DateTime(integer unixtime)&lt;br /&gt;
{&lt;br /&gt;
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;&lt;br /&gt;
    integer day = days_since_1_1_1970 + 1;&lt;br /&gt;
    integer year  = 1970;&lt;br /&gt;
    integer days_per_year = DaysPerYear(year);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_year)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_year;&lt;br /&gt;
        ++year;&lt;br /&gt;
        days_per_year = DaysPerYear(year);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer month = 1;&lt;br /&gt;
    integer days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_month)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_month;&lt;br /&gt;
        &lt;br /&gt;
        if (++month &amp;gt; 12)&lt;br /&gt;
        {    &lt;br /&gt;
            ++year;&lt;br /&gt;
            month = 1;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;&lt;br /&gt;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;&lt;br /&gt;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;&lt;br /&gt;
    integer minute      = second / SECONDS_PER_MINUTE;&lt;br /&gt;
    second               = second % SECONDS_PER_MINUTE;&lt;br /&gt;
    &lt;br /&gt;
    return [ year, month, day, hour, minute, second ];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// MonthName() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list MonthNameList = [     &amp;quot;JAN&amp;quot;, &amp;quot;FEB&amp;quot;, &amp;quot;MAR&amp;quot;, &amp;quot;APR&amp;quot;, &amp;quot;MAY&amp;quot;, &amp;quot;JUN&amp;quot;, &lt;br /&gt;
                        &amp;quot;JUL&amp;quot;, &amp;quot;AUG&amp;quot;, &amp;quot;SEP&amp;quot;, &amp;quot;OCT&amp;quot; , &amp;quot;NOV&amp;quot;, &amp;quot;DEC&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
string MonthName(integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;gt;= 0 &amp;amp;&amp;amp; month &amp;lt; 12)&lt;br /&gt;
        return llList2String(MonthNameList, month);&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// DateString() ///////////////////////////&lt;br /&gt;
&lt;br /&gt;
string DateString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer year       = llList2Integer(timelist,0);&lt;br /&gt;
    integer month      = llList2Integer(timelist,1);&lt;br /&gt;
    integer day        = llList2Integer(timelist,2);&lt;br /&gt;
    &lt;br /&gt;
    return (string)day + &amp;quot;-&amp;quot; + MonthName(month - 1) + &amp;quot;-&amp;quot; + (string)year;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// TimeString() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string TimeString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer hour          = llList2Integer(timelist,3);&lt;br /&gt;
    integer minute         = llList2Integer(timelist,4);&lt;br /&gt;
    integer second         = llList2Integer(timelist,5);&lt;br /&gt;
    string  hourstr     = (string)hour;&lt;br /&gt;
    string  minutestr   = (string)minute;&lt;br /&gt;
    string  secondstr   = (string)second;&lt;br /&gt;
    &lt;br /&gt;
    if (hour &amp;lt; 10)         hourstr     = &amp;quot;0&amp;quot; + hourstr;&lt;br /&gt;
    if (minute &amp;lt; 10)     minutestr     = &amp;quot;0&amp;quot; + minutestr;&lt;br /&gt;
    if (second &amp;lt; 10)    secondstr    = &amp;quot;0&amp;quot; + secondstr;&lt;br /&gt;
    return hourstr + &amp;quot;:&amp;quot; + minutestr + &amp;quot;:&amp;quot; + secondstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() /////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string body)&lt;br /&gt;
{&lt;br /&gt;
    // llOwnerSay(&amp;quot;Sending message to &#039;&amp;quot; + address + &amp;quot;&#039; with subject &#039;&amp;quot; + subject +&amp;quot;&#039;.&amp;quot;);&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND, body, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// SendHome() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendHome(string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SENDHOME, body, (key)subject);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Show() ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Show()&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;Current chat recording is:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; NumLines; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(ChatRecording,i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;Lines is &amp;quot; + (string)NumLines);&lt;br /&gt;
    llOwnerSay(&amp;quot;Message length is &amp;quot; + (string)Length);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Read() /////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Read()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;Reading message &amp;quot; + (string)CurrentMessage + &amp;quot; from mail buffer.&amp;quot;);&lt;br /&gt;
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);&lt;br /&gt;
    list timelist=Unix2DateTime(time);&lt;br /&gt;
    string Address = llList2String(AddressList,CurrentMessage);&lt;br /&gt;
    string Subject = llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
    string Body    = llList2String(BodyList,CurrentMessage);&lt;br /&gt;
    llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Address: &amp;quot; + Address);&lt;br /&gt;
    llOwnerSay(&amp;quot;Subject: &amp;quot; + Subject);&lt;br /&gt;
    llOwnerSay(&amp;quot;Begin of message body:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    list bodylist=llParseStringKeepNulls(Body, [ &amp;quot;\n&amp;quot; ], []);&lt;br /&gt;
    integer num=llGetListLength(bodylist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(bodylist,i));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;End of message body.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////// List ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
List()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;The mail buffer contains the following messages:\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; NumMessages; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer time=llList2Integer(TimeList,i);&lt;br /&gt;
        list timelist=Unix2DateTime(time);&lt;br /&gt;
        if (i &amp;gt; 0) llOwnerSay(&amp;quot;+-+-+-+-+-+-+-+-+-+-+-+-&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Message: &amp;quot; + (string)i);&lt;br /&gt;
        llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;From:    &amp;quot; + llList2String(AddressList,i));&lt;br /&gt;
        llOwnerSay(&amp;quot;Subject: &amp;quot; + llList2String(SubjectList,i));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////// NotifyNewMail() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
NotifyNewMail(string time, string address, string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    list timelist=Unix2DateTime((integer)time);&lt;br /&gt;
&lt;br /&gt;
    if (StatusOnline)&lt;br /&gt;
    {&lt;br /&gt;
        llInstantMessage(llGetOwner(), &amp;quot;You received a new mail message on &amp;quot; &lt;br /&gt;
                                    + DateString(timelist) + &amp;quot; at &amp;quot; + TimeString(timelist)&lt;br /&gt;
                                    + &amp;quot; from &amp;quot; + address &lt;br /&gt;
                                    + &amp;quot; with the subject &amp;quot; + subject);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        SendHome(&amp;quot;FW: &amp;quot; + subject, &amp;quot;Received at: &amp;quot; + DateString(timelist) + &amp;quot; &amp;quot; + TimeString(timelist) + &amp;quot;\nFrom: &amp;quot; +  address &lt;br /&gt;
                    + &amp;quot;\nBegin message body:\n-------------------\n&amp;quot; + body + &amp;quot;\n-------------------\nEnd message body.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ResetOtherScripts() //////////////////////&lt;br /&gt;
&lt;br /&gt;
ResetOtherScripts()&lt;br /&gt;
{&lt;br /&gt;
    string     name;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(ScriptList);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        name = llList2String(ScriptList,i);&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(name) == INVENTORY_SCRIPT)&lt;br /&gt;
        {&lt;br /&gt;
            llResetOtherScript(name);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Error - script &#039;&amp;quot; + name + &amp;quot;&#039; not found.&amp;quot;);&lt;br /&gt;
            ErrorFlag = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
// default &lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ////////////////////// state_entry() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Welcome to SL Mail, released under GNU software licence.&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Version &amp;quot; + SL_MAIL_VERSION + &amp;quot; &amp;quot; + SL_MAIL_DATE);&lt;br /&gt;
        llOwnerSay(&amp;quot;Produced by Logic Scripted Products &amp;amp; Product Services&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Free memory: &amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
        ResetOtherScripts();&lt;br /&gt;
        &lt;br /&gt;
        if (ErrorFlag)&lt;br /&gt;
            state Error;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// on_rez() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// changed() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_LOADED)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_ERROR)&lt;br /&gt;
        {&lt;br /&gt;
            state Error;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() //////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(MAIL_FETCH_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //////////////////////// on_rez() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// listen() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string trimmessage=llStringTrim(message,STRING_TRIM);&lt;br /&gt;
        list   parse = llParseStringKeepNulls(trimmessage, [ &amp;quot; &amp;quot;], []);&lt;br /&gt;
        string command = llToUpper(llList2String(parse,0));&lt;br /&gt;
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        integer nargs  = llGetListLength(parse);&lt;br /&gt;
        string argstr=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (nargs &amp;gt; 1) argstr=llGetSubString(message, llSubStringIndex(message, &amp;quot; &amp;quot;) + 1, -1);&lt;br /&gt;
            &lt;br /&gt;
        if (Recording)&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Recording stopped. Type @SHOW to see the message you have entered,&amp;quot;&lt;br /&gt;
                            + &amp;quot; or @SEND to send it.&amp;quot;);&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                &lt;br /&gt;
                SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];&lt;br /&gt;
                ++NumLines;&lt;br /&gt;
                Length += llStringLength(message) + 2;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_RECORD)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Start recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                ChatRecording = [];&lt;br /&gt;
                NumLines=0;&lt;br /&gt;
                Length=0;&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CONTINUE)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Continue recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_REPLY)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    string address=llList2String(AddressList,CurrentMessage);&lt;br /&gt;
                    string subject=&amp;quot;Re: &amp;quot; + llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, address, NULL_KEY);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, subject, NULL_KEY);&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines=0;&lt;br /&gt;
                    Length=0;&lt;br /&gt;
                    Recording = TRUE;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_MAIL)&lt;br /&gt;
            {&lt;br /&gt;
                string mailaddress=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailaddress != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, mailaddress, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETADDRESS, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SUBJECT)&lt;br /&gt;
            {&lt;br /&gt;
                string mailsubject=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailsubject != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, mailsubject, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETSUBJECT, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Not recording.&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    if (NumLines == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND_NOTECARD, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_IGNORE)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines = 0;&lt;br /&gt;
                    Length = 0;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Show();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_READ)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumMessages == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Read();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        ++CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        --CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_FIRST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = 0;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LAST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LIST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    List();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SELECT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;Need to supply a message number.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    integer msgnum = (integer)arg;&lt;br /&gt;
                     &lt;br /&gt;
                    if (msgnum &amp;lt; 0 || msgnum &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Message number &amp;quot; + arg + &amp;quot; not in mail buffer.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = msgnum;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_DELETE)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    --NumMessages;&lt;br /&gt;
                     &lt;br /&gt;
                    if (NumMessages == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = -1;&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (CurrentMessage &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CLEAR)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList=[];&lt;br /&gt;
                    AddressList=[];&lt;br /&gt;
                    SubjectList=[];&lt;br /&gt;
                    BodyList=[];&lt;br /&gt;
                    NumMessages=0;&lt;br /&gt;
                    CurrentMessage=-1;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_HELP, arg, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_INFO)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                Show();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_RESET)&lt;br /&gt;
            {&lt;br /&gt;
                llResetScript();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                state not_running;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HOME)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs==1)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETHOME, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETHOME, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// email() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    email(string time, string address, string subject, string body, integer queued)&lt;br /&gt;
    {&lt;br /&gt;
        NotifyNewMail(time, address, subject, body);&lt;br /&gt;
        TimeList = (TimeList=[]) + TimeList + [time];&lt;br /&gt;
        AddressList = (AddressList=[]) + AddressList + [address];&lt;br /&gt;
        SubjectList = (SubjectList=[]) + SubjectList + [subject];&lt;br /&gt;
        BodyList = (BodyList=[]) + BodyList + [body];&lt;br /&gt;
        ++NumMessages;&lt;br /&gt;
        &lt;br /&gt;
        if (CurrentMessage == -1)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = NumMessages - 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_REPLY)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state not_running&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state not_running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;SL Mailbox switched OFF. Say @ON to switch it back on.&amp;quot;);&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// on_rez() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// listen() ////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer chan, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string command=llToUpper(message);&lt;br /&gt;
        &lt;br /&gt;
        if (command == COMMAND_ON)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state Error&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state Error&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Error in SL Mail: not all component scripts found.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// End SL Mail V1.2.lsl&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Address Book V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Read and interpret the contents of the Address Book.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail AddressBook V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// &lt;br /&gt;
//  Read the Address Book from a notecard named &amp;quot;Address Book&amp;quot;.&lt;br /&gt;
//&lt;br /&gt;
//  The Address Book has the following format:&lt;br /&gt;
//  &lt;br /&gt;
//  [ADDRESS BOOK]&lt;br /&gt;
//  Name1=username@yourdomain.com&lt;br /&gt;
//  Name2=otheruser@otherdomain.com&lt;br /&gt;
//  ...&lt;br /&gt;
//  [GROUP]&lt;br /&gt;
//  group1=Name1, Name2&lt;br /&gt;
//  ...&lt;br /&gt;
//&lt;br /&gt;
//  Notes:&lt;br /&gt;
//  1. Group and Name share the same namespace, and must be unique.&lt;br /&gt;
//  2. It is allowed to have a name in the addressbook with multiple addresses, seperated by comma&#039;s.&lt;br /&gt;
// &lt;br /&gt;
/////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string  CurrentMailAddress = &amp;quot;&amp;quot;;&lt;br /&gt;
string  CurrentMailSubject = &amp;quot;&amp;quot;;&lt;br /&gt;
integer StatusOnline = FALSE;&lt;br /&gt;
&lt;br /&gt;
// Fetch or Send notecard&lt;br /&gt;
&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Names&lt;br /&gt;
&lt;br /&gt;
list    AddressBookList=[];&lt;br /&gt;
list    MailAddressList=[];&lt;br /&gt;
&lt;br /&gt;
string  STRING_HOME=&amp;quot;HOME&amp;quot;;&lt;br /&gt;
string  STRING_SELF=&amp;quot;SELF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Groups&lt;br /&gt;
&lt;br /&gt;
list   GroupList=[];&lt;br /&gt;
list   GroupNameList=[];&lt;br /&gt;
&lt;br /&gt;
string LSL_DOMAIN = &amp;quot;lsl.secondlife.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Read Address Book notecard&lt;br /&gt;
&lt;br /&gt;
string  ADDRESSBOOK_NOTECARD=&amp;quot;Address Book&amp;quot;;&lt;br /&gt;
integer Line=0;&lt;br /&gt;
key     reqAddressBook=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
integer Section=0;&lt;br /&gt;
integer SECTION_ADDRESS_BOOK=1;&lt;br /&gt;
integer SECTION_GROUP=2;&lt;br /&gt;
string  STRING_ADDRESS_BOOK=&amp;quot;ADDRESS BOOK&amp;quot;;&lt;br /&gt;
string  STRING_GROUP=&amp;quot;GROUP&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Links messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
integer MSG_MESSAGE_NOTIFY              = 90900;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED            = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR            = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// GetSelfAddress() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
string GetSelfAddress()&lt;br /&gt;
{&lt;br /&gt;
    return (string)llGetKey() + &amp;quot;@&amp;quot; + LSL_DOMAIN;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Info() /////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Info()&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;The mail address for this object is: &amp;quot; &lt;br /&gt;
                    + GetSelfAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// IsValidKeyFormat() //////////////////////&lt;br /&gt;
&lt;br /&gt;
integer IsValidKeyFormat(string str)&lt;br /&gt;
{&lt;br /&gt;
    string keychars = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    if (llStringLength(str) != 36)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    if( (llGetSubString( str, 8, 8 )   != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 13, 13 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 18, 18 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 23, 23 )  != &amp;quot;-&amp;quot; ) )&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 9; i &amp;lt; 13; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 14; i &amp;lt; 18; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 19; i &amp;lt; 23; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 24; i &amp;lt; 36; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// ValidMailAddress() ////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer ValidMailAddress(string arg)&lt;br /&gt;
{&lt;br /&gt;
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));&lt;br /&gt;
    &lt;br /&gt;
    if (adress == &amp;quot;&amp;quot;)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    list parse = llParseStringKeepNulls(adress, [ &amp;quot;@&amp;quot; ], []);&lt;br /&gt;
    string account = llList2String(parse,0);&lt;br /&gt;
    string domain  = llList2String(parse,1);&lt;br /&gt;
    &lt;br /&gt;
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    &lt;br /&gt;
    if (domain == LSL_DOMAIN)&lt;br /&gt;
    {&lt;br /&gt;
        return IsValidKeyFormat(account);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list parsedomain = llParseString2List(domain, [ &amp;quot;.&amp;quot; ], []);&lt;br /&gt;
    &lt;br /&gt;
        if (llGetListLength(parsedomain) &amp;lt; 2)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        &lt;br /&gt;
        integer num = llGetListLength(parsedomain);&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llStringLength(llList2String(parsedomain,i)) &amp;lt; 2)&lt;br /&gt;
            {&lt;br /&gt;
                return FALSE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetAddressStr() ///////////////////&lt;br /&gt;
&lt;br /&gt;
string GetAndCheckAddressStr(string address)&lt;br /&gt;
{&lt;br /&gt;
    list addresslist = llCSV2List(address);&lt;br /&gt;
    integer num=llGetListLength(addresslist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    string addressstr=&amp;quot;&amp;quot;;&lt;br /&gt;
    string curaddress=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        curaddress=llList2String(addresslist,i);&lt;br /&gt;
        &lt;br /&gt;
        if (ValidMailAddress(curaddress))&lt;br /&gt;
        {&lt;br /&gt;
            addressstr = (addressstr=&amp;quot;&amp;quot;) + addressstr + curaddress + &amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address string: &#039;&amp;quot; &lt;br /&gt;
                            + curaddress + &amp;quot;&#039;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return llGetSubString(addressstr, 0, -2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ProcessLine() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
ProcessLine(string rawline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(rawline,STRING_TRIM);&lt;br /&gt;
    string first=llGetSubString(line,0,0);&lt;br /&gt;
    string last=llGetSubString(line,-1,-1);&lt;br /&gt;
    &lt;br /&gt;
    // Ignore a blank line or comment line&lt;br /&gt;
    if (line == &amp;quot;&amp;quot; || first == &amp;quot;#&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // Check for the right section&lt;br /&gt;
    &lt;br /&gt;
    if (first == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; last == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        string sectionstr=llToUpper(llStringTrim(llGetSubString(line,1,-2),STRING_TRIM));&lt;br /&gt;
        &lt;br /&gt;
        if (sectionstr == STRING_ADDRESS_BOOK)&lt;br /&gt;
        {&lt;br /&gt;
            Section = SECTION_ADDRESS_BOOK;&lt;br /&gt;
        }&lt;br /&gt;
        else if (sectionstr == STRING_GROUP)&lt;br /&gt;
        {&lt;br /&gt;
            if (Section == 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                        + &amp;quot;. Group section defined before Address Book section.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Section = SECTION_GROUP;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid section header &#039;&amp;quot; + sectionstr &lt;br /&gt;
                        + &amp;quot;&#039; in &amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Must be in a section&lt;br /&gt;
    &lt;br /&gt;
    if (Section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;. No section header.&amp;quot;, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    list     parse=llParseString2List(line, [ &amp;quot;=&amp;quot; ], []);&lt;br /&gt;
    integer  num=llGetListLength(parse);&lt;br /&gt;
    &lt;br /&gt;
    // Format must be correct&lt;br /&gt;
    &lt;br /&gt;
    if (num != 2)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; +  (string)(Line+1) + &amp;quot;:\n&amp;quot; + rawline, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (Section == SECTION_ADDRESS_BOOK)&lt;br /&gt;
    {&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(name) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + name &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ name ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            string address=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
            string addressstr=GetAndCheckAddressStr(address);&lt;br /&gt;
            &lt;br /&gt;
            if (addressstr != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                AddressBookList     = (AddressBookList=[])     + AddressBookList     + [ name ];&lt;br /&gt;
                MailAddressList     = (MailAddressList=[])     + MailAddressList     + [ addressstr ];&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;No valid mail address for &#039;&amp;quot; + name &lt;br /&gt;
                    + &amp;quot;&#039;. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                    + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name &lt;br /&gt;
                + &amp;quot;&#039; already defined. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // Group&lt;br /&gt;
    {&lt;br /&gt;
        string group=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(group) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + group &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ group ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(GroupList, [ group ]) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                string names=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
                list   namelist=llCSV2List(names);&lt;br /&gt;
                integer num=llGetListLength(namelist);&lt;br /&gt;
                integer i;&lt;br /&gt;
                integer index;&lt;br /&gt;
                string  name;&lt;br /&gt;
                string  namestr=&amp;quot;&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
                for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                    name=llList2String(namelist,i);&lt;br /&gt;
                    index=llListFindList(AddressBookList, [ name ]);&lt;br /&gt;
            &lt;br /&gt;
                    if (index == -1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name + &amp;quot;&#039; defined in Group &#039;&amp;quot; &lt;br /&gt;
                                + group + &amp;quot;&#039; not found in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY); &lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        namestr = (namestr=&amp;quot;&amp;quot;) + namestr + name + &amp;quot;,&amp;quot;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (namestr != &amp;quot;&amp;quot;)&lt;br /&gt;
                {    &lt;br /&gt;
                    namestr=llGetSubString(namestr,0,-2);&lt;br /&gt;
                    GroupList         = (GroupList=[])         + GroupList     + [ group ];&lt;br /&gt;
                    GroupNameList     = (GroupNameList=[])    + GroupNameList + [ namestr ];&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                        + &amp;quot;&#039; has no valid names. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                        + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                    + &amp;quot;&#039; already defined in Group. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                    + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group&lt;br /&gt;
                + &amp;quot;&#039; already defined in Address Book. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// GetGroupAddressList ///////////////&lt;br /&gt;
&lt;br /&gt;
string GetGroupAddressList(string group)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(GroupList, [ group ]);&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(GroupList);&lt;br /&gt;
    string  grouplist=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        for (i = index; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2String(GroupList,i) == group)&lt;br /&gt;
            {&lt;br /&gt;
                grouplist = (grouplist=&amp;quot;&amp;quot;) + grouplist + llList2String(GroupNameList,i) + &amp;quot;,&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (grouplist != &amp;quot;&amp;quot;) grouplist=llGetSubString(grouplist,0,-2);   // remove last &amp;quot;,&amp;quot;&lt;br /&gt;
        return grouplist;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// SetMailAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetMailAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ address ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        index=llListFindList(GroupList, [ address ]);&lt;br /&gt;
        &lt;br /&gt;
        if (index == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llToUpper(address) == STRING_SELF)&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = GetSelfAddress();&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if(ValidMailAddress(address))&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = address;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Mail adress &amp;quot; + address &lt;br /&gt;
                            + &amp;quot; : not found in adress book or invalid format.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailAddress = GetGroupAddressList(address);&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        CurrentMailAddress = llList2String(MailAddressList,index);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                        + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string message)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No mail address defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No subject defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list mailaddresslist=llCSV2List(CurrentMailAddress);&lt;br /&gt;
        integer num=llGetListLength(mailaddresslist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(mailaddresslist,i);&lt;br /&gt;
            llEmail(address, CurrentMailSubject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMailHome() ////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMailHome(string message, string subject)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, STRING_HOME &lt;br /&gt;
                + &amp;quot; not set. Set your home adress with @HOME &amp;lt;address&amp;gt;.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        string homeaddress=llList2String(AddressBookList,index);&lt;br /&gt;
        list   homelist=llCSV2List(homeaddress);&lt;br /&gt;
        integer num=llGetListLength(homelist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(homelist,i);&lt;br /&gt;
            llEmail(address, subject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
string GetHomeAddress()&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;not set&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2String(MailAddressList,index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetHomeAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        AddressBookList     = (AddressBookList=[]) + [ STRING_HOME ] + AddressBookList;&lt;br /&gt;
        MailAddressList     = (MailAddressList=[]) + [ GetAndCheckAddressStr(address) ]  + MailAddressList;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MailAddressList = llListReplaceList(MailAddressList, [ GetAndCheckAddressStr(address) ], index, index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        Line=0;&lt;br /&gt;
        Section=0;&lt;br /&gt;
        llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// dataserver() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqAddressBook)&lt;br /&gt;
        {&lt;br /&gt;
            reqAddressBook = NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                ProcessLine(data);&lt;br /&gt;
                reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Address Book loaded.&amp;quot;, NULL_KEY);&lt;br /&gt;
                state running;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// timer() ///////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_ERROR, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Could not read Address Book: &amp;quot; &lt;br /&gt;
                            + ADDRESSBOOK_NOTECARD + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// link_message() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_MESSAGE_GETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is empty.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailSubject = message;&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is empty.&amp;quot;, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            SetMailAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Body of message to send is empty. &amp;quot; &lt;br /&gt;
                                +  &amp;quot;No mail is send.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SENDHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SendMailHome(message, (string)id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetInventoryType(message) == INVENTORY_NOTECARD)&lt;br /&gt;
            {&lt;br /&gt;
                Notecard2Fetch = message;                &lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_READ, message, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + message + &amp;quot; not found.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_NOTECARD_FETCHED)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + Notecard2Fetch &lt;br /&gt;
                            + &amp;quot; was empty or could not be read.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Home address is: &amp;quot; + GetHomeAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SetHomeAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_INFO)&lt;br /&gt;
        {&lt;br /&gt;
            Info();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
// End SL Mail AddressBook V1.2.lsl&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail FetchNotecard V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch the contents of a notecard and return it via link message as a string.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Notecard&lt;br /&gt;
&lt;br /&gt;
integer Line=0;&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
key     reqNotecard=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=10.0;&lt;br /&gt;
integer Fetched=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Lines&lt;br /&gt;
&lt;br /&gt;
list LineList=[];&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    /////////////////////// dataserver() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqNotecard)&lt;br /&gt;
        {&lt;br /&gt;
            reqNotecard=NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                LineList = (LineList=[]) + LineList + [ data ];&lt;br /&gt;
                reqNotecard = llGetNotecardLine(Notecard2Fetch, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Fetched=TRUE;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, llDumpList2String(LineList, &amp;quot;\n&amp;quot;), NULL_KEY);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /////////////////////// timer() ///////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        if (!Fetched)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            llSetTimerEvent(0.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer send, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_NOTECARD_READ)&lt;br /&gt;
        {&lt;br /&gt;
            Line=0;&lt;br /&gt;
            Notecard2Fetch=message;&lt;br /&gt;
            LineList=[];&lt;br /&gt;
            Fetched=FALSE;&lt;br /&gt;
            reqNotecard=llGetNotecardLine(Notecard2Fetch, Line);&lt;br /&gt;
            llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL OnlineStatus V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch online status of owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Online status&lt;br /&gt;
&lt;br /&gt;
key     reqOnlineStatus=NULL_KEY;&lt;br /&gt;
float   STATUS_INTERVAL=2.0;&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_STATUS_ONLINE       = 30000;&lt;br /&gt;
integer MS_STATUS_OFFLINE       = 30100;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus=llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
        llSetTimerEvent(STATUS_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// dataserver() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqOnlineStatus)&lt;br /&gt;
        {&lt;br /&gt;
            reqOnlineStatus = NULL_KEY;&lt;br /&gt;
        &lt;br /&gt;
            if (data==&amp;quot;1&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_STATUS_ONLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if (data==&amp;quot;0&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MS_STATUS_OFFLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus = llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Help V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Display help information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail Help V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP    = 10000;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Help() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Help()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;HELP for SL Mail V1.2.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;COMMANDS:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HELP               - displays help info.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@INFO               - display mailaddress of this object.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RECORD             - start recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CONTINUE           - continue recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@STOP               - stop recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@IGNORE             - ignore the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SHOW               - show what your recorded.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SEND               - send the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@MAIL &amp;lt;mailadress&amp;gt;  - set the mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SUBJECT subject    - set the mail subject.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LIST               - list messages in mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SELECT &amp;lt;message&amp;gt;   - select message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@READ               - read current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@NEXT               - read next message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@PREV               - read previous message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@FIRST              - read first message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LAST               - read last message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@DELETE             - delete current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CLEAR              - clear the mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@REPLY              - reply to current message.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RESET              - reset the script.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HOME               - set the home mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@OFF                - switch mailbox OFF.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@ON                 - switch mailbox ON.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_HELP)&lt;br /&gt;
        {&lt;br /&gt;
            Help();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail Help V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}&lt;/div&gt;</description>
			<pubDate>Sun, 07 Oct 2007 12:09:50 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:SL_Mail_V1.2</comments>
		</item>
		<item>
			<title>SL Mail V1.2</title>
			<link>https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34599</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34599</guid>
			<description>&lt;p&gt;Flennan Roffo: /* &amp;#039;&amp;#039;&amp;#039;Second Life mail client&amp;#039;&amp;#039;&amp;#039; */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}} __NOTOC__&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=&#039;&#039;&#039;Second Life mail client&#039;&#039;&#039;=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Send and receive email from within Second Life from and to any address.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implemented with Address Book function (in a notecard named &#039;Address Book&#039;) to stores addresses by name  and to compile groups of named addresses. Current version is stand-alone (no server functionality) and uses chat commands only.&lt;br /&gt;
&lt;br /&gt;
{{Click&lt;br /&gt;
| image=BannerSLMail.jpg&lt;br /&gt;
| width=500px&lt;br /&gt;
| height=100px&lt;br /&gt;
| link=http://slmail.info&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.slmail.info slmail.info] (website coming soon!)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Release Notes V1.2=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 Release notes (edition 2, 4 sept 2007)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LICENCE INFO&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is released under GNU free software licence&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;PRODUCTION &amp;amp; MAINTANENCE&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
by Logic Scripted Products and Script Services&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.logicscripts.org logicscripts.org] (website coming soon!)&lt;br /&gt;
&lt;br /&gt;
SLurl:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Contact: [[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
&lt;br /&gt;
Email: [mailto:info@slmail.info &#039;&#039;&#039;info&#039;&#039;&#039;] or [mailto:Flennan.Roffo@slmail.info &#039;&#039;&#039;Flennan Roffo&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;DESCRIPTION&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is a simple tool to send and receive mail from within SL.&lt;br /&gt;
You can either compose a message yourself using chat recording, or choose a notecard from inventory to send. The Address Book functionality allows you to use short names for mail recipients stored in a notecard. The current version does not have a persisent mail address. Watch out for the upcoming next release (V1.3) which will facilitate persisent in-world mail addresses and will be enhanced with many new features (See: Requests For Change (RFC).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;COMMANDS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Help&#039;&#039;&#039;&lt;br /&gt;
||Show Help about available commands&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Record&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording (for owner only).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Stop&#039;&#039;&#039;&lt;br /&gt;
||Stops the chat recording without sending&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Continue&#039;&#039;&#039;&lt;br /&gt;
||Continues a previously stopped chat recording. Lines will be appended to you recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Show&#039;&#039;&#039;&lt;br /&gt;
||Shows the content of the recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send&#039;&#039;&#039;&lt;br /&gt;
||If recording, stops the recording, and sends the mail (need to supply mail address and subject first!)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send &amp;lt;notecard&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Sends the content of the notecard, instead of the chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Ignore&#039;&#039;&#039;&lt;br /&gt;
||Ignores your current chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject &amp;lt;subject&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the subject of the mail.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail subject.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Set the HOME address of the owner (mail will be forwarder to this address when offline).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home&#039;&#039;&#039;&lt;br /&gt;
||Show the HOME address.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Info&#039;&#039;&#039;&lt;br /&gt;
||Shows the mail address the object this script is running in uses (e.g. &amp;lt;object-key&amp;gt;@lsl.secondlife.com).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Read&#039;&#039;&#039;&lt;br /&gt;
||Reads the current message from the mail buffer (the mail buffer gets filled with mail you receive)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Select &amp;lt;msg&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Select a message number from the availabe messages in the mail buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Next&#039;&#039;&#039;&lt;br /&gt;
||Make next message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Prev&#039;&#039;&#039;&lt;br /&gt;
||Make previous message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@First&#039;&#039;&#039;&lt;br /&gt;
||Make the first message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Last&#039;&#039;&#039;&lt;br /&gt;
||Make the last message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Clear&#039;&#039;&#039;&lt;br /&gt;
||Clear the mail buffer&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Delete&#039;&#039;&#039;&lt;br /&gt;
||Deletes only the current message&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Reply&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording to reply to the current message. Mail adress and subject are filled in automatically.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* Commands are case insensitive (&amp;quot;@read&amp;quot; == &amp;quot;@READ&amp;quot;). Arguments might not be case insensitive.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;ADDRESS BOOK FORMAT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
A notecard of the name &#039;Address Book&#039; is read during initialization which may contain Address Book items and Groups.&lt;br /&gt;
The notecard is split in two sections, which need to be defined in that particular order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[ADDRESS BOOK]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Defines the section in which you can put names for mail addresses,  like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name1=account@thisdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name2=user@otherdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[GROUP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define groups of previously defined names under a new name, like for instance:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyGroup=Name1, Name2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note that names of groups and individual mail adresses share the same namespace and must be unique.&lt;br /&gt;
&lt;br /&gt;
So when you filled in your mail adresses in the Address Book, you can now use:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail Name1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to  &amp;lt;account@thisdomain.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail MyGroup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to &amp;lt;account@thisdomain.com&amp;gt; and &amp;lt;user@otherdomain.com&amp;gt;&lt;br /&gt;
Mails will be sent one after another.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* Names for Addreses and Groups are case insensitive (e.g. &amp;quot;mary&amp;quot;  == &amp;quot;MARY&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* The special address &#039;Self&#039; can be used in commands where otherwise an address specification can be used. &#039;Self&#039; is case insensitive (e.g. &amp;quot;self&amp;quot; == &amp;quot;SELF&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LIMITATIONS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
The current version is limited by the following:&lt;br /&gt;
&lt;br /&gt;
* Chat recording lines are limited by the 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Output of lines from the mail buffer are also limited by this 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Incoming mail is limited to a 1000 (1024?) byte limit&lt;br /&gt;
&lt;br /&gt;
* Outgoing mai is limited by a 4096 byte limit, which includes the standard mail header (region/location info on the first two lines)&lt;br /&gt;
&lt;br /&gt;
We are making adjustments to this release to help overcome these limitations. At least the line lenght limit can be overcome by introducing a line continuation character (for example a hyphen &#039;-&#039;) that when used at the end of a line appends the next line, so lines longer then 255 bytes are possible then.&lt;br /&gt;
&lt;br /&gt;
To overcome the outgoing mail length limit, the mail can be broken textualy into parts, and each part can be send seperatedely, with an indication in the subject or in an introduced primary line of the mail body to indicate that the mail was split into parts.&lt;br /&gt;
For incoming mail and at least to receive mail from other SL Mail programs, a protocol will be introduced to receive mail in parts that are joined together after receiving them to form a single mail.&lt;br /&gt;
&lt;br /&gt;
These enhancements will be made available in the next release (V1.3) of SL Mail &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;BUGS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Report any bugs you find in this release to Logic (IM: Flennan Roffo).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;REQUEST FOR CHANGE (RFC)&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Do you have additional wishes for enhancement of this product?&lt;br /&gt;
Contact Flennan Roffo and we will see if they can be implemented in the next release.&lt;br /&gt;
&lt;br /&gt;
Existing RFC&#039;s are:&lt;br /&gt;
&lt;br /&gt;
* Menu support for commands.&lt;br /&gt;
&lt;br /&gt;
* Lines on incoming/outgoing mail longer than 255 bytes.&lt;br /&gt;
&lt;br /&gt;
* Send messages longer than 4096 (minus SL mail header) bytes.&lt;br /&gt;
&lt;br /&gt;
* Receive messages longer than 1024 bytes.&lt;br /&gt;
&lt;br /&gt;
* Permanent mail addresses for the SL Mail client (like: &amp;lt;Flennan.Roffo@somedomain.sl&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Add your RFC!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In-world join the group &amp;quot;SL Mail&amp;quot; for bug reports, feature requests, the latest SL Mail release, and notices about development issues.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scripts=&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==Script: SL Mail v1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail core module which scans for incoming mail messages and executes commands used by the owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail V1.2.lsl&lt;br /&gt;
// (c) 2007 Logic Scripted Products and Script Services&lt;br /&gt;
// Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
// VERSION&lt;br /&gt;
// Version: 1.2&lt;br /&gt;
&lt;br /&gt;
// HISTORY&lt;br /&gt;
// Date         Version     Author              Comment&lt;br /&gt;
// --------------------------------------------------------------------------------------&lt;br /&gt;
// 28 aug 2007  V 1.0       Flennan Roffo       Created&lt;br /&gt;
//&lt;br /&gt;
//  1 sep 2007  V 1.1       Flennan Roffo       @Reply empties the recording buffer.&lt;br /&gt;
//                                                @Send while recording ends recording&lt;br /&gt;
//                                                and sends the mail if a mail address&lt;br /&gt;
//                                                and subject are supplied.&lt;br /&gt;
//                                                Fixed incorrect date in Unix2DateTime.&lt;br /&gt;
//  3 sep 2007  V 1.2       Flennan Roffo       Notification options:&lt;br /&gt;
//                                              - When online, send an IM when mail is received.&lt;br /&gt;
//                                              - When offline, send to HOME mail adress.&lt;br /&gt;
//                                              Adressbook&lt;br /&gt;
//                                              - Read adress book from config notecard.&lt;br /&gt;
&lt;br /&gt;
// LICENCE&lt;br /&gt;
// This program is free software; you can redistribute it and/or&lt;br /&gt;
// modify it under the terms of the GNU General Public License&lt;br /&gt;
// as published by the Free Software Foundation; either version 2&lt;br /&gt;
// of the License, or (at your option) any later version.&lt;br /&gt;
// &lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
// &lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program; if not, write to the Free Software&lt;br /&gt;
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
// (Also available at http://www.gnu.org/copyleft/gpl.html) &lt;br /&gt;
&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// Let&#039;s you record a message and sent to email and get messages and reply to messages.&lt;br /&gt;
// Must supply a valid mail adress and non-empty subject using chat commands.&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
// 1) Check for the maximum length of an email message (including newline and header).&lt;br /&gt;
// 2) Read adress book from notecard.                                    *DONE*&lt;br /&gt;
// 3) Send incoming mail to personal mail adress when offline.            *DONE*&lt;br /&gt;
// 4) Alert with an IM when online upon receiving new mail.                *DONE*&lt;br /&gt;
&lt;br /&gt;
string   SL_MAIL_VERSION = &amp;quot;V 1.2&amp;quot;;&lt;br /&gt;
string   SL_MAIL_DATE    = &amp;quot; 2 sep 2007&amp;quot;;&lt;br /&gt;
integer  ErrorFlag         = FALSE;&lt;br /&gt;
list     ScriptList        = [ &amp;quot;SL Mail Help V1.2&amp;quot;, &amp;quot;SL Mail AddressBook V1.2&amp;quot;, &lt;br /&gt;
                                &amp;quot;SL Mail OnlineStatus V1.2&amp;quot;, &amp;quot;SL Mail FetchNotecard V1.2&amp;quot; ];    &lt;br /&gt;
string   LSL_DOMAIN=&amp;quot;lsl.secondlife.com&amp;quot;; &lt;br /&gt;
integer  StatusOnline=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Commands&lt;br /&gt;
&lt;br /&gt;
string  COMMAND_RECORD     = &amp;quot;@RECORD&amp;quot;;&lt;br /&gt;
string  COMMAND_CONTINUE   = &amp;quot;@CONTINUE&amp;quot;;&lt;br /&gt;
string  COMMAND_STOP       = &amp;quot;@STOP&amp;quot;;&lt;br /&gt;
string  COMMAND_MAIL       = &amp;quot;@MAIL&amp;quot;;&lt;br /&gt;
string  COMMAND_SUBJECT    = &amp;quot;@SUBJECT&amp;quot;;&lt;br /&gt;
string  COMMAND_SEND       = &amp;quot;@SEND&amp;quot;;&lt;br /&gt;
string  COMMAND_SEE        = &amp;quot;@SEE&amp;quot;;&lt;br /&gt;
string  COMMAND_IGNORE     = &amp;quot;@IGNORE&amp;quot;;&lt;br /&gt;
string  COMMAND_READ       = &amp;quot;@READ&amp;quot;;&lt;br /&gt;
string  COMMAND_DELETE     = &amp;quot;@DELETE&amp;quot;;&lt;br /&gt;
string  COMMAND_CLEAR      = &amp;quot;@CLEAR&amp;quot;;&lt;br /&gt;
string  COMMAND_REPLY      = &amp;quot;@REPLY&amp;quot;;&lt;br /&gt;
string  COMMAND_NEXT       = &amp;quot;@NEXT&amp;quot;;&lt;br /&gt;
string  COMMAND_PREV       = &amp;quot;@PREV&amp;quot;;&lt;br /&gt;
string  COMMAND_FIRST      = &amp;quot;@FIRST&amp;quot;;&lt;br /&gt;
string  COMMAND_LAST       = &amp;quot;@LAST&amp;quot;;&lt;br /&gt;
string  COMMAND_LIST       = &amp;quot;@LIST&amp;quot;;&lt;br /&gt;
string  COMMAND_SELECT     = &amp;quot;@SELECT&amp;quot;;&lt;br /&gt;
string  COMMAND_HELP       = &amp;quot;@HELP&amp;quot;;&lt;br /&gt;
string  COMMAND_INFO       = &amp;quot;@INFO&amp;quot;;&lt;br /&gt;
string  COMMAND_RESET      = &amp;quot;@RESET&amp;quot;;&lt;br /&gt;
string  COMMAND_SHOW       = &amp;quot;@SHOW&amp;quot;;&lt;br /&gt;
string  COMMAND_ON         = &amp;quot;@ON&amp;quot;;&lt;br /&gt;
string  COMMAND_OFF        = &amp;quot;@OFF&amp;quot;;&lt;br /&gt;
string  COMMAND_HOME       = &amp;quot;@HOME&amp;quot;;&lt;br /&gt;
string  COMMAND_LOAD       = &amp;quot;@LOAD&amp;quot;;&lt;br /&gt;
string  COMMAND_ADDRESS    = &amp;quot;@ADDRESS&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Recording&lt;br /&gt;
&lt;br /&gt;
integer Recording = FALSE;&lt;br /&gt;
&lt;br /&gt;
list    ChatRecording=[];&lt;br /&gt;
integer NumLines=0;&lt;br /&gt;
integer Length=0;&lt;br /&gt;
&lt;br /&gt;
list     TimeList=[];&lt;br /&gt;
list     AddressList=[];&lt;br /&gt;
list     SubjectList=[];&lt;br /&gt;
list     BodyList=[];&lt;br /&gt;
integer  NumMessages=0;&lt;br /&gt;
integer  CurrentMessage=-1;&lt;br /&gt;
&lt;br /&gt;
float    MAIL_FETCH_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
// Link Messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP                        = 10000;&lt;br /&gt;
integer MSG_STATUS_ONLINE               = 30000;&lt;br /&gt;
integer MSG_STATUS_OFFLINE              = 30100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED          = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR           = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Unix Time conversion //////////////////&lt;br /&gt;
&lt;br /&gt;
integer DAYS_PER_YEAR        = 365;                // Non leap year&lt;br /&gt;
integer SECONDS_PER_YEAR     = 31536000;          // Non leap year&lt;br /&gt;
integer SECONDS_PER_DAY      = 86400;&lt;br /&gt;
integer SECONDS_PER_HOUR     = 3600;&lt;br /&gt;
integer SECONDS_PER_MINUTE   = 60;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// LeapYear() /////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer LeapYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (year % 4 == 0)&lt;br /&gt;
    {&lt;br /&gt;
        if (year % 100 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (year % 400 == 0)&lt;br /&gt;
            {&lt;br /&gt;
                return 1;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// DaysPerMonth() ///////////////////////////////////////&lt;br /&gt;
                &lt;br /&gt;
integer DaysPerMonth(integer year,integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;lt; 8)&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (month == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if (LeapYear(year))&lt;br /&gt;
                {&lt;br /&gt;
                    return 29;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    return 28;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 30;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 30;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////// DaysPerYear() ////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DaysPerYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (LeapYear(year))&lt;br /&gt;
        return DAYS_PER_YEAR + 1;&lt;br /&gt;
    else&lt;br /&gt;
        return DAYS_PER_YEAR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Unix2DataTime() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list Unix2DateTime(integer unixtime)&lt;br /&gt;
{&lt;br /&gt;
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;&lt;br /&gt;
    integer day = days_since_1_1_1970 + 1;&lt;br /&gt;
    integer year  = 1970;&lt;br /&gt;
    integer days_per_year = DaysPerYear(year);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_year)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_year;&lt;br /&gt;
        ++year;&lt;br /&gt;
        days_per_year = DaysPerYear(year);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer month = 1;&lt;br /&gt;
    integer days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_month)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_month;&lt;br /&gt;
        &lt;br /&gt;
        if (++month &amp;gt; 12)&lt;br /&gt;
        {    &lt;br /&gt;
            ++year;&lt;br /&gt;
            month = 1;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;&lt;br /&gt;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;&lt;br /&gt;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;&lt;br /&gt;
    integer minute      = second / SECONDS_PER_MINUTE;&lt;br /&gt;
    second               = second % SECONDS_PER_MINUTE;&lt;br /&gt;
    &lt;br /&gt;
    return [ year, month, day, hour, minute, second ];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// MonthName() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list MonthNameList = [     &amp;quot;JAN&amp;quot;, &amp;quot;FEB&amp;quot;, &amp;quot;MAR&amp;quot;, &amp;quot;APR&amp;quot;, &amp;quot;MAY&amp;quot;, &amp;quot;JUN&amp;quot;, &lt;br /&gt;
                        &amp;quot;JUL&amp;quot;, &amp;quot;AUG&amp;quot;, &amp;quot;SEP&amp;quot;, &amp;quot;OCT&amp;quot; , &amp;quot;NOV&amp;quot;, &amp;quot;DEC&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
string MonthName(integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;gt;= 0 &amp;amp;&amp;amp; month &amp;lt; 12)&lt;br /&gt;
        return llList2String(MonthNameList, month);&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// DateString() ///////////////////////////&lt;br /&gt;
&lt;br /&gt;
string DateString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer year       = llList2Integer(timelist,0);&lt;br /&gt;
    integer month      = llList2Integer(timelist,1);&lt;br /&gt;
    integer day        = llList2Integer(timelist,2);&lt;br /&gt;
    &lt;br /&gt;
    return (string)day + &amp;quot;-&amp;quot; + MonthName(month - 1) + &amp;quot;-&amp;quot; + (string)year;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// TimeString() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string TimeString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer hour          = llList2Integer(timelist,3);&lt;br /&gt;
    integer minute         = llList2Integer(timelist,4);&lt;br /&gt;
    integer second         = llList2Integer(timelist,5);&lt;br /&gt;
    string  hourstr     = (string)hour;&lt;br /&gt;
    string  minutestr   = (string)minute;&lt;br /&gt;
    string  secondstr   = (string)second;&lt;br /&gt;
    &lt;br /&gt;
    if (hour &amp;lt; 10)         hourstr     = &amp;quot;0&amp;quot; + hourstr;&lt;br /&gt;
    if (minute &amp;lt; 10)     minutestr     = &amp;quot;0&amp;quot; + minutestr;&lt;br /&gt;
    if (second &amp;lt; 10)    secondstr    = &amp;quot;0&amp;quot; + secondstr;&lt;br /&gt;
    return hourstr + &amp;quot;:&amp;quot; + minutestr + &amp;quot;:&amp;quot; + secondstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() /////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string body)&lt;br /&gt;
{&lt;br /&gt;
    // llOwnerSay(&amp;quot;Sending message to &#039;&amp;quot; + address + &amp;quot;&#039; with subject &#039;&amp;quot; + subject +&amp;quot;&#039;.&amp;quot;);&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND, body, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// SendHome() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendHome(string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SENDHOME, body, (key)subject);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Show() ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Show()&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;Current chat recording is:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; NumLines; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(ChatRecording,i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;Lines is &amp;quot; + (string)NumLines);&lt;br /&gt;
    llOwnerSay(&amp;quot;Message length is &amp;quot; + (string)Length);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Read() /////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Read()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;Reading message &amp;quot; + (string)CurrentMessage + &amp;quot; from mail buffer.&amp;quot;);&lt;br /&gt;
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);&lt;br /&gt;
    list timelist=Unix2DateTime(time);&lt;br /&gt;
    string Address = llList2String(AddressList,CurrentMessage);&lt;br /&gt;
    string Subject = llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
    string Body    = llList2String(BodyList,CurrentMessage);&lt;br /&gt;
    llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Address: &amp;quot; + Address);&lt;br /&gt;
    llOwnerSay(&amp;quot;Subject: &amp;quot; + Subject);&lt;br /&gt;
    llOwnerSay(&amp;quot;Begin of message body:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    list bodylist=llParseStringKeepNulls(Body, [ &amp;quot;\n&amp;quot; ], []);&lt;br /&gt;
    integer num=llGetListLength(bodylist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(bodylist,i));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;End of message body.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////// List ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
List()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;The mail buffer contains the following messages:\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; NumMessages; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer time=llList2Integer(TimeList,i);&lt;br /&gt;
        list timelist=Unix2DateTime(time);&lt;br /&gt;
        if (i &amp;gt; 0) llOwnerSay(&amp;quot;+-+-+-+-+-+-+-+-+-+-+-+-&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Message: &amp;quot; + (string)i);&lt;br /&gt;
        llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;From:    &amp;quot; + llList2String(AddressList,i));&lt;br /&gt;
        llOwnerSay(&amp;quot;Subject: &amp;quot; + llList2String(SubjectList,i));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////// NotifyNewMail() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
NotifyNewMail(string time, string address, string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    list timelist=Unix2DateTime((integer)time);&lt;br /&gt;
&lt;br /&gt;
    if (StatusOnline)&lt;br /&gt;
    {&lt;br /&gt;
        llInstantMessage(llGetOwner(), &amp;quot;You received a new mail message on &amp;quot; &lt;br /&gt;
                                    + DateString(timelist) + &amp;quot; at &amp;quot; + TimeString(timelist)&lt;br /&gt;
                                    + &amp;quot; from &amp;quot; + address &lt;br /&gt;
                                    + &amp;quot; with the subject &amp;quot; + subject);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        SendHome(&amp;quot;FW: &amp;quot; + subject, &amp;quot;Received at: &amp;quot; + DateString(timelist) + &amp;quot; &amp;quot; + TimeString(timelist) + &amp;quot;\nFrom: &amp;quot; +  address &lt;br /&gt;
                    + &amp;quot;\nBegin message body:\n-------------------\n&amp;quot; + body + &amp;quot;\n-------------------\nEnd message body.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ResetOtherScripts() //////////////////////&lt;br /&gt;
&lt;br /&gt;
ResetOtherScripts()&lt;br /&gt;
{&lt;br /&gt;
    string     name;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(ScriptList);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        name = llList2String(ScriptList,i);&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(name) == INVENTORY_SCRIPT)&lt;br /&gt;
        {&lt;br /&gt;
            llResetOtherScript(name);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Error - script &#039;&amp;quot; + name + &amp;quot;&#039; not found.&amp;quot;);&lt;br /&gt;
            ErrorFlag = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
// default &lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ////////////////////// state_entry() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Welcome to SL Mail, released under GNU software licence.&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Version &amp;quot; + SL_MAIL_VERSION + &amp;quot; &amp;quot; + SL_MAIL_DATE);&lt;br /&gt;
        llOwnerSay(&amp;quot;Produced by Logic Scripted Products &amp;amp; Product Services&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Free memory: &amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
        ResetOtherScripts();&lt;br /&gt;
        &lt;br /&gt;
        if (ErrorFlag)&lt;br /&gt;
            state Error;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// on_rez() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// changed() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_LOADED)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_ERROR)&lt;br /&gt;
        {&lt;br /&gt;
            state Error;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() //////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(MAIL_FETCH_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //////////////////////// on_rez() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// listen() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string trimmessage=llStringTrim(message,STRING_TRIM);&lt;br /&gt;
        list   parse = llParseStringKeepNulls(trimmessage, [ &amp;quot; &amp;quot;], []);&lt;br /&gt;
        string command = llToUpper(llList2String(parse,0));&lt;br /&gt;
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        integer nargs  = llGetListLength(parse);&lt;br /&gt;
        string argstr=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (nargs &amp;gt; 1) argstr=llGetSubString(message, llSubStringIndex(message, &amp;quot; &amp;quot;) + 1, -1);&lt;br /&gt;
            &lt;br /&gt;
        if (Recording)&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Recording stopped. Type @SHOW to see the message you have entered,&amp;quot;&lt;br /&gt;
                            + &amp;quot; or @SEND to send it.&amp;quot;);&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                &lt;br /&gt;
                SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];&lt;br /&gt;
                ++NumLines;&lt;br /&gt;
                Length += llStringLength(message) + 2;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_RECORD)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Start recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                ChatRecording = [];&lt;br /&gt;
                NumLines=0;&lt;br /&gt;
                Length=0;&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CONTINUE)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Continue recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_REPLY)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    string address=llList2String(AddressList,CurrentMessage);&lt;br /&gt;
                    string subject=&amp;quot;Re: &amp;quot; + llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, address, NULL_KEY);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, subject, NULL_KEY);&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines=0;&lt;br /&gt;
                    Length=0;&lt;br /&gt;
                    Recording = TRUE;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_MAIL)&lt;br /&gt;
            {&lt;br /&gt;
                string mailaddress=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailaddress != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, mailaddress, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETADDRESS, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SUBJECT)&lt;br /&gt;
            {&lt;br /&gt;
                string mailsubject=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailsubject != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, mailsubject, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETSUBJECT, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Not recording.&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    if (NumLines == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND_NOTECARD, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_IGNORE)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines = 0;&lt;br /&gt;
                    Length = 0;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Show();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_READ)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumMessages == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Read();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        ++CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        --CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_FIRST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = 0;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LAST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LIST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    List();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SELECT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;Need to supply a message number.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    integer msgnum = (integer)arg;&lt;br /&gt;
                     &lt;br /&gt;
                    if (msgnum &amp;lt; 0 || msgnum &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Message number &amp;quot; + arg + &amp;quot; not in mail buffer.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = msgnum;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_DELETE)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    --NumMessages;&lt;br /&gt;
                     &lt;br /&gt;
                    if (NumMessages == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = -1;&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (CurrentMessage &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CLEAR)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList=[];&lt;br /&gt;
                    AddressList=[];&lt;br /&gt;
                    SubjectList=[];&lt;br /&gt;
                    BodyList=[];&lt;br /&gt;
                    NumMessages=0;&lt;br /&gt;
                    CurrentMessage=-1;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_HELP, arg, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_INFO)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                Show();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_RESET)&lt;br /&gt;
            {&lt;br /&gt;
                llResetScript();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                state not_running;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HOME)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs==1)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETHOME, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETHOME, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// email() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    email(string time, string address, string subject, string body, integer queued)&lt;br /&gt;
    {&lt;br /&gt;
        NotifyNewMail(time, address, subject, body);&lt;br /&gt;
        TimeList = (TimeList=[]) + TimeList + [time];&lt;br /&gt;
        AddressList = (AddressList=[]) + AddressList + [address];&lt;br /&gt;
        SubjectList = (SubjectList=[]) + SubjectList + [subject];&lt;br /&gt;
        BodyList = (BodyList=[]) + BodyList + [body];&lt;br /&gt;
        ++NumMessages;&lt;br /&gt;
        &lt;br /&gt;
        if (CurrentMessage == -1)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = NumMessages - 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_REPLY)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state not_running&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state not_running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;SL Mailbox switched OFF. Say @ON to switch it back on.&amp;quot;);&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// on_rez() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// listen() ////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer chan, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string command=llToUpper(message);&lt;br /&gt;
        &lt;br /&gt;
        if (command == COMMAND_ON)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state Error&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state Error&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Error in SL Mail: not all component scripts found.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// End SL Mail V1.2.lsl&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Address Book V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Read and interpret the contents of the Address Book.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail AddressBook V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// &lt;br /&gt;
//  Read the Address Book from a notecard named &amp;quot;Address Book&amp;quot;.&lt;br /&gt;
//&lt;br /&gt;
//  The Address Book has the following format:&lt;br /&gt;
//  &lt;br /&gt;
//  [ADDRESS BOOK]&lt;br /&gt;
//  Name1=username@yourdomain.com&lt;br /&gt;
//  Name2=otheruser@otherdomain.com&lt;br /&gt;
//  ...&lt;br /&gt;
//  [GROUP]&lt;br /&gt;
//  group1=Name1, Name2&lt;br /&gt;
//  ...&lt;br /&gt;
//&lt;br /&gt;
//  Notes:&lt;br /&gt;
//  1. Group and Name share the same namespace, and must be unique.&lt;br /&gt;
//  2. It is allowed to have a name in the addressbook with multiple addresses, seperated by comma&#039;s.&lt;br /&gt;
// &lt;br /&gt;
/////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string  CurrentMailAddress = &amp;quot;&amp;quot;;&lt;br /&gt;
string  CurrentMailSubject = &amp;quot;&amp;quot;;&lt;br /&gt;
integer StatusOnline = FALSE;&lt;br /&gt;
&lt;br /&gt;
// Fetch or Send notecard&lt;br /&gt;
&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Names&lt;br /&gt;
&lt;br /&gt;
list    AddressBookList=[];&lt;br /&gt;
list    MailAddressList=[];&lt;br /&gt;
&lt;br /&gt;
string  STRING_HOME=&amp;quot;HOME&amp;quot;;&lt;br /&gt;
string  STRING_SELF=&amp;quot;SELF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Groups&lt;br /&gt;
&lt;br /&gt;
list   GroupList=[];&lt;br /&gt;
list   GroupNameList=[];&lt;br /&gt;
&lt;br /&gt;
string LSL_DOMAIN = &amp;quot;lsl.secondlife.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Read Address Book notecard&lt;br /&gt;
&lt;br /&gt;
string  ADDRESSBOOK_NOTECARD=&amp;quot;Address Book&amp;quot;;&lt;br /&gt;
integer Line=0;&lt;br /&gt;
key     reqAddressBook=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
integer Section=0;&lt;br /&gt;
integer SECTION_ADDRESS_BOOK=1;&lt;br /&gt;
integer SECTION_GROUP=2;&lt;br /&gt;
string  STRING_ADDRESS_BOOK=&amp;quot;ADDRESS BOOK&amp;quot;;&lt;br /&gt;
string  STRING_GROUP=&amp;quot;GROUP&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Links messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
integer MSG_MESSAGE_NOTIFY              = 90900;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED            = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR            = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// GetSelfAddress() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
string GetSelfAddress()&lt;br /&gt;
{&lt;br /&gt;
    return (string)llGetKey() + &amp;quot;@&amp;quot; + LSL_DOMAIN;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Info() /////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Info()&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;The mail address for this object is: &amp;quot; &lt;br /&gt;
                    + GetSelfAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// IsValidKeyFormat() //////////////////////&lt;br /&gt;
&lt;br /&gt;
integer IsValidKeyFormat(string str)&lt;br /&gt;
{&lt;br /&gt;
    string keychars = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    if (llStringLength(str) != 36)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    if( (llGetSubString( str, 8, 8 )   != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 13, 13 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 18, 18 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 23, 23 )  != &amp;quot;-&amp;quot; ) )&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 9; i &amp;lt; 13; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 14; i &amp;lt; 18; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 19; i &amp;lt; 23; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 24; i &amp;lt; 36; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// ValidMailAddress() ////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer ValidMailAddress(string arg)&lt;br /&gt;
{&lt;br /&gt;
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));&lt;br /&gt;
    &lt;br /&gt;
    if (adress == &amp;quot;&amp;quot;)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    list parse = llParseStringKeepNulls(adress, [ &amp;quot;@&amp;quot; ], []);&lt;br /&gt;
    string account = llList2String(parse,0);&lt;br /&gt;
    string domain  = llList2String(parse,1);&lt;br /&gt;
    &lt;br /&gt;
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    &lt;br /&gt;
    if (domain == LSL_DOMAIN)&lt;br /&gt;
    {&lt;br /&gt;
        return IsValidKeyFormat(account);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list parsedomain = llParseString2List(domain, [ &amp;quot;.&amp;quot; ], []);&lt;br /&gt;
    &lt;br /&gt;
        if (llGetListLength(parsedomain) &amp;lt; 2)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        &lt;br /&gt;
        integer num = llGetListLength(parsedomain);&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llStringLength(llList2String(parsedomain,i)) &amp;lt; 2)&lt;br /&gt;
            {&lt;br /&gt;
                return FALSE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetAddressStr() ///////////////////&lt;br /&gt;
&lt;br /&gt;
string GetAndCheckAddressStr(string address)&lt;br /&gt;
{&lt;br /&gt;
    list addresslist = llCSV2List(address);&lt;br /&gt;
    integer num=llGetListLength(addresslist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    string addressstr=&amp;quot;&amp;quot;;&lt;br /&gt;
    string curaddress=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        curaddress=llList2String(addresslist,i);&lt;br /&gt;
        &lt;br /&gt;
        if (ValidMailAddress(curaddress))&lt;br /&gt;
        {&lt;br /&gt;
            addressstr = (addressstr=&amp;quot;&amp;quot;) + addressstr + curaddress + &amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address string: &#039;&amp;quot; &lt;br /&gt;
                            + curaddress + &amp;quot;&#039;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return llGetSubString(addressstr, 0, -2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ProcessLine() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
ProcessLine(string rawline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(rawline,STRING_TRIM);&lt;br /&gt;
    string first=llGetSubString(line,0,0);&lt;br /&gt;
    string last=llGetSubString(line,-1,-1);&lt;br /&gt;
    &lt;br /&gt;
    // Ignore a blank line or comment line&lt;br /&gt;
    if (line == &amp;quot;&amp;quot; || first == &amp;quot;#&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // Check for the right section&lt;br /&gt;
    &lt;br /&gt;
    if (first == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; last == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        string sectionstr=llToUpper(llStringTrim(llGetSubString(line,1,-2),STRING_TRIM));&lt;br /&gt;
        &lt;br /&gt;
        if (sectionstr == STRING_ADDRESS_BOOK)&lt;br /&gt;
        {&lt;br /&gt;
            Section = SECTION_ADDRESS_BOOK;&lt;br /&gt;
        }&lt;br /&gt;
        else if (sectionstr == STRING_GROUP)&lt;br /&gt;
        {&lt;br /&gt;
            if (Section == 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                        + &amp;quot;. Group section defined before Address Book section.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Section = SECTION_GROUP;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid section header &#039;&amp;quot; + sectionstr &lt;br /&gt;
                        + &amp;quot;&#039; in &amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Must be in a section&lt;br /&gt;
    &lt;br /&gt;
    if (Section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;. No section header.&amp;quot;, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    list     parse=llParseString2List(line, [ &amp;quot;=&amp;quot; ], []);&lt;br /&gt;
    integer  num=llGetListLength(parse);&lt;br /&gt;
    &lt;br /&gt;
    // Format must be correct&lt;br /&gt;
    &lt;br /&gt;
    if (num != 2)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; +  (string)(Line+1) + &amp;quot;:\n&amp;quot; + rawline, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (Section == SECTION_ADDRESS_BOOK)&lt;br /&gt;
    {&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(name) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + name &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ name ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            string address=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
            string addressstr=GetAndCheckAddressStr(address);&lt;br /&gt;
            &lt;br /&gt;
            if (addressstr != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                AddressBookList     = (AddressBookList=[])     + AddressBookList     + [ name ];&lt;br /&gt;
                MailAddressList     = (MailAddressList=[])     + MailAddressList     + [ addressstr ];&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;No valid mail address for &#039;&amp;quot; + name &lt;br /&gt;
                    + &amp;quot;&#039;. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                    + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name &lt;br /&gt;
                + &amp;quot;&#039; already defined. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // Group&lt;br /&gt;
    {&lt;br /&gt;
        string group=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(group) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + group &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ group ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(GroupList, [ group ]) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                string names=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
                list   namelist=llCSV2List(names);&lt;br /&gt;
                integer num=llGetListLength(namelist);&lt;br /&gt;
                integer i;&lt;br /&gt;
                integer index;&lt;br /&gt;
                string  name;&lt;br /&gt;
                string  namestr=&amp;quot;&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
                for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                    name=llList2String(namelist,i);&lt;br /&gt;
                    index=llListFindList(AddressBookList, [ name ]);&lt;br /&gt;
            &lt;br /&gt;
                    if (index == -1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name + &amp;quot;&#039; defined in Group &#039;&amp;quot; &lt;br /&gt;
                                + group + &amp;quot;&#039; not found in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY); &lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        namestr = (namestr=&amp;quot;&amp;quot;) + namestr + name + &amp;quot;,&amp;quot;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (namestr != &amp;quot;&amp;quot;)&lt;br /&gt;
                {    &lt;br /&gt;
                    namestr=llGetSubString(namestr,0,-2);&lt;br /&gt;
                    GroupList         = (GroupList=[])         + GroupList     + [ group ];&lt;br /&gt;
                    GroupNameList     = (GroupNameList=[])    + GroupNameList + [ namestr ];&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                        + &amp;quot;&#039; has no valid names. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                        + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                    + &amp;quot;&#039; already defined in Group. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                    + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group&lt;br /&gt;
                + &amp;quot;&#039; already defined in Address Book. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// GetGroupAddressList ///////////////&lt;br /&gt;
&lt;br /&gt;
string GetGroupAddressList(string group)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(GroupList, [ group ]);&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(GroupList);&lt;br /&gt;
    string  grouplist=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        for (i = index; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2String(GroupList,i) == group)&lt;br /&gt;
            {&lt;br /&gt;
                grouplist = (grouplist=&amp;quot;&amp;quot;) + grouplist + llList2String(GroupNameList,i) + &amp;quot;,&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (grouplist != &amp;quot;&amp;quot;) grouplist=llGetSubString(grouplist,0,-2);   // remove last &amp;quot;,&amp;quot;&lt;br /&gt;
        return grouplist;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// SetMailAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetMailAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ address ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        index=llListFindList(GroupList, [ address ]);&lt;br /&gt;
        &lt;br /&gt;
        if (index == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llToUpper(address) == STRING_SELF)&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = GetSelfAddress();&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if(ValidMailAddress(address))&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = address;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Mail adress &amp;quot; + address &lt;br /&gt;
                            + &amp;quot; : not found in adress book or invalid format.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailAddress = GetGroupAddressList(address);&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        CurrentMailAddress = llList2String(MailAddressList,index);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                        + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string message)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No mail address defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No subject defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list mailaddresslist=llCSV2List(CurrentMailAddress);&lt;br /&gt;
        integer num=llGetListLength(mailaddresslist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(mailaddresslist,i);&lt;br /&gt;
            llEmail(address, CurrentMailSubject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMailHome() ////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMailHome(string message, string subject)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, STRING_HOME &lt;br /&gt;
                + &amp;quot; not set. Set your home adress with @HOME &amp;lt;address&amp;gt;.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        string homeaddress=llList2String(AddressBookList,index);&lt;br /&gt;
        list   homelist=llCSV2List(homeaddress);&lt;br /&gt;
        integer num=llGetListLength(homelist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(homelist,i);&lt;br /&gt;
            llEmail(address, subject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
string GetHomeAddress()&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;not set&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2String(MailAddressList,index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetHomeAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        AddressBookList     = (AddressBookList=[]) + [ STRING_HOME ] + AddressBookList;&lt;br /&gt;
        MailAddressList     = (MailAddressList=[]) + [ GetAndCheckAddressStr(address) ]  + MailAddressList;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MailAddressList = llListReplaceList(MailAddressList, [ GetAndCheckAddressStr(address) ], index, index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        Line=0;&lt;br /&gt;
        Section=0;&lt;br /&gt;
        llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// dataserver() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqAddressBook)&lt;br /&gt;
        {&lt;br /&gt;
            reqAddressBook = NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                ProcessLine(data);&lt;br /&gt;
                reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Address Book loaded.&amp;quot;, NULL_KEY);&lt;br /&gt;
                state running;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// timer() ///////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_ERROR, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Could not read Address Book: &amp;quot; &lt;br /&gt;
                            + ADDRESSBOOK_NOTECARD + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// link_message() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_MESSAGE_GETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is empty.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailSubject = message;&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is empty.&amp;quot;, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            SetMailAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Body of message to send is empty. &amp;quot; &lt;br /&gt;
                                +  &amp;quot;No mail is send.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SENDHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SendMailHome(message, (string)id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetInventoryType(message) == INVENTORY_NOTECARD)&lt;br /&gt;
            {&lt;br /&gt;
                Notecard2Fetch = message;                &lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_READ, message, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + message + &amp;quot; not found.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_NOTECARD_FETCHED)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + Notecard2Fetch &lt;br /&gt;
                            + &amp;quot; was empty or could not be read.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Home address is: &amp;quot; + GetHomeAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SetHomeAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_INFO)&lt;br /&gt;
        {&lt;br /&gt;
            Info();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
// End SL Mail AddressBook V1.2.lsl&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail FetchNotecard V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch the contents of a notecard and return it via link message as a string.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Notecard&lt;br /&gt;
&lt;br /&gt;
integer Line=0;&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
key     reqNotecard=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=10.0;&lt;br /&gt;
integer Fetched=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Lines&lt;br /&gt;
&lt;br /&gt;
list LineList=[];&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    /////////////////////// dataserver() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqNotecard)&lt;br /&gt;
        {&lt;br /&gt;
            reqNotecard=NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                LineList = (LineList=[]) + LineList + [ data ];&lt;br /&gt;
                reqNotecard = llGetNotecardLine(Notecard2Fetch, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Fetched=TRUE;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, llDumpList2String(LineList, &amp;quot;\n&amp;quot;), NULL_KEY);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /////////////////////// timer() ///////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        if (!Fetched)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            llSetTimerEvent(0.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer send, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_NOTECARD_READ)&lt;br /&gt;
        {&lt;br /&gt;
            Line=0;&lt;br /&gt;
            Notecard2Fetch=message;&lt;br /&gt;
            LineList=[];&lt;br /&gt;
            Fetched=FALSE;&lt;br /&gt;
            reqNotecard=llGetNotecardLine(Notecard2Fetch, Line);&lt;br /&gt;
            llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL OnlineStatus V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch online status of owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Online status&lt;br /&gt;
&lt;br /&gt;
key     reqOnlineStatus=NULL_KEY;&lt;br /&gt;
float   STATUS_INTERVAL=2.0;&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_STATUS_ONLINE       = 30000;&lt;br /&gt;
integer MS_STATUS_OFFLINE       = 30100;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus=llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
        llSetTimerEvent(STATUS_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// dataserver() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqOnlineStatus)&lt;br /&gt;
        {&lt;br /&gt;
            reqOnlineStatus = NULL_KEY;&lt;br /&gt;
        &lt;br /&gt;
            if (data==&amp;quot;1&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_STATUS_ONLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if (data==&amp;quot;0&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MS_STATUS_OFFLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus = llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Help V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Display help information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail Help V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP    = 10000;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Help() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Help()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;HELP for SL Mail V1.2.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;COMMANDS:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HELP               - displays help info.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@INFO               - display mailaddress of this object.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RECORD             - start recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CONTINUE           - continue recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@STOP               - stop recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@IGNORE             - ignore the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SHOW               - show what your recorded.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SEND               - send the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@MAIL &amp;lt;mailadress&amp;gt;  - set the mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SUBJECT subject    - set the mail subject.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LIST               - list messages in mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SELECT &amp;lt;message&amp;gt;   - select message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@READ               - read current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@NEXT               - read next message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@PREV               - read previous message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@FIRST              - read first message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LAST               - read last message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@DELETE             - delete current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CLEAR              - clear the mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@REPLY              - reply to current message.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RESET              - reset the script.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HOME               - set the home mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@OFF                - switch mailbox OFF.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@ON                 - switch mailbox ON.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_HELP)&lt;br /&gt;
        {&lt;br /&gt;
            Help();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail Help V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}&lt;/div&gt;</description>
			<pubDate>Sun, 07 Oct 2007 12:08:39 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:SL_Mail_V1.2</comments>
		</item>
		<item>
			<title>SL Mail V1.2</title>
			<link>https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34595</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34595</guid>
			<description>&lt;p&gt;Flennan Roffo: /* &amp;#039;&amp;#039;&amp;#039;Second Life mail client&amp;#039;&amp;#039;&amp;#039; */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}} __NOTOC__&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=&#039;&#039;&#039;Second Life mail client&#039;&#039;&#039;=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Send and receive email from within Second Life from and to any address.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implemented with Address Book function (in a notecard named &#039;Address Book&#039;) to stores addresses by name  and to compile groups of named addresses. Current version is stand-alone (no server functionality) and uses chat commands only.&lt;br /&gt;
&lt;br /&gt;
[[Image:BannerSLMail.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.slmail.info slmail.info] (website coming soon!)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Release Notes V1.2=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 Release notes (edition 2, 4 sept 2007)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LICENCE INFO&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is released under GNU free software licence&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;PRODUCTION &amp;amp; MAINTANENCE&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
by Logic Scripted Products and Script Services&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.logicscripts.org logicscripts.org] (website coming soon!)&lt;br /&gt;
&lt;br /&gt;
SLurl:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Contact: [[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
&lt;br /&gt;
Email: [mailto:info@slmail.info &#039;&#039;&#039;info&#039;&#039;&#039;] or [mailto:Flennan.Roffo@slmail.info &#039;&#039;&#039;Flennan Roffo&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;DESCRIPTION&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is a simple tool to send and receive mail from within SL.&lt;br /&gt;
You can either compose a message yourself using chat recording, or choose a notecard from inventory to send. The Address Book functionality allows you to use short names for mail recipients stored in a notecard. The current version does not have a persisent mail address. Watch out for the upcoming next release (V1.3) which will facilitate persisent in-world mail addresses and will be enhanced with many new features (See: Requests For Change (RFC).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;COMMANDS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Help&#039;&#039;&#039;&lt;br /&gt;
||Show Help about available commands&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Record&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording (for owner only).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Stop&#039;&#039;&#039;&lt;br /&gt;
||Stops the chat recording without sending&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Continue&#039;&#039;&#039;&lt;br /&gt;
||Continues a previously stopped chat recording. Lines will be appended to you recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Show&#039;&#039;&#039;&lt;br /&gt;
||Shows the content of the recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send&#039;&#039;&#039;&lt;br /&gt;
||If recording, stops the recording, and sends the mail (need to supply mail address and subject first!)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send &amp;lt;notecard&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Sends the content of the notecard, instead of the chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Ignore&#039;&#039;&#039;&lt;br /&gt;
||Ignores your current chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject &amp;lt;subject&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the subject of the mail.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail subject.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Set the HOME address of the owner (mail will be forwarder to this address when offline).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home&#039;&#039;&#039;&lt;br /&gt;
||Show the HOME address.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Info&#039;&#039;&#039;&lt;br /&gt;
||Shows the mail address the object this script is running in uses (e.g. &amp;lt;object-key&amp;gt;@lsl.secondlife.com).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Read&#039;&#039;&#039;&lt;br /&gt;
||Reads the current message from the mail buffer (the mail buffer gets filled with mail you receive)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Select &amp;lt;msg&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Select a message number from the availabe messages in the mail buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Next&#039;&#039;&#039;&lt;br /&gt;
||Make next message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Prev&#039;&#039;&#039;&lt;br /&gt;
||Make previous message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@First&#039;&#039;&#039;&lt;br /&gt;
||Make the first message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Last&#039;&#039;&#039;&lt;br /&gt;
||Make the last message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Clear&#039;&#039;&#039;&lt;br /&gt;
||Clear the mail buffer&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Delete&#039;&#039;&#039;&lt;br /&gt;
||Deletes only the current message&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Reply&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording to reply to the current message. Mail adress and subject are filled in automatically.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* Commands are case insensitive (&amp;quot;@read&amp;quot; == &amp;quot;@READ&amp;quot;). Arguments might not be case insensitive.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;ADDRESS BOOK FORMAT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
A notecard of the name &#039;Address Book&#039; is read during initialization which may contain Address Book items and Groups.&lt;br /&gt;
The notecard is split in two sections, which need to be defined in that particular order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[ADDRESS BOOK]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Defines the section in which you can put names for mail addresses,  like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name1=account@thisdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name2=user@otherdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[GROUP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define groups of previously defined names under a new name, like for instance:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyGroup=Name1, Name2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note that names of groups and individual mail adresses share the same namespace and must be unique.&lt;br /&gt;
&lt;br /&gt;
So when you filled in your mail adresses in the Address Book, you can now use:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail Name1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to  &amp;lt;account@thisdomain.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail MyGroup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to &amp;lt;account@thisdomain.com&amp;gt; and &amp;lt;user@otherdomain.com&amp;gt;&lt;br /&gt;
Mails will be sent one after another.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* Names for Addreses and Groups are case insensitive (e.g. &amp;quot;mary&amp;quot;  == &amp;quot;MARY&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* The special address &#039;Self&#039; can be used in commands where otherwise an address specification can be used. &#039;Self&#039; is case insensitive (e.g. &amp;quot;self&amp;quot; == &amp;quot;SELF&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LIMITATIONS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
The current version is limited by the following:&lt;br /&gt;
&lt;br /&gt;
* Chat recording lines are limited by the 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Output of lines from the mail buffer are also limited by this 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Incoming mail is limited to a 1000 (1024?) byte limit&lt;br /&gt;
&lt;br /&gt;
* Outgoing mai is limited by a 4096 byte limit, which includes the standard mail header (region/location info on the first two lines)&lt;br /&gt;
&lt;br /&gt;
We are making adjustments to this release to help overcome these limitations. At least the line lenght limit can be overcome by introducing a line continuation character (for example a hyphen &#039;-&#039;) that when used at the end of a line appends the next line, so lines longer then 255 bytes are possible then.&lt;br /&gt;
&lt;br /&gt;
To overcome the outgoing mail length limit, the mail can be broken textualy into parts, and each part can be send seperatedely, with an indication in the subject or in an introduced primary line of the mail body to indicate that the mail was split into parts.&lt;br /&gt;
For incoming mail and at least to receive mail from other SL Mail programs, a protocol will be introduced to receive mail in parts that are joined together after receiving them to form a single mail.&lt;br /&gt;
&lt;br /&gt;
These enhancements will be made available in the next release (V1.3) of SL Mail &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;BUGS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Report any bugs you find in this release to Logic (IM: Flennan Roffo).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;REQUEST FOR CHANGE (RFC)&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Do you have additional wishes for enhancement of this product?&lt;br /&gt;
Contact Flennan Roffo and we will see if they can be implemented in the next release.&lt;br /&gt;
&lt;br /&gt;
Existing RFC&#039;s are:&lt;br /&gt;
&lt;br /&gt;
* Menu support for commands.&lt;br /&gt;
&lt;br /&gt;
* Lines on incoming/outgoing mail longer than 255 bytes.&lt;br /&gt;
&lt;br /&gt;
* Send messages longer than 4096 (minus SL mail header) bytes.&lt;br /&gt;
&lt;br /&gt;
* Receive messages longer than 1024 bytes.&lt;br /&gt;
&lt;br /&gt;
* Permanent mail addresses for the SL Mail client (like: &amp;lt;Flennan.Roffo@somedomain.sl&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Add your RFC!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In-world join the group &amp;quot;SL Mail&amp;quot; for bug reports, feature requests, the latest SL Mail release, and notices about development issues.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scripts=&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==Script: SL Mail v1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail core module which scans for incoming mail messages and executes commands used by the owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail V1.2.lsl&lt;br /&gt;
// (c) 2007 Logic Scripted Products and Script Services&lt;br /&gt;
// Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
// VERSION&lt;br /&gt;
// Version: 1.2&lt;br /&gt;
&lt;br /&gt;
// HISTORY&lt;br /&gt;
// Date         Version     Author              Comment&lt;br /&gt;
// --------------------------------------------------------------------------------------&lt;br /&gt;
// 28 aug 2007  V 1.0       Flennan Roffo       Created&lt;br /&gt;
//&lt;br /&gt;
//  1 sep 2007  V 1.1       Flennan Roffo       @Reply empties the recording buffer.&lt;br /&gt;
//                                                @Send while recording ends recording&lt;br /&gt;
//                                                and sends the mail if a mail address&lt;br /&gt;
//                                                and subject are supplied.&lt;br /&gt;
//                                                Fixed incorrect date in Unix2DateTime.&lt;br /&gt;
//  3 sep 2007  V 1.2       Flennan Roffo       Notification options:&lt;br /&gt;
//                                              - When online, send an IM when mail is received.&lt;br /&gt;
//                                              - When offline, send to HOME mail adress.&lt;br /&gt;
//                                              Adressbook&lt;br /&gt;
//                                              - Read adress book from config notecard.&lt;br /&gt;
&lt;br /&gt;
// LICENCE&lt;br /&gt;
// This program is free software; you can redistribute it and/or&lt;br /&gt;
// modify it under the terms of the GNU General Public License&lt;br /&gt;
// as published by the Free Software Foundation; either version 2&lt;br /&gt;
// of the License, or (at your option) any later version.&lt;br /&gt;
// &lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
// &lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program; if not, write to the Free Software&lt;br /&gt;
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
// (Also available at http://www.gnu.org/copyleft/gpl.html) &lt;br /&gt;
&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// Let&#039;s you record a message and sent to email and get messages and reply to messages.&lt;br /&gt;
// Must supply a valid mail adress and non-empty subject using chat commands.&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
// 1) Check for the maximum length of an email message (including newline and header).&lt;br /&gt;
// 2) Read adress book from notecard.                                    *DONE*&lt;br /&gt;
// 3) Send incoming mail to personal mail adress when offline.            *DONE*&lt;br /&gt;
// 4) Alert with an IM when online upon receiving new mail.                *DONE*&lt;br /&gt;
&lt;br /&gt;
string   SL_MAIL_VERSION = &amp;quot;V 1.2&amp;quot;;&lt;br /&gt;
string   SL_MAIL_DATE    = &amp;quot; 2 sep 2007&amp;quot;;&lt;br /&gt;
integer  ErrorFlag         = FALSE;&lt;br /&gt;
list     ScriptList        = [ &amp;quot;SL Mail Help V1.2&amp;quot;, &amp;quot;SL Mail AddressBook V1.2&amp;quot;, &lt;br /&gt;
                                &amp;quot;SL Mail OnlineStatus V1.2&amp;quot;, &amp;quot;SL Mail FetchNotecard V1.2&amp;quot; ];    &lt;br /&gt;
string   LSL_DOMAIN=&amp;quot;lsl.secondlife.com&amp;quot;; &lt;br /&gt;
integer  StatusOnline=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Commands&lt;br /&gt;
&lt;br /&gt;
string  COMMAND_RECORD     = &amp;quot;@RECORD&amp;quot;;&lt;br /&gt;
string  COMMAND_CONTINUE   = &amp;quot;@CONTINUE&amp;quot;;&lt;br /&gt;
string  COMMAND_STOP       = &amp;quot;@STOP&amp;quot;;&lt;br /&gt;
string  COMMAND_MAIL       = &amp;quot;@MAIL&amp;quot;;&lt;br /&gt;
string  COMMAND_SUBJECT    = &amp;quot;@SUBJECT&amp;quot;;&lt;br /&gt;
string  COMMAND_SEND       = &amp;quot;@SEND&amp;quot;;&lt;br /&gt;
string  COMMAND_SEE        = &amp;quot;@SEE&amp;quot;;&lt;br /&gt;
string  COMMAND_IGNORE     = &amp;quot;@IGNORE&amp;quot;;&lt;br /&gt;
string  COMMAND_READ       = &amp;quot;@READ&amp;quot;;&lt;br /&gt;
string  COMMAND_DELETE     = &amp;quot;@DELETE&amp;quot;;&lt;br /&gt;
string  COMMAND_CLEAR      = &amp;quot;@CLEAR&amp;quot;;&lt;br /&gt;
string  COMMAND_REPLY      = &amp;quot;@REPLY&amp;quot;;&lt;br /&gt;
string  COMMAND_NEXT       = &amp;quot;@NEXT&amp;quot;;&lt;br /&gt;
string  COMMAND_PREV       = &amp;quot;@PREV&amp;quot;;&lt;br /&gt;
string  COMMAND_FIRST      = &amp;quot;@FIRST&amp;quot;;&lt;br /&gt;
string  COMMAND_LAST       = &amp;quot;@LAST&amp;quot;;&lt;br /&gt;
string  COMMAND_LIST       = &amp;quot;@LIST&amp;quot;;&lt;br /&gt;
string  COMMAND_SELECT     = &amp;quot;@SELECT&amp;quot;;&lt;br /&gt;
string  COMMAND_HELP       = &amp;quot;@HELP&amp;quot;;&lt;br /&gt;
string  COMMAND_INFO       = &amp;quot;@INFO&amp;quot;;&lt;br /&gt;
string  COMMAND_RESET      = &amp;quot;@RESET&amp;quot;;&lt;br /&gt;
string  COMMAND_SHOW       = &amp;quot;@SHOW&amp;quot;;&lt;br /&gt;
string  COMMAND_ON         = &amp;quot;@ON&amp;quot;;&lt;br /&gt;
string  COMMAND_OFF        = &amp;quot;@OFF&amp;quot;;&lt;br /&gt;
string  COMMAND_HOME       = &amp;quot;@HOME&amp;quot;;&lt;br /&gt;
string  COMMAND_LOAD       = &amp;quot;@LOAD&amp;quot;;&lt;br /&gt;
string  COMMAND_ADDRESS    = &amp;quot;@ADDRESS&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Recording&lt;br /&gt;
&lt;br /&gt;
integer Recording = FALSE;&lt;br /&gt;
&lt;br /&gt;
list    ChatRecording=[];&lt;br /&gt;
integer NumLines=0;&lt;br /&gt;
integer Length=0;&lt;br /&gt;
&lt;br /&gt;
list     TimeList=[];&lt;br /&gt;
list     AddressList=[];&lt;br /&gt;
list     SubjectList=[];&lt;br /&gt;
list     BodyList=[];&lt;br /&gt;
integer  NumMessages=0;&lt;br /&gt;
integer  CurrentMessage=-1;&lt;br /&gt;
&lt;br /&gt;
float    MAIL_FETCH_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
// Link Messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP                        = 10000;&lt;br /&gt;
integer MSG_STATUS_ONLINE               = 30000;&lt;br /&gt;
integer MSG_STATUS_OFFLINE              = 30100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED          = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR           = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Unix Time conversion //////////////////&lt;br /&gt;
&lt;br /&gt;
integer DAYS_PER_YEAR        = 365;                // Non leap year&lt;br /&gt;
integer SECONDS_PER_YEAR     = 31536000;          // Non leap year&lt;br /&gt;
integer SECONDS_PER_DAY      = 86400;&lt;br /&gt;
integer SECONDS_PER_HOUR     = 3600;&lt;br /&gt;
integer SECONDS_PER_MINUTE   = 60;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// LeapYear() /////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer LeapYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (year % 4 == 0)&lt;br /&gt;
    {&lt;br /&gt;
        if (year % 100 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (year % 400 == 0)&lt;br /&gt;
            {&lt;br /&gt;
                return 1;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// DaysPerMonth() ///////////////////////////////////////&lt;br /&gt;
                &lt;br /&gt;
integer DaysPerMonth(integer year,integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;lt; 8)&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (month == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if (LeapYear(year))&lt;br /&gt;
                {&lt;br /&gt;
                    return 29;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    return 28;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 30;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 30;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////// DaysPerYear() ////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DaysPerYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (LeapYear(year))&lt;br /&gt;
        return DAYS_PER_YEAR + 1;&lt;br /&gt;
    else&lt;br /&gt;
        return DAYS_PER_YEAR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Unix2DataTime() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list Unix2DateTime(integer unixtime)&lt;br /&gt;
{&lt;br /&gt;
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;&lt;br /&gt;
    integer day = days_since_1_1_1970 + 1;&lt;br /&gt;
    integer year  = 1970;&lt;br /&gt;
    integer days_per_year = DaysPerYear(year);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_year)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_year;&lt;br /&gt;
        ++year;&lt;br /&gt;
        days_per_year = DaysPerYear(year);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer month = 1;&lt;br /&gt;
    integer days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_month)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_month;&lt;br /&gt;
        &lt;br /&gt;
        if (++month &amp;gt; 12)&lt;br /&gt;
        {    &lt;br /&gt;
            ++year;&lt;br /&gt;
            month = 1;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;&lt;br /&gt;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;&lt;br /&gt;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;&lt;br /&gt;
    integer minute      = second / SECONDS_PER_MINUTE;&lt;br /&gt;
    second               = second % SECONDS_PER_MINUTE;&lt;br /&gt;
    &lt;br /&gt;
    return [ year, month, day, hour, minute, second ];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// MonthName() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list MonthNameList = [     &amp;quot;JAN&amp;quot;, &amp;quot;FEB&amp;quot;, &amp;quot;MAR&amp;quot;, &amp;quot;APR&amp;quot;, &amp;quot;MAY&amp;quot;, &amp;quot;JUN&amp;quot;, &lt;br /&gt;
                        &amp;quot;JUL&amp;quot;, &amp;quot;AUG&amp;quot;, &amp;quot;SEP&amp;quot;, &amp;quot;OCT&amp;quot; , &amp;quot;NOV&amp;quot;, &amp;quot;DEC&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
string MonthName(integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;gt;= 0 &amp;amp;&amp;amp; month &amp;lt; 12)&lt;br /&gt;
        return llList2String(MonthNameList, month);&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// DateString() ///////////////////////////&lt;br /&gt;
&lt;br /&gt;
string DateString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer year       = llList2Integer(timelist,0);&lt;br /&gt;
    integer month      = llList2Integer(timelist,1);&lt;br /&gt;
    integer day        = llList2Integer(timelist,2);&lt;br /&gt;
    &lt;br /&gt;
    return (string)day + &amp;quot;-&amp;quot; + MonthName(month - 1) + &amp;quot;-&amp;quot; + (string)year;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// TimeString() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string TimeString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer hour          = llList2Integer(timelist,3);&lt;br /&gt;
    integer minute         = llList2Integer(timelist,4);&lt;br /&gt;
    integer second         = llList2Integer(timelist,5);&lt;br /&gt;
    string  hourstr     = (string)hour;&lt;br /&gt;
    string  minutestr   = (string)minute;&lt;br /&gt;
    string  secondstr   = (string)second;&lt;br /&gt;
    &lt;br /&gt;
    if (hour &amp;lt; 10)         hourstr     = &amp;quot;0&amp;quot; + hourstr;&lt;br /&gt;
    if (minute &amp;lt; 10)     minutestr     = &amp;quot;0&amp;quot; + minutestr;&lt;br /&gt;
    if (second &amp;lt; 10)    secondstr    = &amp;quot;0&amp;quot; + secondstr;&lt;br /&gt;
    return hourstr + &amp;quot;:&amp;quot; + minutestr + &amp;quot;:&amp;quot; + secondstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() /////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string body)&lt;br /&gt;
{&lt;br /&gt;
    // llOwnerSay(&amp;quot;Sending message to &#039;&amp;quot; + address + &amp;quot;&#039; with subject &#039;&amp;quot; + subject +&amp;quot;&#039;.&amp;quot;);&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND, body, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// SendHome() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendHome(string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SENDHOME, body, (key)subject);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Show() ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Show()&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;Current chat recording is:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; NumLines; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(ChatRecording,i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;Lines is &amp;quot; + (string)NumLines);&lt;br /&gt;
    llOwnerSay(&amp;quot;Message length is &amp;quot; + (string)Length);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Read() /////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Read()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;Reading message &amp;quot; + (string)CurrentMessage + &amp;quot; from mail buffer.&amp;quot;);&lt;br /&gt;
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);&lt;br /&gt;
    list timelist=Unix2DateTime(time);&lt;br /&gt;
    string Address = llList2String(AddressList,CurrentMessage);&lt;br /&gt;
    string Subject = llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
    string Body    = llList2String(BodyList,CurrentMessage);&lt;br /&gt;
    llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Address: &amp;quot; + Address);&lt;br /&gt;
    llOwnerSay(&amp;quot;Subject: &amp;quot; + Subject);&lt;br /&gt;
    llOwnerSay(&amp;quot;Begin of message body:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    list bodylist=llParseStringKeepNulls(Body, [ &amp;quot;\n&amp;quot; ], []);&lt;br /&gt;
    integer num=llGetListLength(bodylist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(bodylist,i));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;End of message body.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////// List ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
List()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;The mail buffer contains the following messages:\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; NumMessages; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer time=llList2Integer(TimeList,i);&lt;br /&gt;
        list timelist=Unix2DateTime(time);&lt;br /&gt;
        if (i &amp;gt; 0) llOwnerSay(&amp;quot;+-+-+-+-+-+-+-+-+-+-+-+-&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Message: &amp;quot; + (string)i);&lt;br /&gt;
        llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;From:    &amp;quot; + llList2String(AddressList,i));&lt;br /&gt;
        llOwnerSay(&amp;quot;Subject: &amp;quot; + llList2String(SubjectList,i));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////// NotifyNewMail() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
NotifyNewMail(string time, string address, string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    list timelist=Unix2DateTime((integer)time);&lt;br /&gt;
&lt;br /&gt;
    if (StatusOnline)&lt;br /&gt;
    {&lt;br /&gt;
        llInstantMessage(llGetOwner(), &amp;quot;You received a new mail message on &amp;quot; &lt;br /&gt;
                                    + DateString(timelist) + &amp;quot; at &amp;quot; + TimeString(timelist)&lt;br /&gt;
                                    + &amp;quot; from &amp;quot; + address &lt;br /&gt;
                                    + &amp;quot; with the subject &amp;quot; + subject);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        SendHome(&amp;quot;FW: &amp;quot; + subject, &amp;quot;Received at: &amp;quot; + DateString(timelist) + &amp;quot; &amp;quot; + TimeString(timelist) + &amp;quot;\nFrom: &amp;quot; +  address &lt;br /&gt;
                    + &amp;quot;\nBegin message body:\n-------------------\n&amp;quot; + body + &amp;quot;\n-------------------\nEnd message body.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ResetOtherScripts() //////////////////////&lt;br /&gt;
&lt;br /&gt;
ResetOtherScripts()&lt;br /&gt;
{&lt;br /&gt;
    string     name;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(ScriptList);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        name = llList2String(ScriptList,i);&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(name) == INVENTORY_SCRIPT)&lt;br /&gt;
        {&lt;br /&gt;
            llResetOtherScript(name);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Error - script &#039;&amp;quot; + name + &amp;quot;&#039; not found.&amp;quot;);&lt;br /&gt;
            ErrorFlag = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
// default &lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ////////////////////// state_entry() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Welcome to SL Mail, released under GNU software licence.&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Version &amp;quot; + SL_MAIL_VERSION + &amp;quot; &amp;quot; + SL_MAIL_DATE);&lt;br /&gt;
        llOwnerSay(&amp;quot;Produced by Logic Scripted Products &amp;amp; Product Services&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Free memory: &amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
        ResetOtherScripts();&lt;br /&gt;
        &lt;br /&gt;
        if (ErrorFlag)&lt;br /&gt;
            state Error;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// on_rez() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// changed() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_LOADED)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_ERROR)&lt;br /&gt;
        {&lt;br /&gt;
            state Error;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() //////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(MAIL_FETCH_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //////////////////////// on_rez() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// listen() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string trimmessage=llStringTrim(message,STRING_TRIM);&lt;br /&gt;
        list   parse = llParseStringKeepNulls(trimmessage, [ &amp;quot; &amp;quot;], []);&lt;br /&gt;
        string command = llToUpper(llList2String(parse,0));&lt;br /&gt;
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        integer nargs  = llGetListLength(parse);&lt;br /&gt;
        string argstr=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (nargs &amp;gt; 1) argstr=llGetSubString(message, llSubStringIndex(message, &amp;quot; &amp;quot;) + 1, -1);&lt;br /&gt;
            &lt;br /&gt;
        if (Recording)&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Recording stopped. Type @SHOW to see the message you have entered,&amp;quot;&lt;br /&gt;
                            + &amp;quot; or @SEND to send it.&amp;quot;);&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                &lt;br /&gt;
                SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];&lt;br /&gt;
                ++NumLines;&lt;br /&gt;
                Length += llStringLength(message) + 2;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_RECORD)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Start recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                ChatRecording = [];&lt;br /&gt;
                NumLines=0;&lt;br /&gt;
                Length=0;&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CONTINUE)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Continue recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_REPLY)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    string address=llList2String(AddressList,CurrentMessage);&lt;br /&gt;
                    string subject=&amp;quot;Re: &amp;quot; + llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, address, NULL_KEY);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, subject, NULL_KEY);&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines=0;&lt;br /&gt;
                    Length=0;&lt;br /&gt;
                    Recording = TRUE;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_MAIL)&lt;br /&gt;
            {&lt;br /&gt;
                string mailaddress=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailaddress != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, mailaddress, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETADDRESS, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SUBJECT)&lt;br /&gt;
            {&lt;br /&gt;
                string mailsubject=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailsubject != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, mailsubject, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETSUBJECT, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Not recording.&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    if (NumLines == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND_NOTECARD, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_IGNORE)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines = 0;&lt;br /&gt;
                    Length = 0;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Show();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_READ)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumMessages == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Read();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        ++CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        --CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_FIRST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = 0;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LAST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LIST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    List();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SELECT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;Need to supply a message number.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    integer msgnum = (integer)arg;&lt;br /&gt;
                     &lt;br /&gt;
                    if (msgnum &amp;lt; 0 || msgnum &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Message number &amp;quot; + arg + &amp;quot; not in mail buffer.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = msgnum;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_DELETE)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    --NumMessages;&lt;br /&gt;
                     &lt;br /&gt;
                    if (NumMessages == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = -1;&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (CurrentMessage &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CLEAR)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList=[];&lt;br /&gt;
                    AddressList=[];&lt;br /&gt;
                    SubjectList=[];&lt;br /&gt;
                    BodyList=[];&lt;br /&gt;
                    NumMessages=0;&lt;br /&gt;
                    CurrentMessage=-1;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_HELP, arg, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_INFO)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                Show();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_RESET)&lt;br /&gt;
            {&lt;br /&gt;
                llResetScript();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                state not_running;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HOME)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs==1)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETHOME, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETHOME, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// email() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    email(string time, string address, string subject, string body, integer queued)&lt;br /&gt;
    {&lt;br /&gt;
        NotifyNewMail(time, address, subject, body);&lt;br /&gt;
        TimeList = (TimeList=[]) + TimeList + [time];&lt;br /&gt;
        AddressList = (AddressList=[]) + AddressList + [address];&lt;br /&gt;
        SubjectList = (SubjectList=[]) + SubjectList + [subject];&lt;br /&gt;
        BodyList = (BodyList=[]) + BodyList + [body];&lt;br /&gt;
        ++NumMessages;&lt;br /&gt;
        &lt;br /&gt;
        if (CurrentMessage == -1)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = NumMessages - 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_REPLY)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state not_running&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state not_running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;SL Mailbox switched OFF. Say @ON to switch it back on.&amp;quot;);&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// on_rez() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// listen() ////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer chan, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string command=llToUpper(message);&lt;br /&gt;
        &lt;br /&gt;
        if (command == COMMAND_ON)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state Error&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state Error&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Error in SL Mail: not all component scripts found.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// End SL Mail V1.2.lsl&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Address Book V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Read and interpret the contents of the Address Book.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail AddressBook V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// &lt;br /&gt;
//  Read the Address Book from a notecard named &amp;quot;Address Book&amp;quot;.&lt;br /&gt;
//&lt;br /&gt;
//  The Address Book has the following format:&lt;br /&gt;
//  &lt;br /&gt;
//  [ADDRESS BOOK]&lt;br /&gt;
//  Name1=username@yourdomain.com&lt;br /&gt;
//  Name2=otheruser@otherdomain.com&lt;br /&gt;
//  ...&lt;br /&gt;
//  [GROUP]&lt;br /&gt;
//  group1=Name1, Name2&lt;br /&gt;
//  ...&lt;br /&gt;
//&lt;br /&gt;
//  Notes:&lt;br /&gt;
//  1. Group and Name share the same namespace, and must be unique.&lt;br /&gt;
//  2. It is allowed to have a name in the addressbook with multiple addresses, seperated by comma&#039;s.&lt;br /&gt;
// &lt;br /&gt;
/////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string  CurrentMailAddress = &amp;quot;&amp;quot;;&lt;br /&gt;
string  CurrentMailSubject = &amp;quot;&amp;quot;;&lt;br /&gt;
integer StatusOnline = FALSE;&lt;br /&gt;
&lt;br /&gt;
// Fetch or Send notecard&lt;br /&gt;
&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Names&lt;br /&gt;
&lt;br /&gt;
list    AddressBookList=[];&lt;br /&gt;
list    MailAddressList=[];&lt;br /&gt;
&lt;br /&gt;
string  STRING_HOME=&amp;quot;HOME&amp;quot;;&lt;br /&gt;
string  STRING_SELF=&amp;quot;SELF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Groups&lt;br /&gt;
&lt;br /&gt;
list   GroupList=[];&lt;br /&gt;
list   GroupNameList=[];&lt;br /&gt;
&lt;br /&gt;
string LSL_DOMAIN = &amp;quot;lsl.secondlife.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Read Address Book notecard&lt;br /&gt;
&lt;br /&gt;
string  ADDRESSBOOK_NOTECARD=&amp;quot;Address Book&amp;quot;;&lt;br /&gt;
integer Line=0;&lt;br /&gt;
key     reqAddressBook=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
integer Section=0;&lt;br /&gt;
integer SECTION_ADDRESS_BOOK=1;&lt;br /&gt;
integer SECTION_GROUP=2;&lt;br /&gt;
string  STRING_ADDRESS_BOOK=&amp;quot;ADDRESS BOOK&amp;quot;;&lt;br /&gt;
string  STRING_GROUP=&amp;quot;GROUP&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Links messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
integer MSG_MESSAGE_NOTIFY              = 90900;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED            = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR            = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// GetSelfAddress() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
string GetSelfAddress()&lt;br /&gt;
{&lt;br /&gt;
    return (string)llGetKey() + &amp;quot;@&amp;quot; + LSL_DOMAIN;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Info() /////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Info()&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;The mail address for this object is: &amp;quot; &lt;br /&gt;
                    + GetSelfAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// IsValidKeyFormat() //////////////////////&lt;br /&gt;
&lt;br /&gt;
integer IsValidKeyFormat(string str)&lt;br /&gt;
{&lt;br /&gt;
    string keychars = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    if (llStringLength(str) != 36)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    if( (llGetSubString( str, 8, 8 )   != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 13, 13 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 18, 18 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 23, 23 )  != &amp;quot;-&amp;quot; ) )&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 9; i &amp;lt; 13; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 14; i &amp;lt; 18; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 19; i &amp;lt; 23; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 24; i &amp;lt; 36; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// ValidMailAddress() ////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer ValidMailAddress(string arg)&lt;br /&gt;
{&lt;br /&gt;
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));&lt;br /&gt;
    &lt;br /&gt;
    if (adress == &amp;quot;&amp;quot;)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    list parse = llParseStringKeepNulls(adress, [ &amp;quot;@&amp;quot; ], []);&lt;br /&gt;
    string account = llList2String(parse,0);&lt;br /&gt;
    string domain  = llList2String(parse,1);&lt;br /&gt;
    &lt;br /&gt;
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    &lt;br /&gt;
    if (domain == LSL_DOMAIN)&lt;br /&gt;
    {&lt;br /&gt;
        return IsValidKeyFormat(account);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list parsedomain = llParseString2List(domain, [ &amp;quot;.&amp;quot; ], []);&lt;br /&gt;
    &lt;br /&gt;
        if (llGetListLength(parsedomain) &amp;lt; 2)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        &lt;br /&gt;
        integer num = llGetListLength(parsedomain);&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llStringLength(llList2String(parsedomain,i)) &amp;lt; 2)&lt;br /&gt;
            {&lt;br /&gt;
                return FALSE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetAddressStr() ///////////////////&lt;br /&gt;
&lt;br /&gt;
string GetAndCheckAddressStr(string address)&lt;br /&gt;
{&lt;br /&gt;
    list addresslist = llCSV2List(address);&lt;br /&gt;
    integer num=llGetListLength(addresslist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    string addressstr=&amp;quot;&amp;quot;;&lt;br /&gt;
    string curaddress=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        curaddress=llList2String(addresslist,i);&lt;br /&gt;
        &lt;br /&gt;
        if (ValidMailAddress(curaddress))&lt;br /&gt;
        {&lt;br /&gt;
            addressstr = (addressstr=&amp;quot;&amp;quot;) + addressstr + curaddress + &amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address string: &#039;&amp;quot; &lt;br /&gt;
                            + curaddress + &amp;quot;&#039;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return llGetSubString(addressstr, 0, -2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ProcessLine() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
ProcessLine(string rawline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(rawline,STRING_TRIM);&lt;br /&gt;
    string first=llGetSubString(line,0,0);&lt;br /&gt;
    string last=llGetSubString(line,-1,-1);&lt;br /&gt;
    &lt;br /&gt;
    // Ignore a blank line or comment line&lt;br /&gt;
    if (line == &amp;quot;&amp;quot; || first == &amp;quot;#&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // Check for the right section&lt;br /&gt;
    &lt;br /&gt;
    if (first == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; last == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        string sectionstr=llToUpper(llStringTrim(llGetSubString(line,1,-2),STRING_TRIM));&lt;br /&gt;
        &lt;br /&gt;
        if (sectionstr == STRING_ADDRESS_BOOK)&lt;br /&gt;
        {&lt;br /&gt;
            Section = SECTION_ADDRESS_BOOK;&lt;br /&gt;
        }&lt;br /&gt;
        else if (sectionstr == STRING_GROUP)&lt;br /&gt;
        {&lt;br /&gt;
            if (Section == 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                        + &amp;quot;. Group section defined before Address Book section.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Section = SECTION_GROUP;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid section header &#039;&amp;quot; + sectionstr &lt;br /&gt;
                        + &amp;quot;&#039; in &amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Must be in a section&lt;br /&gt;
    &lt;br /&gt;
    if (Section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;. No section header.&amp;quot;, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    list     parse=llParseString2List(line, [ &amp;quot;=&amp;quot; ], []);&lt;br /&gt;
    integer  num=llGetListLength(parse);&lt;br /&gt;
    &lt;br /&gt;
    // Format must be correct&lt;br /&gt;
    &lt;br /&gt;
    if (num != 2)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; +  (string)(Line+1) + &amp;quot;:\n&amp;quot; + rawline, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (Section == SECTION_ADDRESS_BOOK)&lt;br /&gt;
    {&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(name) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + name &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ name ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            string address=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
            string addressstr=GetAndCheckAddressStr(address);&lt;br /&gt;
            &lt;br /&gt;
            if (addressstr != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                AddressBookList     = (AddressBookList=[])     + AddressBookList     + [ name ];&lt;br /&gt;
                MailAddressList     = (MailAddressList=[])     + MailAddressList     + [ addressstr ];&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;No valid mail address for &#039;&amp;quot; + name &lt;br /&gt;
                    + &amp;quot;&#039;. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                    + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name &lt;br /&gt;
                + &amp;quot;&#039; already defined. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // Group&lt;br /&gt;
    {&lt;br /&gt;
        string group=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(group) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + group &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ group ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(GroupList, [ group ]) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                string names=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
                list   namelist=llCSV2List(names);&lt;br /&gt;
                integer num=llGetListLength(namelist);&lt;br /&gt;
                integer i;&lt;br /&gt;
                integer index;&lt;br /&gt;
                string  name;&lt;br /&gt;
                string  namestr=&amp;quot;&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
                for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                    name=llList2String(namelist,i);&lt;br /&gt;
                    index=llListFindList(AddressBookList, [ name ]);&lt;br /&gt;
            &lt;br /&gt;
                    if (index == -1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name + &amp;quot;&#039; defined in Group &#039;&amp;quot; &lt;br /&gt;
                                + group + &amp;quot;&#039; not found in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY); &lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        namestr = (namestr=&amp;quot;&amp;quot;) + namestr + name + &amp;quot;,&amp;quot;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (namestr != &amp;quot;&amp;quot;)&lt;br /&gt;
                {    &lt;br /&gt;
                    namestr=llGetSubString(namestr,0,-2);&lt;br /&gt;
                    GroupList         = (GroupList=[])         + GroupList     + [ group ];&lt;br /&gt;
                    GroupNameList     = (GroupNameList=[])    + GroupNameList + [ namestr ];&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                        + &amp;quot;&#039; has no valid names. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                        + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                    + &amp;quot;&#039; already defined in Group. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                    + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group&lt;br /&gt;
                + &amp;quot;&#039; already defined in Address Book. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// GetGroupAddressList ///////////////&lt;br /&gt;
&lt;br /&gt;
string GetGroupAddressList(string group)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(GroupList, [ group ]);&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(GroupList);&lt;br /&gt;
    string  grouplist=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        for (i = index; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2String(GroupList,i) == group)&lt;br /&gt;
            {&lt;br /&gt;
                grouplist = (grouplist=&amp;quot;&amp;quot;) + grouplist + llList2String(GroupNameList,i) + &amp;quot;,&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (grouplist != &amp;quot;&amp;quot;) grouplist=llGetSubString(grouplist,0,-2);   // remove last &amp;quot;,&amp;quot;&lt;br /&gt;
        return grouplist;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// SetMailAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetMailAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ address ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        index=llListFindList(GroupList, [ address ]);&lt;br /&gt;
        &lt;br /&gt;
        if (index == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llToUpper(address) == STRING_SELF)&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = GetSelfAddress();&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if(ValidMailAddress(address))&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = address;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Mail adress &amp;quot; + address &lt;br /&gt;
                            + &amp;quot; : not found in adress book or invalid format.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailAddress = GetGroupAddressList(address);&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        CurrentMailAddress = llList2String(MailAddressList,index);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                        + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string message)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No mail address defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No subject defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list mailaddresslist=llCSV2List(CurrentMailAddress);&lt;br /&gt;
        integer num=llGetListLength(mailaddresslist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(mailaddresslist,i);&lt;br /&gt;
            llEmail(address, CurrentMailSubject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMailHome() ////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMailHome(string message, string subject)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, STRING_HOME &lt;br /&gt;
                + &amp;quot; not set. Set your home adress with @HOME &amp;lt;address&amp;gt;.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        string homeaddress=llList2String(AddressBookList,index);&lt;br /&gt;
        list   homelist=llCSV2List(homeaddress);&lt;br /&gt;
        integer num=llGetListLength(homelist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(homelist,i);&lt;br /&gt;
            llEmail(address, subject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
string GetHomeAddress()&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;not set&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2String(MailAddressList,index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetHomeAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        AddressBookList     = (AddressBookList=[]) + [ STRING_HOME ] + AddressBookList;&lt;br /&gt;
        MailAddressList     = (MailAddressList=[]) + [ GetAndCheckAddressStr(address) ]  + MailAddressList;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MailAddressList = llListReplaceList(MailAddressList, [ GetAndCheckAddressStr(address) ], index, index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        Line=0;&lt;br /&gt;
        Section=0;&lt;br /&gt;
        llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// dataserver() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqAddressBook)&lt;br /&gt;
        {&lt;br /&gt;
            reqAddressBook = NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                ProcessLine(data);&lt;br /&gt;
                reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Address Book loaded.&amp;quot;, NULL_KEY);&lt;br /&gt;
                state running;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// timer() ///////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_ERROR, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Could not read Address Book: &amp;quot; &lt;br /&gt;
                            + ADDRESSBOOK_NOTECARD + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// link_message() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_MESSAGE_GETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is empty.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailSubject = message;&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is empty.&amp;quot;, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            SetMailAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Body of message to send is empty. &amp;quot; &lt;br /&gt;
                                +  &amp;quot;No mail is send.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SENDHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SendMailHome(message, (string)id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetInventoryType(message) == INVENTORY_NOTECARD)&lt;br /&gt;
            {&lt;br /&gt;
                Notecard2Fetch = message;                &lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_READ, message, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + message + &amp;quot; not found.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_NOTECARD_FETCHED)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + Notecard2Fetch &lt;br /&gt;
                            + &amp;quot; was empty or could not be read.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Home address is: &amp;quot; + GetHomeAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SetHomeAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_INFO)&lt;br /&gt;
        {&lt;br /&gt;
            Info();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
// End SL Mail AddressBook V1.2.lsl&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail FetchNotecard V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch the contents of a notecard and return it via link message as a string.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Notecard&lt;br /&gt;
&lt;br /&gt;
integer Line=0;&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
key     reqNotecard=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=10.0;&lt;br /&gt;
integer Fetched=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Lines&lt;br /&gt;
&lt;br /&gt;
list LineList=[];&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    /////////////////////// dataserver() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqNotecard)&lt;br /&gt;
        {&lt;br /&gt;
            reqNotecard=NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                LineList = (LineList=[]) + LineList + [ data ];&lt;br /&gt;
                reqNotecard = llGetNotecardLine(Notecard2Fetch, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Fetched=TRUE;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, llDumpList2String(LineList, &amp;quot;\n&amp;quot;), NULL_KEY);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /////////////////////// timer() ///////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        if (!Fetched)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            llSetTimerEvent(0.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer send, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_NOTECARD_READ)&lt;br /&gt;
        {&lt;br /&gt;
            Line=0;&lt;br /&gt;
            Notecard2Fetch=message;&lt;br /&gt;
            LineList=[];&lt;br /&gt;
            Fetched=FALSE;&lt;br /&gt;
            reqNotecard=llGetNotecardLine(Notecard2Fetch, Line);&lt;br /&gt;
            llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL OnlineStatus V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch online status of owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Online status&lt;br /&gt;
&lt;br /&gt;
key     reqOnlineStatus=NULL_KEY;&lt;br /&gt;
float   STATUS_INTERVAL=2.0;&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_STATUS_ONLINE       = 30000;&lt;br /&gt;
integer MS_STATUS_OFFLINE       = 30100;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus=llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
        llSetTimerEvent(STATUS_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// dataserver() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqOnlineStatus)&lt;br /&gt;
        {&lt;br /&gt;
            reqOnlineStatus = NULL_KEY;&lt;br /&gt;
        &lt;br /&gt;
            if (data==&amp;quot;1&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_STATUS_ONLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if (data==&amp;quot;0&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MS_STATUS_OFFLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus = llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Help V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Display help information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail Help V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP    = 10000;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Help() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Help()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;HELP for SL Mail V1.2.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;COMMANDS:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HELP               - displays help info.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@INFO               - display mailaddress of this object.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RECORD             - start recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CONTINUE           - continue recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@STOP               - stop recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@IGNORE             - ignore the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SHOW               - show what your recorded.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SEND               - send the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@MAIL &amp;lt;mailadress&amp;gt;  - set the mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SUBJECT subject    - set the mail subject.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LIST               - list messages in mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SELECT &amp;lt;message&amp;gt;   - select message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@READ               - read current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@NEXT               - read next message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@PREV               - read previous message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@FIRST              - read first message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LAST               - read last message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@DELETE             - delete current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CLEAR              - clear the mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@REPLY              - reply to current message.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RESET              - reset the script.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HOME               - set the home mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@OFF                - switch mailbox OFF.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@ON                 - switch mailbox ON.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_HELP)&lt;br /&gt;
        {&lt;br /&gt;
            Help();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail Help V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}&lt;/div&gt;</description>
			<pubDate>Sun, 07 Oct 2007 11:19:04 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:SL_Mail_V1.2</comments>
		</item>
		<item>
			<title>SL Mail V1.2</title>
			<link>https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34593</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34593</guid>
			<description>&lt;p&gt;Flennan Roffo: /* &amp;#039;&amp;#039;&amp;#039;PRODUCTION &amp;amp; MAINTANENCE&amp;#039;&amp;#039;&amp;#039; */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}} __NOTOC__&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=&#039;&#039;&#039;Second Life mail client&#039;&#039;&#039;=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Send and receive email from within Second Life from and to any address.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implemented with Address Book function (in a notecard named &#039;Address Book&#039;) to stores addresses by name  and to compile groups of named addresses. Current version is stand-alone (no server functionality) and uses chat commands only.&lt;br /&gt;
&lt;br /&gt;
[[Image:BannerSLMail.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=Release Notes V1.2=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 Release notes (edition 2, 4 sept 2007)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LICENCE INFO&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is released under GNU free software licence&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;PRODUCTION &amp;amp; MAINTANENCE&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
by Logic Scripted Products and Script Services&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL: [http://www.logicscripts.org logicscripts.org] (website coming soon!)&lt;br /&gt;
&lt;br /&gt;
SLurl:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Contact: [[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
&lt;br /&gt;
Email: [mailto:info@slmail.info &#039;&#039;&#039;info&#039;&#039;&#039;] or [mailto:Flennan.Roffo@slmail.info &#039;&#039;&#039;Flennan Roffo&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;DESCRIPTION&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is a simple tool to send and receive mail from within SL.&lt;br /&gt;
You can either compose a message yourself using chat recording, or choose a notecard from inventory to send. The Address Book functionality allows you to use short names for mail recipients stored in a notecard. The current version does not have a persisent mail address. Watch out for the upcoming next release (V1.3) which will facilitate persisent in-world mail addresses and will be enhanced with many new features (See: Requests For Change (RFC).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;COMMANDS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Help&#039;&#039;&#039;&lt;br /&gt;
||Show Help about available commands&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Record&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording (for owner only).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Stop&#039;&#039;&#039;&lt;br /&gt;
||Stops the chat recording without sending&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Continue&#039;&#039;&#039;&lt;br /&gt;
||Continues a previously stopped chat recording. Lines will be appended to you recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Show&#039;&#039;&#039;&lt;br /&gt;
||Shows the content of the recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send&#039;&#039;&#039;&lt;br /&gt;
||If recording, stops the recording, and sends the mail (need to supply mail address and subject first!)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send &amp;lt;notecard&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Sends the content of the notecard, instead of the chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Ignore&#039;&#039;&#039;&lt;br /&gt;
||Ignores your current chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject &amp;lt;subject&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the subject of the mail.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail subject.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Set the HOME address of the owner (mail will be forwarder to this address when offline).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home&#039;&#039;&#039;&lt;br /&gt;
||Show the HOME address.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Info&#039;&#039;&#039;&lt;br /&gt;
||Shows the mail address the object this script is running in uses (e.g. &amp;lt;object-key&amp;gt;@lsl.secondlife.com).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Read&#039;&#039;&#039;&lt;br /&gt;
||Reads the current message from the mail buffer (the mail buffer gets filled with mail you receive)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Select &amp;lt;msg&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Select a message number from the availabe messages in the mail buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Next&#039;&#039;&#039;&lt;br /&gt;
||Make next message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Prev&#039;&#039;&#039;&lt;br /&gt;
||Make previous message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@First&#039;&#039;&#039;&lt;br /&gt;
||Make the first message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Last&#039;&#039;&#039;&lt;br /&gt;
||Make the last message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Clear&#039;&#039;&#039;&lt;br /&gt;
||Clear the mail buffer&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Delete&#039;&#039;&#039;&lt;br /&gt;
||Deletes only the current message&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Reply&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording to reply to the current message. Mail adress and subject are filled in automatically.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* Commands are case insensitive (&amp;quot;@read&amp;quot; == &amp;quot;@READ&amp;quot;). Arguments might not be case insensitive.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;ADDRESS BOOK FORMAT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
A notecard of the name &#039;Address Book&#039; is read during initialization which may contain Address Book items and Groups.&lt;br /&gt;
The notecard is split in two sections, which need to be defined in that particular order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[ADDRESS BOOK]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Defines the section in which you can put names for mail addresses,  like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name1=account@thisdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name2=user@otherdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[GROUP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define groups of previously defined names under a new name, like for instance:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyGroup=Name1, Name2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note that names of groups and individual mail adresses share the same namespace and must be unique.&lt;br /&gt;
&lt;br /&gt;
So when you filled in your mail adresses in the Address Book, you can now use:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail Name1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to  &amp;lt;account@thisdomain.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail MyGroup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to &amp;lt;account@thisdomain.com&amp;gt; and &amp;lt;user@otherdomain.com&amp;gt;&lt;br /&gt;
Mails will be sent one after another.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* Names for Addreses and Groups are case insensitive (e.g. &amp;quot;mary&amp;quot;  == &amp;quot;MARY&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* The special address &#039;Self&#039; can be used in commands where otherwise an address specification can be used. &#039;Self&#039; is case insensitive (e.g. &amp;quot;self&amp;quot; == &amp;quot;SELF&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LIMITATIONS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
The current version is limited by the following:&lt;br /&gt;
&lt;br /&gt;
* Chat recording lines are limited by the 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Output of lines from the mail buffer are also limited by this 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Incoming mail is limited to a 1000 (1024?) byte limit&lt;br /&gt;
&lt;br /&gt;
* Outgoing mai is limited by a 4096 byte limit, which includes the standard mail header (region/location info on the first two lines)&lt;br /&gt;
&lt;br /&gt;
We are making adjustments to this release to help overcome these limitations. At least the line lenght limit can be overcome by introducing a line continuation character (for example a hyphen &#039;-&#039;) that when used at the end of a line appends the next line, so lines longer then 255 bytes are possible then.&lt;br /&gt;
&lt;br /&gt;
To overcome the outgoing mail length limit, the mail can be broken textualy into parts, and each part can be send seperatedely, with an indication in the subject or in an introduced primary line of the mail body to indicate that the mail was split into parts.&lt;br /&gt;
For incoming mail and at least to receive mail from other SL Mail programs, a protocol will be introduced to receive mail in parts that are joined together after receiving them to form a single mail.&lt;br /&gt;
&lt;br /&gt;
These enhancements will be made available in the next release (V1.3) of SL Mail &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;BUGS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Report any bugs you find in this release to Logic (IM: Flennan Roffo).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;REQUEST FOR CHANGE (RFC)&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Do you have additional wishes for enhancement of this product?&lt;br /&gt;
Contact Flennan Roffo and we will see if they can be implemented in the next release.&lt;br /&gt;
&lt;br /&gt;
Existing RFC&#039;s are:&lt;br /&gt;
&lt;br /&gt;
* Menu support for commands.&lt;br /&gt;
&lt;br /&gt;
* Lines on incoming/outgoing mail longer than 255 bytes.&lt;br /&gt;
&lt;br /&gt;
* Send messages longer than 4096 (minus SL mail header) bytes.&lt;br /&gt;
&lt;br /&gt;
* Receive messages longer than 1024 bytes.&lt;br /&gt;
&lt;br /&gt;
* Permanent mail addresses for the SL Mail client (like: &amp;lt;Flennan.Roffo@somedomain.sl&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Add your RFC!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In-world join the group &amp;quot;SL Mail&amp;quot; for bug reports, feature requests, the latest SL Mail release, and notices about development issues.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scripts=&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==Script: SL Mail v1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail core module which scans for incoming mail messages and executes commands used by the owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail V1.2.lsl&lt;br /&gt;
// (c) 2007 Logic Scripted Products and Script Services&lt;br /&gt;
// Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
// VERSION&lt;br /&gt;
// Version: 1.2&lt;br /&gt;
&lt;br /&gt;
// HISTORY&lt;br /&gt;
// Date         Version     Author              Comment&lt;br /&gt;
// --------------------------------------------------------------------------------------&lt;br /&gt;
// 28 aug 2007  V 1.0       Flennan Roffo       Created&lt;br /&gt;
//&lt;br /&gt;
//  1 sep 2007  V 1.1       Flennan Roffo       @Reply empties the recording buffer.&lt;br /&gt;
//                                                @Send while recording ends recording&lt;br /&gt;
//                                                and sends the mail if a mail address&lt;br /&gt;
//                                                and subject are supplied.&lt;br /&gt;
//                                                Fixed incorrect date in Unix2DateTime.&lt;br /&gt;
//  3 sep 2007  V 1.2       Flennan Roffo       Notification options:&lt;br /&gt;
//                                              - When online, send an IM when mail is received.&lt;br /&gt;
//                                              - When offline, send to HOME mail adress.&lt;br /&gt;
//                                              Adressbook&lt;br /&gt;
//                                              - Read adress book from config notecard.&lt;br /&gt;
&lt;br /&gt;
// LICENCE&lt;br /&gt;
// This program is free software; you can redistribute it and/or&lt;br /&gt;
// modify it under the terms of the GNU General Public License&lt;br /&gt;
// as published by the Free Software Foundation; either version 2&lt;br /&gt;
// of the License, or (at your option) any later version.&lt;br /&gt;
// &lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
// &lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program; if not, write to the Free Software&lt;br /&gt;
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
// (Also available at http://www.gnu.org/copyleft/gpl.html) &lt;br /&gt;
&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// Let&#039;s you record a message and sent to email and get messages and reply to messages.&lt;br /&gt;
// Must supply a valid mail adress and non-empty subject using chat commands.&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
// 1) Check for the maximum length of an email message (including newline and header).&lt;br /&gt;
// 2) Read adress book from notecard.                                    *DONE*&lt;br /&gt;
// 3) Send incoming mail to personal mail adress when offline.            *DONE*&lt;br /&gt;
// 4) Alert with an IM when online upon receiving new mail.                *DONE*&lt;br /&gt;
&lt;br /&gt;
string   SL_MAIL_VERSION = &amp;quot;V 1.2&amp;quot;;&lt;br /&gt;
string   SL_MAIL_DATE    = &amp;quot; 2 sep 2007&amp;quot;;&lt;br /&gt;
integer  ErrorFlag         = FALSE;&lt;br /&gt;
list     ScriptList        = [ &amp;quot;SL Mail Help V1.2&amp;quot;, &amp;quot;SL Mail AddressBook V1.2&amp;quot;, &lt;br /&gt;
                                &amp;quot;SL Mail OnlineStatus V1.2&amp;quot;, &amp;quot;SL Mail FetchNotecard V1.2&amp;quot; ];    &lt;br /&gt;
string   LSL_DOMAIN=&amp;quot;lsl.secondlife.com&amp;quot;; &lt;br /&gt;
integer  StatusOnline=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Commands&lt;br /&gt;
&lt;br /&gt;
string  COMMAND_RECORD     = &amp;quot;@RECORD&amp;quot;;&lt;br /&gt;
string  COMMAND_CONTINUE   = &amp;quot;@CONTINUE&amp;quot;;&lt;br /&gt;
string  COMMAND_STOP       = &amp;quot;@STOP&amp;quot;;&lt;br /&gt;
string  COMMAND_MAIL       = &amp;quot;@MAIL&amp;quot;;&lt;br /&gt;
string  COMMAND_SUBJECT    = &amp;quot;@SUBJECT&amp;quot;;&lt;br /&gt;
string  COMMAND_SEND       = &amp;quot;@SEND&amp;quot;;&lt;br /&gt;
string  COMMAND_SEE        = &amp;quot;@SEE&amp;quot;;&lt;br /&gt;
string  COMMAND_IGNORE     = &amp;quot;@IGNORE&amp;quot;;&lt;br /&gt;
string  COMMAND_READ       = &amp;quot;@READ&amp;quot;;&lt;br /&gt;
string  COMMAND_DELETE     = &amp;quot;@DELETE&amp;quot;;&lt;br /&gt;
string  COMMAND_CLEAR      = &amp;quot;@CLEAR&amp;quot;;&lt;br /&gt;
string  COMMAND_REPLY      = &amp;quot;@REPLY&amp;quot;;&lt;br /&gt;
string  COMMAND_NEXT       = &amp;quot;@NEXT&amp;quot;;&lt;br /&gt;
string  COMMAND_PREV       = &amp;quot;@PREV&amp;quot;;&lt;br /&gt;
string  COMMAND_FIRST      = &amp;quot;@FIRST&amp;quot;;&lt;br /&gt;
string  COMMAND_LAST       = &amp;quot;@LAST&amp;quot;;&lt;br /&gt;
string  COMMAND_LIST       = &amp;quot;@LIST&amp;quot;;&lt;br /&gt;
string  COMMAND_SELECT     = &amp;quot;@SELECT&amp;quot;;&lt;br /&gt;
string  COMMAND_HELP       = &amp;quot;@HELP&amp;quot;;&lt;br /&gt;
string  COMMAND_INFO       = &amp;quot;@INFO&amp;quot;;&lt;br /&gt;
string  COMMAND_RESET      = &amp;quot;@RESET&amp;quot;;&lt;br /&gt;
string  COMMAND_SHOW       = &amp;quot;@SHOW&amp;quot;;&lt;br /&gt;
string  COMMAND_ON         = &amp;quot;@ON&amp;quot;;&lt;br /&gt;
string  COMMAND_OFF        = &amp;quot;@OFF&amp;quot;;&lt;br /&gt;
string  COMMAND_HOME       = &amp;quot;@HOME&amp;quot;;&lt;br /&gt;
string  COMMAND_LOAD       = &amp;quot;@LOAD&amp;quot;;&lt;br /&gt;
string  COMMAND_ADDRESS    = &amp;quot;@ADDRESS&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Recording&lt;br /&gt;
&lt;br /&gt;
integer Recording = FALSE;&lt;br /&gt;
&lt;br /&gt;
list    ChatRecording=[];&lt;br /&gt;
integer NumLines=0;&lt;br /&gt;
integer Length=0;&lt;br /&gt;
&lt;br /&gt;
list     TimeList=[];&lt;br /&gt;
list     AddressList=[];&lt;br /&gt;
list     SubjectList=[];&lt;br /&gt;
list     BodyList=[];&lt;br /&gt;
integer  NumMessages=0;&lt;br /&gt;
integer  CurrentMessage=-1;&lt;br /&gt;
&lt;br /&gt;
float    MAIL_FETCH_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
// Link Messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP                        = 10000;&lt;br /&gt;
integer MSG_STATUS_ONLINE               = 30000;&lt;br /&gt;
integer MSG_STATUS_OFFLINE              = 30100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED          = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR           = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Unix Time conversion //////////////////&lt;br /&gt;
&lt;br /&gt;
integer DAYS_PER_YEAR        = 365;                // Non leap year&lt;br /&gt;
integer SECONDS_PER_YEAR     = 31536000;          // Non leap year&lt;br /&gt;
integer SECONDS_PER_DAY      = 86400;&lt;br /&gt;
integer SECONDS_PER_HOUR     = 3600;&lt;br /&gt;
integer SECONDS_PER_MINUTE   = 60;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// LeapYear() /////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer LeapYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (year % 4 == 0)&lt;br /&gt;
    {&lt;br /&gt;
        if (year % 100 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (year % 400 == 0)&lt;br /&gt;
            {&lt;br /&gt;
                return 1;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// DaysPerMonth() ///////////////////////////////////////&lt;br /&gt;
                &lt;br /&gt;
integer DaysPerMonth(integer year,integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;lt; 8)&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (month == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if (LeapYear(year))&lt;br /&gt;
                {&lt;br /&gt;
                    return 29;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    return 28;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 30;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 30;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////// DaysPerYear() ////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DaysPerYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (LeapYear(year))&lt;br /&gt;
        return DAYS_PER_YEAR + 1;&lt;br /&gt;
    else&lt;br /&gt;
        return DAYS_PER_YEAR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Unix2DataTime() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list Unix2DateTime(integer unixtime)&lt;br /&gt;
{&lt;br /&gt;
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;&lt;br /&gt;
    integer day = days_since_1_1_1970 + 1;&lt;br /&gt;
    integer year  = 1970;&lt;br /&gt;
    integer days_per_year = DaysPerYear(year);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_year)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_year;&lt;br /&gt;
        ++year;&lt;br /&gt;
        days_per_year = DaysPerYear(year);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer month = 1;&lt;br /&gt;
    integer days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_month)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_month;&lt;br /&gt;
        &lt;br /&gt;
        if (++month &amp;gt; 12)&lt;br /&gt;
        {    &lt;br /&gt;
            ++year;&lt;br /&gt;
            month = 1;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;&lt;br /&gt;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;&lt;br /&gt;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;&lt;br /&gt;
    integer minute      = second / SECONDS_PER_MINUTE;&lt;br /&gt;
    second               = second % SECONDS_PER_MINUTE;&lt;br /&gt;
    &lt;br /&gt;
    return [ year, month, day, hour, minute, second ];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// MonthName() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list MonthNameList = [     &amp;quot;JAN&amp;quot;, &amp;quot;FEB&amp;quot;, &amp;quot;MAR&amp;quot;, &amp;quot;APR&amp;quot;, &amp;quot;MAY&amp;quot;, &amp;quot;JUN&amp;quot;, &lt;br /&gt;
                        &amp;quot;JUL&amp;quot;, &amp;quot;AUG&amp;quot;, &amp;quot;SEP&amp;quot;, &amp;quot;OCT&amp;quot; , &amp;quot;NOV&amp;quot;, &amp;quot;DEC&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
string MonthName(integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;gt;= 0 &amp;amp;&amp;amp; month &amp;lt; 12)&lt;br /&gt;
        return llList2String(MonthNameList, month);&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// DateString() ///////////////////////////&lt;br /&gt;
&lt;br /&gt;
string DateString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer year       = llList2Integer(timelist,0);&lt;br /&gt;
    integer month      = llList2Integer(timelist,1);&lt;br /&gt;
    integer day        = llList2Integer(timelist,2);&lt;br /&gt;
    &lt;br /&gt;
    return (string)day + &amp;quot;-&amp;quot; + MonthName(month - 1) + &amp;quot;-&amp;quot; + (string)year;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// TimeString() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string TimeString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer hour          = llList2Integer(timelist,3);&lt;br /&gt;
    integer minute         = llList2Integer(timelist,4);&lt;br /&gt;
    integer second         = llList2Integer(timelist,5);&lt;br /&gt;
    string  hourstr     = (string)hour;&lt;br /&gt;
    string  minutestr   = (string)minute;&lt;br /&gt;
    string  secondstr   = (string)second;&lt;br /&gt;
    &lt;br /&gt;
    if (hour &amp;lt; 10)         hourstr     = &amp;quot;0&amp;quot; + hourstr;&lt;br /&gt;
    if (minute &amp;lt; 10)     minutestr     = &amp;quot;0&amp;quot; + minutestr;&lt;br /&gt;
    if (second &amp;lt; 10)    secondstr    = &amp;quot;0&amp;quot; + secondstr;&lt;br /&gt;
    return hourstr + &amp;quot;:&amp;quot; + minutestr + &amp;quot;:&amp;quot; + secondstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() /////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string body)&lt;br /&gt;
{&lt;br /&gt;
    // llOwnerSay(&amp;quot;Sending message to &#039;&amp;quot; + address + &amp;quot;&#039; with subject &#039;&amp;quot; + subject +&amp;quot;&#039;.&amp;quot;);&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND, body, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// SendHome() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendHome(string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SENDHOME, body, (key)subject);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Show() ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Show()&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;Current chat recording is:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; NumLines; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(ChatRecording,i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;Lines is &amp;quot; + (string)NumLines);&lt;br /&gt;
    llOwnerSay(&amp;quot;Message length is &amp;quot; + (string)Length);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Read() /////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Read()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;Reading message &amp;quot; + (string)CurrentMessage + &amp;quot; from mail buffer.&amp;quot;);&lt;br /&gt;
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);&lt;br /&gt;
    list timelist=Unix2DateTime(time);&lt;br /&gt;
    string Address = llList2String(AddressList,CurrentMessage);&lt;br /&gt;
    string Subject = llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
    string Body    = llList2String(BodyList,CurrentMessage);&lt;br /&gt;
    llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Address: &amp;quot; + Address);&lt;br /&gt;
    llOwnerSay(&amp;quot;Subject: &amp;quot; + Subject);&lt;br /&gt;
    llOwnerSay(&amp;quot;Begin of message body:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    list bodylist=llParseStringKeepNulls(Body, [ &amp;quot;\n&amp;quot; ], []);&lt;br /&gt;
    integer num=llGetListLength(bodylist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(bodylist,i));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;End of message body.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////// List ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
List()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;The mail buffer contains the following messages:\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; NumMessages; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer time=llList2Integer(TimeList,i);&lt;br /&gt;
        list timelist=Unix2DateTime(time);&lt;br /&gt;
        if (i &amp;gt; 0) llOwnerSay(&amp;quot;+-+-+-+-+-+-+-+-+-+-+-+-&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Message: &amp;quot; + (string)i);&lt;br /&gt;
        llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;From:    &amp;quot; + llList2String(AddressList,i));&lt;br /&gt;
        llOwnerSay(&amp;quot;Subject: &amp;quot; + llList2String(SubjectList,i));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////// NotifyNewMail() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
NotifyNewMail(string time, string address, string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    list timelist=Unix2DateTime((integer)time);&lt;br /&gt;
&lt;br /&gt;
    if (StatusOnline)&lt;br /&gt;
    {&lt;br /&gt;
        llInstantMessage(llGetOwner(), &amp;quot;You received a new mail message on &amp;quot; &lt;br /&gt;
                                    + DateString(timelist) + &amp;quot; at &amp;quot; + TimeString(timelist)&lt;br /&gt;
                                    + &amp;quot; from &amp;quot; + address &lt;br /&gt;
                                    + &amp;quot; with the subject &amp;quot; + subject);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        SendHome(&amp;quot;FW: &amp;quot; + subject, &amp;quot;Received at: &amp;quot; + DateString(timelist) + &amp;quot; &amp;quot; + TimeString(timelist) + &amp;quot;\nFrom: &amp;quot; +  address &lt;br /&gt;
                    + &amp;quot;\nBegin message body:\n-------------------\n&amp;quot; + body + &amp;quot;\n-------------------\nEnd message body.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ResetOtherScripts() //////////////////////&lt;br /&gt;
&lt;br /&gt;
ResetOtherScripts()&lt;br /&gt;
{&lt;br /&gt;
    string     name;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(ScriptList);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        name = llList2String(ScriptList,i);&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(name) == INVENTORY_SCRIPT)&lt;br /&gt;
        {&lt;br /&gt;
            llResetOtherScript(name);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Error - script &#039;&amp;quot; + name + &amp;quot;&#039; not found.&amp;quot;);&lt;br /&gt;
            ErrorFlag = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
// default &lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ////////////////////// state_entry() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Welcome to SL Mail, released under GNU software licence.&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Version &amp;quot; + SL_MAIL_VERSION + &amp;quot; &amp;quot; + SL_MAIL_DATE);&lt;br /&gt;
        llOwnerSay(&amp;quot;Produced by Logic Scripted Products &amp;amp; Product Services&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Free memory: &amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
        ResetOtherScripts();&lt;br /&gt;
        &lt;br /&gt;
        if (ErrorFlag)&lt;br /&gt;
            state Error;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// on_rez() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// changed() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_LOADED)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_ERROR)&lt;br /&gt;
        {&lt;br /&gt;
            state Error;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() //////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(MAIL_FETCH_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //////////////////////// on_rez() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// listen() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string trimmessage=llStringTrim(message,STRING_TRIM);&lt;br /&gt;
        list   parse = llParseStringKeepNulls(trimmessage, [ &amp;quot; &amp;quot;], []);&lt;br /&gt;
        string command = llToUpper(llList2String(parse,0));&lt;br /&gt;
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        integer nargs  = llGetListLength(parse);&lt;br /&gt;
        string argstr=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (nargs &amp;gt; 1) argstr=llGetSubString(message, llSubStringIndex(message, &amp;quot; &amp;quot;) + 1, -1);&lt;br /&gt;
            &lt;br /&gt;
        if (Recording)&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Recording stopped. Type @SHOW to see the message you have entered,&amp;quot;&lt;br /&gt;
                            + &amp;quot; or @SEND to send it.&amp;quot;);&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                &lt;br /&gt;
                SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];&lt;br /&gt;
                ++NumLines;&lt;br /&gt;
                Length += llStringLength(message) + 2;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_RECORD)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Start recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                ChatRecording = [];&lt;br /&gt;
                NumLines=0;&lt;br /&gt;
                Length=0;&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CONTINUE)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Continue recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_REPLY)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    string address=llList2String(AddressList,CurrentMessage);&lt;br /&gt;
                    string subject=&amp;quot;Re: &amp;quot; + llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, address, NULL_KEY);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, subject, NULL_KEY);&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines=0;&lt;br /&gt;
                    Length=0;&lt;br /&gt;
                    Recording = TRUE;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_MAIL)&lt;br /&gt;
            {&lt;br /&gt;
                string mailaddress=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailaddress != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, mailaddress, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETADDRESS, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SUBJECT)&lt;br /&gt;
            {&lt;br /&gt;
                string mailsubject=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailsubject != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, mailsubject, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETSUBJECT, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Not recording.&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    if (NumLines == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND_NOTECARD, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_IGNORE)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines = 0;&lt;br /&gt;
                    Length = 0;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Show();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_READ)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumMessages == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Read();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        ++CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        --CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_FIRST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = 0;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LAST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LIST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    List();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SELECT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;Need to supply a message number.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    integer msgnum = (integer)arg;&lt;br /&gt;
                     &lt;br /&gt;
                    if (msgnum &amp;lt; 0 || msgnum &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Message number &amp;quot; + arg + &amp;quot; not in mail buffer.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = msgnum;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_DELETE)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    --NumMessages;&lt;br /&gt;
                     &lt;br /&gt;
                    if (NumMessages == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = -1;&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (CurrentMessage &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CLEAR)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList=[];&lt;br /&gt;
                    AddressList=[];&lt;br /&gt;
                    SubjectList=[];&lt;br /&gt;
                    BodyList=[];&lt;br /&gt;
                    NumMessages=0;&lt;br /&gt;
                    CurrentMessage=-1;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_HELP, arg, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_INFO)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                Show();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_RESET)&lt;br /&gt;
            {&lt;br /&gt;
                llResetScript();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                state not_running;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HOME)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs==1)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETHOME, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETHOME, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// email() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    email(string time, string address, string subject, string body, integer queued)&lt;br /&gt;
    {&lt;br /&gt;
        NotifyNewMail(time, address, subject, body);&lt;br /&gt;
        TimeList = (TimeList=[]) + TimeList + [time];&lt;br /&gt;
        AddressList = (AddressList=[]) + AddressList + [address];&lt;br /&gt;
        SubjectList = (SubjectList=[]) + SubjectList + [subject];&lt;br /&gt;
        BodyList = (BodyList=[]) + BodyList + [body];&lt;br /&gt;
        ++NumMessages;&lt;br /&gt;
        &lt;br /&gt;
        if (CurrentMessage == -1)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = NumMessages - 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_REPLY)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state not_running&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state not_running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;SL Mailbox switched OFF. Say @ON to switch it back on.&amp;quot;);&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// on_rez() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// listen() ////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer chan, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string command=llToUpper(message);&lt;br /&gt;
        &lt;br /&gt;
        if (command == COMMAND_ON)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state Error&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state Error&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Error in SL Mail: not all component scripts found.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// End SL Mail V1.2.lsl&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Address Book V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Read and interpret the contents of the Address Book.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail AddressBook V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// &lt;br /&gt;
//  Read the Address Book from a notecard named &amp;quot;Address Book&amp;quot;.&lt;br /&gt;
//&lt;br /&gt;
//  The Address Book has the following format:&lt;br /&gt;
//  &lt;br /&gt;
//  [ADDRESS BOOK]&lt;br /&gt;
//  Name1=username@yourdomain.com&lt;br /&gt;
//  Name2=otheruser@otherdomain.com&lt;br /&gt;
//  ...&lt;br /&gt;
//  [GROUP]&lt;br /&gt;
//  group1=Name1, Name2&lt;br /&gt;
//  ...&lt;br /&gt;
//&lt;br /&gt;
//  Notes:&lt;br /&gt;
//  1. Group and Name share the same namespace, and must be unique.&lt;br /&gt;
//  2. It is allowed to have a name in the addressbook with multiple addresses, seperated by comma&#039;s.&lt;br /&gt;
// &lt;br /&gt;
/////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string  CurrentMailAddress = &amp;quot;&amp;quot;;&lt;br /&gt;
string  CurrentMailSubject = &amp;quot;&amp;quot;;&lt;br /&gt;
integer StatusOnline = FALSE;&lt;br /&gt;
&lt;br /&gt;
// Fetch or Send notecard&lt;br /&gt;
&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Names&lt;br /&gt;
&lt;br /&gt;
list    AddressBookList=[];&lt;br /&gt;
list    MailAddressList=[];&lt;br /&gt;
&lt;br /&gt;
string  STRING_HOME=&amp;quot;HOME&amp;quot;;&lt;br /&gt;
string  STRING_SELF=&amp;quot;SELF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Groups&lt;br /&gt;
&lt;br /&gt;
list   GroupList=[];&lt;br /&gt;
list   GroupNameList=[];&lt;br /&gt;
&lt;br /&gt;
string LSL_DOMAIN = &amp;quot;lsl.secondlife.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Read Address Book notecard&lt;br /&gt;
&lt;br /&gt;
string  ADDRESSBOOK_NOTECARD=&amp;quot;Address Book&amp;quot;;&lt;br /&gt;
integer Line=0;&lt;br /&gt;
key     reqAddressBook=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
integer Section=0;&lt;br /&gt;
integer SECTION_ADDRESS_BOOK=1;&lt;br /&gt;
integer SECTION_GROUP=2;&lt;br /&gt;
string  STRING_ADDRESS_BOOK=&amp;quot;ADDRESS BOOK&amp;quot;;&lt;br /&gt;
string  STRING_GROUP=&amp;quot;GROUP&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Links messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
integer MSG_MESSAGE_NOTIFY              = 90900;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED            = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR            = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// GetSelfAddress() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
string GetSelfAddress()&lt;br /&gt;
{&lt;br /&gt;
    return (string)llGetKey() + &amp;quot;@&amp;quot; + LSL_DOMAIN;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Info() /////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Info()&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;The mail address for this object is: &amp;quot; &lt;br /&gt;
                    + GetSelfAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// IsValidKeyFormat() //////////////////////&lt;br /&gt;
&lt;br /&gt;
integer IsValidKeyFormat(string str)&lt;br /&gt;
{&lt;br /&gt;
    string keychars = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    if (llStringLength(str) != 36)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    if( (llGetSubString( str, 8, 8 )   != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 13, 13 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 18, 18 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 23, 23 )  != &amp;quot;-&amp;quot; ) )&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 9; i &amp;lt; 13; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 14; i &amp;lt; 18; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 19; i &amp;lt; 23; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 24; i &amp;lt; 36; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// ValidMailAddress() ////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer ValidMailAddress(string arg)&lt;br /&gt;
{&lt;br /&gt;
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));&lt;br /&gt;
    &lt;br /&gt;
    if (adress == &amp;quot;&amp;quot;)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    list parse = llParseStringKeepNulls(adress, [ &amp;quot;@&amp;quot; ], []);&lt;br /&gt;
    string account = llList2String(parse,0);&lt;br /&gt;
    string domain  = llList2String(parse,1);&lt;br /&gt;
    &lt;br /&gt;
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    &lt;br /&gt;
    if (domain == LSL_DOMAIN)&lt;br /&gt;
    {&lt;br /&gt;
        return IsValidKeyFormat(account);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list parsedomain = llParseString2List(domain, [ &amp;quot;.&amp;quot; ], []);&lt;br /&gt;
    &lt;br /&gt;
        if (llGetListLength(parsedomain) &amp;lt; 2)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        &lt;br /&gt;
        integer num = llGetListLength(parsedomain);&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llStringLength(llList2String(parsedomain,i)) &amp;lt; 2)&lt;br /&gt;
            {&lt;br /&gt;
                return FALSE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetAddressStr() ///////////////////&lt;br /&gt;
&lt;br /&gt;
string GetAndCheckAddressStr(string address)&lt;br /&gt;
{&lt;br /&gt;
    list addresslist = llCSV2List(address);&lt;br /&gt;
    integer num=llGetListLength(addresslist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    string addressstr=&amp;quot;&amp;quot;;&lt;br /&gt;
    string curaddress=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        curaddress=llList2String(addresslist,i);&lt;br /&gt;
        &lt;br /&gt;
        if (ValidMailAddress(curaddress))&lt;br /&gt;
        {&lt;br /&gt;
            addressstr = (addressstr=&amp;quot;&amp;quot;) + addressstr + curaddress + &amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address string: &#039;&amp;quot; &lt;br /&gt;
                            + curaddress + &amp;quot;&#039;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return llGetSubString(addressstr, 0, -2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ProcessLine() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
ProcessLine(string rawline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(rawline,STRING_TRIM);&lt;br /&gt;
    string first=llGetSubString(line,0,0);&lt;br /&gt;
    string last=llGetSubString(line,-1,-1);&lt;br /&gt;
    &lt;br /&gt;
    // Ignore a blank line or comment line&lt;br /&gt;
    if (line == &amp;quot;&amp;quot; || first == &amp;quot;#&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // Check for the right section&lt;br /&gt;
    &lt;br /&gt;
    if (first == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; last == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        string sectionstr=llToUpper(llStringTrim(llGetSubString(line,1,-2),STRING_TRIM));&lt;br /&gt;
        &lt;br /&gt;
        if (sectionstr == STRING_ADDRESS_BOOK)&lt;br /&gt;
        {&lt;br /&gt;
            Section = SECTION_ADDRESS_BOOK;&lt;br /&gt;
        }&lt;br /&gt;
        else if (sectionstr == STRING_GROUP)&lt;br /&gt;
        {&lt;br /&gt;
            if (Section == 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                        + &amp;quot;. Group section defined before Address Book section.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Section = SECTION_GROUP;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid section header &#039;&amp;quot; + sectionstr &lt;br /&gt;
                        + &amp;quot;&#039; in &amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Must be in a section&lt;br /&gt;
    &lt;br /&gt;
    if (Section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;. No section header.&amp;quot;, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    list     parse=llParseString2List(line, [ &amp;quot;=&amp;quot; ], []);&lt;br /&gt;
    integer  num=llGetListLength(parse);&lt;br /&gt;
    &lt;br /&gt;
    // Format must be correct&lt;br /&gt;
    &lt;br /&gt;
    if (num != 2)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; +  (string)(Line+1) + &amp;quot;:\n&amp;quot; + rawline, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (Section == SECTION_ADDRESS_BOOK)&lt;br /&gt;
    {&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(name) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + name &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ name ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            string address=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
            string addressstr=GetAndCheckAddressStr(address);&lt;br /&gt;
            &lt;br /&gt;
            if (addressstr != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                AddressBookList     = (AddressBookList=[])     + AddressBookList     + [ name ];&lt;br /&gt;
                MailAddressList     = (MailAddressList=[])     + MailAddressList     + [ addressstr ];&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;No valid mail address for &#039;&amp;quot; + name &lt;br /&gt;
                    + &amp;quot;&#039;. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                    + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name &lt;br /&gt;
                + &amp;quot;&#039; already defined. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // Group&lt;br /&gt;
    {&lt;br /&gt;
        string group=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(group) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + group &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ group ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(GroupList, [ group ]) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                string names=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
                list   namelist=llCSV2List(names);&lt;br /&gt;
                integer num=llGetListLength(namelist);&lt;br /&gt;
                integer i;&lt;br /&gt;
                integer index;&lt;br /&gt;
                string  name;&lt;br /&gt;
                string  namestr=&amp;quot;&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
                for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                    name=llList2String(namelist,i);&lt;br /&gt;
                    index=llListFindList(AddressBookList, [ name ]);&lt;br /&gt;
            &lt;br /&gt;
                    if (index == -1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name + &amp;quot;&#039; defined in Group &#039;&amp;quot; &lt;br /&gt;
                                + group + &amp;quot;&#039; not found in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY); &lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        namestr = (namestr=&amp;quot;&amp;quot;) + namestr + name + &amp;quot;,&amp;quot;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (namestr != &amp;quot;&amp;quot;)&lt;br /&gt;
                {    &lt;br /&gt;
                    namestr=llGetSubString(namestr,0,-2);&lt;br /&gt;
                    GroupList         = (GroupList=[])         + GroupList     + [ group ];&lt;br /&gt;
                    GroupNameList     = (GroupNameList=[])    + GroupNameList + [ namestr ];&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                        + &amp;quot;&#039; has no valid names. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                        + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                    + &amp;quot;&#039; already defined in Group. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                    + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group&lt;br /&gt;
                + &amp;quot;&#039; already defined in Address Book. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// GetGroupAddressList ///////////////&lt;br /&gt;
&lt;br /&gt;
string GetGroupAddressList(string group)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(GroupList, [ group ]);&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(GroupList);&lt;br /&gt;
    string  grouplist=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        for (i = index; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2String(GroupList,i) == group)&lt;br /&gt;
            {&lt;br /&gt;
                grouplist = (grouplist=&amp;quot;&amp;quot;) + grouplist + llList2String(GroupNameList,i) + &amp;quot;,&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (grouplist != &amp;quot;&amp;quot;) grouplist=llGetSubString(grouplist,0,-2);   // remove last &amp;quot;,&amp;quot;&lt;br /&gt;
        return grouplist;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// SetMailAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetMailAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ address ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        index=llListFindList(GroupList, [ address ]);&lt;br /&gt;
        &lt;br /&gt;
        if (index == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llToUpper(address) == STRING_SELF)&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = GetSelfAddress();&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if(ValidMailAddress(address))&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = address;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Mail adress &amp;quot; + address &lt;br /&gt;
                            + &amp;quot; : not found in adress book or invalid format.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailAddress = GetGroupAddressList(address);&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        CurrentMailAddress = llList2String(MailAddressList,index);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                        + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string message)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No mail address defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No subject defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list mailaddresslist=llCSV2List(CurrentMailAddress);&lt;br /&gt;
        integer num=llGetListLength(mailaddresslist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(mailaddresslist,i);&lt;br /&gt;
            llEmail(address, CurrentMailSubject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMailHome() ////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMailHome(string message, string subject)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, STRING_HOME &lt;br /&gt;
                + &amp;quot; not set. Set your home adress with @HOME &amp;lt;address&amp;gt;.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        string homeaddress=llList2String(AddressBookList,index);&lt;br /&gt;
        list   homelist=llCSV2List(homeaddress);&lt;br /&gt;
        integer num=llGetListLength(homelist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(homelist,i);&lt;br /&gt;
            llEmail(address, subject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
string GetHomeAddress()&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;not set&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2String(MailAddressList,index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetHomeAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        AddressBookList     = (AddressBookList=[]) + [ STRING_HOME ] + AddressBookList;&lt;br /&gt;
        MailAddressList     = (MailAddressList=[]) + [ GetAndCheckAddressStr(address) ]  + MailAddressList;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MailAddressList = llListReplaceList(MailAddressList, [ GetAndCheckAddressStr(address) ], index, index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        Line=0;&lt;br /&gt;
        Section=0;&lt;br /&gt;
        llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// dataserver() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqAddressBook)&lt;br /&gt;
        {&lt;br /&gt;
            reqAddressBook = NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                ProcessLine(data);&lt;br /&gt;
                reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Address Book loaded.&amp;quot;, NULL_KEY);&lt;br /&gt;
                state running;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// timer() ///////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_ERROR, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Could not read Address Book: &amp;quot; &lt;br /&gt;
                            + ADDRESSBOOK_NOTECARD + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// link_message() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_MESSAGE_GETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is empty.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailSubject = message;&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is empty.&amp;quot;, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            SetMailAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Body of message to send is empty. &amp;quot; &lt;br /&gt;
                                +  &amp;quot;No mail is send.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SENDHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SendMailHome(message, (string)id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetInventoryType(message) == INVENTORY_NOTECARD)&lt;br /&gt;
            {&lt;br /&gt;
                Notecard2Fetch = message;                &lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_READ, message, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + message + &amp;quot; not found.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_NOTECARD_FETCHED)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + Notecard2Fetch &lt;br /&gt;
                            + &amp;quot; was empty or could not be read.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Home address is: &amp;quot; + GetHomeAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SetHomeAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_INFO)&lt;br /&gt;
        {&lt;br /&gt;
            Info();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
// End SL Mail AddressBook V1.2.lsl&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail FetchNotecard V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch the contents of a notecard and return it via link message as a string.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Notecard&lt;br /&gt;
&lt;br /&gt;
integer Line=0;&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
key     reqNotecard=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=10.0;&lt;br /&gt;
integer Fetched=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Lines&lt;br /&gt;
&lt;br /&gt;
list LineList=[];&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    /////////////////////// dataserver() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqNotecard)&lt;br /&gt;
        {&lt;br /&gt;
            reqNotecard=NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                LineList = (LineList=[]) + LineList + [ data ];&lt;br /&gt;
                reqNotecard = llGetNotecardLine(Notecard2Fetch, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Fetched=TRUE;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, llDumpList2String(LineList, &amp;quot;\n&amp;quot;), NULL_KEY);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /////////////////////// timer() ///////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        if (!Fetched)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            llSetTimerEvent(0.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer send, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_NOTECARD_READ)&lt;br /&gt;
        {&lt;br /&gt;
            Line=0;&lt;br /&gt;
            Notecard2Fetch=message;&lt;br /&gt;
            LineList=[];&lt;br /&gt;
            Fetched=FALSE;&lt;br /&gt;
            reqNotecard=llGetNotecardLine(Notecard2Fetch, Line);&lt;br /&gt;
            llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL OnlineStatus V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch online status of owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Online status&lt;br /&gt;
&lt;br /&gt;
key     reqOnlineStatus=NULL_KEY;&lt;br /&gt;
float   STATUS_INTERVAL=2.0;&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_STATUS_ONLINE       = 30000;&lt;br /&gt;
integer MS_STATUS_OFFLINE       = 30100;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus=llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
        llSetTimerEvent(STATUS_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// dataserver() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqOnlineStatus)&lt;br /&gt;
        {&lt;br /&gt;
            reqOnlineStatus = NULL_KEY;&lt;br /&gt;
        &lt;br /&gt;
            if (data==&amp;quot;1&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_STATUS_ONLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if (data==&amp;quot;0&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MS_STATUS_OFFLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus = llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Help V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Display help information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail Help V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP    = 10000;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Help() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Help()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;HELP for SL Mail V1.2.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;COMMANDS:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HELP               - displays help info.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@INFO               - display mailaddress of this object.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RECORD             - start recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CONTINUE           - continue recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@STOP               - stop recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@IGNORE             - ignore the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SHOW               - show what your recorded.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SEND               - send the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@MAIL &amp;lt;mailadress&amp;gt;  - set the mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SUBJECT subject    - set the mail subject.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LIST               - list messages in mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SELECT &amp;lt;message&amp;gt;   - select message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@READ               - read current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@NEXT               - read next message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@PREV               - read previous message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@FIRST              - read first message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LAST               - read last message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@DELETE             - delete current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CLEAR              - clear the mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@REPLY              - reply to current message.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RESET              - reset the script.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HOME               - set the home mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@OFF                - switch mailbox OFF.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@ON                 - switch mailbox ON.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_HELP)&lt;br /&gt;
        {&lt;br /&gt;
            Help();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail Help V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}&lt;/div&gt;</description>
			<pubDate>Sun, 07 Oct 2007 11:17:29 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:SL_Mail_V1.2</comments>
		</item>
		<item>
			<title>SL Mail V1.2</title>
			<link>https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34592</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34592</guid>
			<description>&lt;p&gt;Flennan Roffo: /* &amp;#039;&amp;#039;&amp;#039;PRODUCTION &amp;amp; MAINTANENCE&amp;#039;&amp;#039;&amp;#039; */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}} __NOTOC__&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=&#039;&#039;&#039;Second Life mail client&#039;&#039;&#039;=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Send and receive email from within Second Life from and to any address.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implemented with Address Book function (in a notecard named &#039;Address Book&#039;) to stores addresses by name  and to compile groups of named addresses. Current version is stand-alone (no server functionality) and uses chat commands only.&lt;br /&gt;
&lt;br /&gt;
[[Image:BannerSLMail.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=Release Notes V1.2=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 Release notes (edition 2, 4 sept 2007)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LICENCE INFO&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is released under GNU free software licence&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;PRODUCTION &amp;amp; MAINTANENCE&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
by Logic Scripted Products and Script Services&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
URL:[http://www.logicscripts.org logicscripts.org] (website coming soon!)&lt;br /&gt;
&lt;br /&gt;
SLurl:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Contact: [[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
&lt;br /&gt;
Email: [mailto:info@slmail.info &#039;&#039;&#039;info&#039;&#039;&#039;] or [mailto:Flennan.Roffo@slmail.info &#039;&#039;&#039;Flennan Roffo&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;DESCRIPTION&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is a simple tool to send and receive mail from within SL.&lt;br /&gt;
You can either compose a message yourself using chat recording, or choose a notecard from inventory to send. The Address Book functionality allows you to use short names for mail recipients stored in a notecard. The current version does not have a persisent mail address. Watch out for the upcoming next release (V1.3) which will facilitate persisent in-world mail addresses and will be enhanced with many new features (See: Requests For Change (RFC).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;COMMANDS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Help&#039;&#039;&#039;&lt;br /&gt;
||Show Help about available commands&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Record&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording (for owner only).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Stop&#039;&#039;&#039;&lt;br /&gt;
||Stops the chat recording without sending&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Continue&#039;&#039;&#039;&lt;br /&gt;
||Continues a previously stopped chat recording. Lines will be appended to you recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Show&#039;&#039;&#039;&lt;br /&gt;
||Shows the content of the recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send&#039;&#039;&#039;&lt;br /&gt;
||If recording, stops the recording, and sends the mail (need to supply mail address and subject first!)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send &amp;lt;notecard&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Sends the content of the notecard, instead of the chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Ignore&#039;&#039;&#039;&lt;br /&gt;
||Ignores your current chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject &amp;lt;subject&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the subject of the mail.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail subject.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Set the HOME address of the owner (mail will be forwarder to this address when offline).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home&#039;&#039;&#039;&lt;br /&gt;
||Show the HOME address.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Info&#039;&#039;&#039;&lt;br /&gt;
||Shows the mail address the object this script is running in uses (e.g. &amp;lt;object-key&amp;gt;@lsl.secondlife.com).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Read&#039;&#039;&#039;&lt;br /&gt;
||Reads the current message from the mail buffer (the mail buffer gets filled with mail you receive)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Select &amp;lt;msg&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Select a message number from the availabe messages in the mail buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Next&#039;&#039;&#039;&lt;br /&gt;
||Make next message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Prev&#039;&#039;&#039;&lt;br /&gt;
||Make previous message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@First&#039;&#039;&#039;&lt;br /&gt;
||Make the first message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Last&#039;&#039;&#039;&lt;br /&gt;
||Make the last message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Clear&#039;&#039;&#039;&lt;br /&gt;
||Clear the mail buffer&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Delete&#039;&#039;&#039;&lt;br /&gt;
||Deletes only the current message&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Reply&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording to reply to the current message. Mail adress and subject are filled in automatically.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* Commands are case insensitive (&amp;quot;@read&amp;quot; == &amp;quot;@READ&amp;quot;). Arguments might not be case insensitive.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;ADDRESS BOOK FORMAT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
A notecard of the name &#039;Address Book&#039; is read during initialization which may contain Address Book items and Groups.&lt;br /&gt;
The notecard is split in two sections, which need to be defined in that particular order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[ADDRESS BOOK]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Defines the section in which you can put names for mail addresses,  like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name1=account@thisdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name2=user@otherdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[GROUP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define groups of previously defined names under a new name, like for instance:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyGroup=Name1, Name2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note that names of groups and individual mail adresses share the same namespace and must be unique.&lt;br /&gt;
&lt;br /&gt;
So when you filled in your mail adresses in the Address Book, you can now use:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail Name1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to  &amp;lt;account@thisdomain.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail MyGroup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to &amp;lt;account@thisdomain.com&amp;gt; and &amp;lt;user@otherdomain.com&amp;gt;&lt;br /&gt;
Mails will be sent one after another.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* Names for Addreses and Groups are case insensitive (e.g. &amp;quot;mary&amp;quot;  == &amp;quot;MARY&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* The special address &#039;Self&#039; can be used in commands where otherwise an address specification can be used. &#039;Self&#039; is case insensitive (e.g. &amp;quot;self&amp;quot; == &amp;quot;SELF&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LIMITATIONS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
The current version is limited by the following:&lt;br /&gt;
&lt;br /&gt;
* Chat recording lines are limited by the 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Output of lines from the mail buffer are also limited by this 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Incoming mail is limited to a 1000 (1024?) byte limit&lt;br /&gt;
&lt;br /&gt;
* Outgoing mai is limited by a 4096 byte limit, which includes the standard mail header (region/location info on the first two lines)&lt;br /&gt;
&lt;br /&gt;
We are making adjustments to this release to help overcome these limitations. At least the line lenght limit can be overcome by introducing a line continuation character (for example a hyphen &#039;-&#039;) that when used at the end of a line appends the next line, so lines longer then 255 bytes are possible then.&lt;br /&gt;
&lt;br /&gt;
To overcome the outgoing mail length limit, the mail can be broken textualy into parts, and each part can be send seperatedely, with an indication in the subject or in an introduced primary line of the mail body to indicate that the mail was split into parts.&lt;br /&gt;
For incoming mail and at least to receive mail from other SL Mail programs, a protocol will be introduced to receive mail in parts that are joined together after receiving them to form a single mail.&lt;br /&gt;
&lt;br /&gt;
These enhancements will be made available in the next release (V1.3) of SL Mail &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;BUGS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Report any bugs you find in this release to Logic (IM: Flennan Roffo).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;REQUEST FOR CHANGE (RFC)&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Do you have additional wishes for enhancement of this product?&lt;br /&gt;
Contact Flennan Roffo and we will see if they can be implemented in the next release.&lt;br /&gt;
&lt;br /&gt;
Existing RFC&#039;s are:&lt;br /&gt;
&lt;br /&gt;
* Menu support for commands.&lt;br /&gt;
&lt;br /&gt;
* Lines on incoming/outgoing mail longer than 255 bytes.&lt;br /&gt;
&lt;br /&gt;
* Send messages longer than 4096 (minus SL mail header) bytes.&lt;br /&gt;
&lt;br /&gt;
* Receive messages longer than 1024 bytes.&lt;br /&gt;
&lt;br /&gt;
* Permanent mail addresses for the SL Mail client (like: &amp;lt;Flennan.Roffo@somedomain.sl&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Add your RFC!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In-world join the group &amp;quot;SL Mail&amp;quot; for bug reports, feature requests, the latest SL Mail release, and notices about development issues.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scripts=&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==Script: SL Mail v1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail core module which scans for incoming mail messages and executes commands used by the owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail V1.2.lsl&lt;br /&gt;
// (c) 2007 Logic Scripted Products and Script Services&lt;br /&gt;
// Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
// VERSION&lt;br /&gt;
// Version: 1.2&lt;br /&gt;
&lt;br /&gt;
// HISTORY&lt;br /&gt;
// Date         Version     Author              Comment&lt;br /&gt;
// --------------------------------------------------------------------------------------&lt;br /&gt;
// 28 aug 2007  V 1.0       Flennan Roffo       Created&lt;br /&gt;
//&lt;br /&gt;
//  1 sep 2007  V 1.1       Flennan Roffo       @Reply empties the recording buffer.&lt;br /&gt;
//                                                @Send while recording ends recording&lt;br /&gt;
//                                                and sends the mail if a mail address&lt;br /&gt;
//                                                and subject are supplied.&lt;br /&gt;
//                                                Fixed incorrect date in Unix2DateTime.&lt;br /&gt;
//  3 sep 2007  V 1.2       Flennan Roffo       Notification options:&lt;br /&gt;
//                                              - When online, send an IM when mail is received.&lt;br /&gt;
//                                              - When offline, send to HOME mail adress.&lt;br /&gt;
//                                              Adressbook&lt;br /&gt;
//                                              - Read adress book from config notecard.&lt;br /&gt;
&lt;br /&gt;
// LICENCE&lt;br /&gt;
// This program is free software; you can redistribute it and/or&lt;br /&gt;
// modify it under the terms of the GNU General Public License&lt;br /&gt;
// as published by the Free Software Foundation; either version 2&lt;br /&gt;
// of the License, or (at your option) any later version.&lt;br /&gt;
// &lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
// &lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program; if not, write to the Free Software&lt;br /&gt;
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
// (Also available at http://www.gnu.org/copyleft/gpl.html) &lt;br /&gt;
&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// Let&#039;s you record a message and sent to email and get messages and reply to messages.&lt;br /&gt;
// Must supply a valid mail adress and non-empty subject using chat commands.&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
// 1) Check for the maximum length of an email message (including newline and header).&lt;br /&gt;
// 2) Read adress book from notecard.                                    *DONE*&lt;br /&gt;
// 3) Send incoming mail to personal mail adress when offline.            *DONE*&lt;br /&gt;
// 4) Alert with an IM when online upon receiving new mail.                *DONE*&lt;br /&gt;
&lt;br /&gt;
string   SL_MAIL_VERSION = &amp;quot;V 1.2&amp;quot;;&lt;br /&gt;
string   SL_MAIL_DATE    = &amp;quot; 2 sep 2007&amp;quot;;&lt;br /&gt;
integer  ErrorFlag         = FALSE;&lt;br /&gt;
list     ScriptList        = [ &amp;quot;SL Mail Help V1.2&amp;quot;, &amp;quot;SL Mail AddressBook V1.2&amp;quot;, &lt;br /&gt;
                                &amp;quot;SL Mail OnlineStatus V1.2&amp;quot;, &amp;quot;SL Mail FetchNotecard V1.2&amp;quot; ];    &lt;br /&gt;
string   LSL_DOMAIN=&amp;quot;lsl.secondlife.com&amp;quot;; &lt;br /&gt;
integer  StatusOnline=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Commands&lt;br /&gt;
&lt;br /&gt;
string  COMMAND_RECORD     = &amp;quot;@RECORD&amp;quot;;&lt;br /&gt;
string  COMMAND_CONTINUE   = &amp;quot;@CONTINUE&amp;quot;;&lt;br /&gt;
string  COMMAND_STOP       = &amp;quot;@STOP&amp;quot;;&lt;br /&gt;
string  COMMAND_MAIL       = &amp;quot;@MAIL&amp;quot;;&lt;br /&gt;
string  COMMAND_SUBJECT    = &amp;quot;@SUBJECT&amp;quot;;&lt;br /&gt;
string  COMMAND_SEND       = &amp;quot;@SEND&amp;quot;;&lt;br /&gt;
string  COMMAND_SEE        = &amp;quot;@SEE&amp;quot;;&lt;br /&gt;
string  COMMAND_IGNORE     = &amp;quot;@IGNORE&amp;quot;;&lt;br /&gt;
string  COMMAND_READ       = &amp;quot;@READ&amp;quot;;&lt;br /&gt;
string  COMMAND_DELETE     = &amp;quot;@DELETE&amp;quot;;&lt;br /&gt;
string  COMMAND_CLEAR      = &amp;quot;@CLEAR&amp;quot;;&lt;br /&gt;
string  COMMAND_REPLY      = &amp;quot;@REPLY&amp;quot;;&lt;br /&gt;
string  COMMAND_NEXT       = &amp;quot;@NEXT&amp;quot;;&lt;br /&gt;
string  COMMAND_PREV       = &amp;quot;@PREV&amp;quot;;&lt;br /&gt;
string  COMMAND_FIRST      = &amp;quot;@FIRST&amp;quot;;&lt;br /&gt;
string  COMMAND_LAST       = &amp;quot;@LAST&amp;quot;;&lt;br /&gt;
string  COMMAND_LIST       = &amp;quot;@LIST&amp;quot;;&lt;br /&gt;
string  COMMAND_SELECT     = &amp;quot;@SELECT&amp;quot;;&lt;br /&gt;
string  COMMAND_HELP       = &amp;quot;@HELP&amp;quot;;&lt;br /&gt;
string  COMMAND_INFO       = &amp;quot;@INFO&amp;quot;;&lt;br /&gt;
string  COMMAND_RESET      = &amp;quot;@RESET&amp;quot;;&lt;br /&gt;
string  COMMAND_SHOW       = &amp;quot;@SHOW&amp;quot;;&lt;br /&gt;
string  COMMAND_ON         = &amp;quot;@ON&amp;quot;;&lt;br /&gt;
string  COMMAND_OFF        = &amp;quot;@OFF&amp;quot;;&lt;br /&gt;
string  COMMAND_HOME       = &amp;quot;@HOME&amp;quot;;&lt;br /&gt;
string  COMMAND_LOAD       = &amp;quot;@LOAD&amp;quot;;&lt;br /&gt;
string  COMMAND_ADDRESS    = &amp;quot;@ADDRESS&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Recording&lt;br /&gt;
&lt;br /&gt;
integer Recording = FALSE;&lt;br /&gt;
&lt;br /&gt;
list    ChatRecording=[];&lt;br /&gt;
integer NumLines=0;&lt;br /&gt;
integer Length=0;&lt;br /&gt;
&lt;br /&gt;
list     TimeList=[];&lt;br /&gt;
list     AddressList=[];&lt;br /&gt;
list     SubjectList=[];&lt;br /&gt;
list     BodyList=[];&lt;br /&gt;
integer  NumMessages=0;&lt;br /&gt;
integer  CurrentMessage=-1;&lt;br /&gt;
&lt;br /&gt;
float    MAIL_FETCH_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
// Link Messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP                        = 10000;&lt;br /&gt;
integer MSG_STATUS_ONLINE               = 30000;&lt;br /&gt;
integer MSG_STATUS_OFFLINE              = 30100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED          = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR           = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Unix Time conversion //////////////////&lt;br /&gt;
&lt;br /&gt;
integer DAYS_PER_YEAR        = 365;                // Non leap year&lt;br /&gt;
integer SECONDS_PER_YEAR     = 31536000;          // Non leap year&lt;br /&gt;
integer SECONDS_PER_DAY      = 86400;&lt;br /&gt;
integer SECONDS_PER_HOUR     = 3600;&lt;br /&gt;
integer SECONDS_PER_MINUTE   = 60;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// LeapYear() /////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer LeapYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (year % 4 == 0)&lt;br /&gt;
    {&lt;br /&gt;
        if (year % 100 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (year % 400 == 0)&lt;br /&gt;
            {&lt;br /&gt;
                return 1;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// DaysPerMonth() ///////////////////////////////////////&lt;br /&gt;
                &lt;br /&gt;
integer DaysPerMonth(integer year,integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;lt; 8)&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (month == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if (LeapYear(year))&lt;br /&gt;
                {&lt;br /&gt;
                    return 29;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    return 28;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 30;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 30;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////// DaysPerYear() ////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DaysPerYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (LeapYear(year))&lt;br /&gt;
        return DAYS_PER_YEAR + 1;&lt;br /&gt;
    else&lt;br /&gt;
        return DAYS_PER_YEAR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Unix2DataTime() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list Unix2DateTime(integer unixtime)&lt;br /&gt;
{&lt;br /&gt;
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;&lt;br /&gt;
    integer day = days_since_1_1_1970 + 1;&lt;br /&gt;
    integer year  = 1970;&lt;br /&gt;
    integer days_per_year = DaysPerYear(year);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_year)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_year;&lt;br /&gt;
        ++year;&lt;br /&gt;
        days_per_year = DaysPerYear(year);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer month = 1;&lt;br /&gt;
    integer days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_month)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_month;&lt;br /&gt;
        &lt;br /&gt;
        if (++month &amp;gt; 12)&lt;br /&gt;
        {    &lt;br /&gt;
            ++year;&lt;br /&gt;
            month = 1;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;&lt;br /&gt;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;&lt;br /&gt;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;&lt;br /&gt;
    integer minute      = second / SECONDS_PER_MINUTE;&lt;br /&gt;
    second               = second % SECONDS_PER_MINUTE;&lt;br /&gt;
    &lt;br /&gt;
    return [ year, month, day, hour, minute, second ];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// MonthName() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list MonthNameList = [     &amp;quot;JAN&amp;quot;, &amp;quot;FEB&amp;quot;, &amp;quot;MAR&amp;quot;, &amp;quot;APR&amp;quot;, &amp;quot;MAY&amp;quot;, &amp;quot;JUN&amp;quot;, &lt;br /&gt;
                        &amp;quot;JUL&amp;quot;, &amp;quot;AUG&amp;quot;, &amp;quot;SEP&amp;quot;, &amp;quot;OCT&amp;quot; , &amp;quot;NOV&amp;quot;, &amp;quot;DEC&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
string MonthName(integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;gt;= 0 &amp;amp;&amp;amp; month &amp;lt; 12)&lt;br /&gt;
        return llList2String(MonthNameList, month);&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// DateString() ///////////////////////////&lt;br /&gt;
&lt;br /&gt;
string DateString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer year       = llList2Integer(timelist,0);&lt;br /&gt;
    integer month      = llList2Integer(timelist,1);&lt;br /&gt;
    integer day        = llList2Integer(timelist,2);&lt;br /&gt;
    &lt;br /&gt;
    return (string)day + &amp;quot;-&amp;quot; + MonthName(month - 1) + &amp;quot;-&amp;quot; + (string)year;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// TimeString() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string TimeString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer hour          = llList2Integer(timelist,3);&lt;br /&gt;
    integer minute         = llList2Integer(timelist,4);&lt;br /&gt;
    integer second         = llList2Integer(timelist,5);&lt;br /&gt;
    string  hourstr     = (string)hour;&lt;br /&gt;
    string  minutestr   = (string)minute;&lt;br /&gt;
    string  secondstr   = (string)second;&lt;br /&gt;
    &lt;br /&gt;
    if (hour &amp;lt; 10)         hourstr     = &amp;quot;0&amp;quot; + hourstr;&lt;br /&gt;
    if (minute &amp;lt; 10)     minutestr     = &amp;quot;0&amp;quot; + minutestr;&lt;br /&gt;
    if (second &amp;lt; 10)    secondstr    = &amp;quot;0&amp;quot; + secondstr;&lt;br /&gt;
    return hourstr + &amp;quot;:&amp;quot; + minutestr + &amp;quot;:&amp;quot; + secondstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() /////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string body)&lt;br /&gt;
{&lt;br /&gt;
    // llOwnerSay(&amp;quot;Sending message to &#039;&amp;quot; + address + &amp;quot;&#039; with subject &#039;&amp;quot; + subject +&amp;quot;&#039;.&amp;quot;);&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND, body, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// SendHome() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendHome(string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SENDHOME, body, (key)subject);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Show() ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Show()&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;Current chat recording is:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; NumLines; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(ChatRecording,i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;Lines is &amp;quot; + (string)NumLines);&lt;br /&gt;
    llOwnerSay(&amp;quot;Message length is &amp;quot; + (string)Length);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Read() /////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Read()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;Reading message &amp;quot; + (string)CurrentMessage + &amp;quot; from mail buffer.&amp;quot;);&lt;br /&gt;
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);&lt;br /&gt;
    list timelist=Unix2DateTime(time);&lt;br /&gt;
    string Address = llList2String(AddressList,CurrentMessage);&lt;br /&gt;
    string Subject = llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
    string Body    = llList2String(BodyList,CurrentMessage);&lt;br /&gt;
    llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Address: &amp;quot; + Address);&lt;br /&gt;
    llOwnerSay(&amp;quot;Subject: &amp;quot; + Subject);&lt;br /&gt;
    llOwnerSay(&amp;quot;Begin of message body:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    list bodylist=llParseStringKeepNulls(Body, [ &amp;quot;\n&amp;quot; ], []);&lt;br /&gt;
    integer num=llGetListLength(bodylist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(bodylist,i));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;End of message body.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////// List ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
List()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;The mail buffer contains the following messages:\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; NumMessages; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer time=llList2Integer(TimeList,i);&lt;br /&gt;
        list timelist=Unix2DateTime(time);&lt;br /&gt;
        if (i &amp;gt; 0) llOwnerSay(&amp;quot;+-+-+-+-+-+-+-+-+-+-+-+-&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Message: &amp;quot; + (string)i);&lt;br /&gt;
        llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;From:    &amp;quot; + llList2String(AddressList,i));&lt;br /&gt;
        llOwnerSay(&amp;quot;Subject: &amp;quot; + llList2String(SubjectList,i));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////// NotifyNewMail() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
NotifyNewMail(string time, string address, string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    list timelist=Unix2DateTime((integer)time);&lt;br /&gt;
&lt;br /&gt;
    if (StatusOnline)&lt;br /&gt;
    {&lt;br /&gt;
        llInstantMessage(llGetOwner(), &amp;quot;You received a new mail message on &amp;quot; &lt;br /&gt;
                                    + DateString(timelist) + &amp;quot; at &amp;quot; + TimeString(timelist)&lt;br /&gt;
                                    + &amp;quot; from &amp;quot; + address &lt;br /&gt;
                                    + &amp;quot; with the subject &amp;quot; + subject);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        SendHome(&amp;quot;FW: &amp;quot; + subject, &amp;quot;Received at: &amp;quot; + DateString(timelist) + &amp;quot; &amp;quot; + TimeString(timelist) + &amp;quot;\nFrom: &amp;quot; +  address &lt;br /&gt;
                    + &amp;quot;\nBegin message body:\n-------------------\n&amp;quot; + body + &amp;quot;\n-------------------\nEnd message body.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ResetOtherScripts() //////////////////////&lt;br /&gt;
&lt;br /&gt;
ResetOtherScripts()&lt;br /&gt;
{&lt;br /&gt;
    string     name;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(ScriptList);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        name = llList2String(ScriptList,i);&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(name) == INVENTORY_SCRIPT)&lt;br /&gt;
        {&lt;br /&gt;
            llResetOtherScript(name);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Error - script &#039;&amp;quot; + name + &amp;quot;&#039; not found.&amp;quot;);&lt;br /&gt;
            ErrorFlag = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
// default &lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ////////////////////// state_entry() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Welcome to SL Mail, released under GNU software licence.&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Version &amp;quot; + SL_MAIL_VERSION + &amp;quot; &amp;quot; + SL_MAIL_DATE);&lt;br /&gt;
        llOwnerSay(&amp;quot;Produced by Logic Scripted Products &amp;amp; Product Services&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Free memory: &amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
        ResetOtherScripts();&lt;br /&gt;
        &lt;br /&gt;
        if (ErrorFlag)&lt;br /&gt;
            state Error;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// on_rez() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// changed() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_LOADED)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_ERROR)&lt;br /&gt;
        {&lt;br /&gt;
            state Error;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() //////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(MAIL_FETCH_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //////////////////////// on_rez() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// listen() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string trimmessage=llStringTrim(message,STRING_TRIM);&lt;br /&gt;
        list   parse = llParseStringKeepNulls(trimmessage, [ &amp;quot; &amp;quot;], []);&lt;br /&gt;
        string command = llToUpper(llList2String(parse,0));&lt;br /&gt;
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        integer nargs  = llGetListLength(parse);&lt;br /&gt;
        string argstr=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (nargs &amp;gt; 1) argstr=llGetSubString(message, llSubStringIndex(message, &amp;quot; &amp;quot;) + 1, -1);&lt;br /&gt;
            &lt;br /&gt;
        if (Recording)&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Recording stopped. Type @SHOW to see the message you have entered,&amp;quot;&lt;br /&gt;
                            + &amp;quot; or @SEND to send it.&amp;quot;);&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                &lt;br /&gt;
                SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];&lt;br /&gt;
                ++NumLines;&lt;br /&gt;
                Length += llStringLength(message) + 2;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_RECORD)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Start recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                ChatRecording = [];&lt;br /&gt;
                NumLines=0;&lt;br /&gt;
                Length=0;&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CONTINUE)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Continue recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_REPLY)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    string address=llList2String(AddressList,CurrentMessage);&lt;br /&gt;
                    string subject=&amp;quot;Re: &amp;quot; + llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, address, NULL_KEY);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, subject, NULL_KEY);&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines=0;&lt;br /&gt;
                    Length=0;&lt;br /&gt;
                    Recording = TRUE;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_MAIL)&lt;br /&gt;
            {&lt;br /&gt;
                string mailaddress=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailaddress != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, mailaddress, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETADDRESS, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SUBJECT)&lt;br /&gt;
            {&lt;br /&gt;
                string mailsubject=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailsubject != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, mailsubject, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETSUBJECT, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Not recording.&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    if (NumLines == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND_NOTECARD, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_IGNORE)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines = 0;&lt;br /&gt;
                    Length = 0;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Show();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_READ)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumMessages == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Read();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        ++CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        --CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_FIRST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = 0;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LAST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LIST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    List();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SELECT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;Need to supply a message number.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    integer msgnum = (integer)arg;&lt;br /&gt;
                     &lt;br /&gt;
                    if (msgnum &amp;lt; 0 || msgnum &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Message number &amp;quot; + arg + &amp;quot; not in mail buffer.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = msgnum;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_DELETE)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    --NumMessages;&lt;br /&gt;
                     &lt;br /&gt;
                    if (NumMessages == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = -1;&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (CurrentMessage &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CLEAR)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList=[];&lt;br /&gt;
                    AddressList=[];&lt;br /&gt;
                    SubjectList=[];&lt;br /&gt;
                    BodyList=[];&lt;br /&gt;
                    NumMessages=0;&lt;br /&gt;
                    CurrentMessage=-1;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_HELP, arg, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_INFO)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                Show();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_RESET)&lt;br /&gt;
            {&lt;br /&gt;
                llResetScript();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                state not_running;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HOME)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs==1)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETHOME, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETHOME, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// email() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    email(string time, string address, string subject, string body, integer queued)&lt;br /&gt;
    {&lt;br /&gt;
        NotifyNewMail(time, address, subject, body);&lt;br /&gt;
        TimeList = (TimeList=[]) + TimeList + [time];&lt;br /&gt;
        AddressList = (AddressList=[]) + AddressList + [address];&lt;br /&gt;
        SubjectList = (SubjectList=[]) + SubjectList + [subject];&lt;br /&gt;
        BodyList = (BodyList=[]) + BodyList + [body];&lt;br /&gt;
        ++NumMessages;&lt;br /&gt;
        &lt;br /&gt;
        if (CurrentMessage == -1)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = NumMessages - 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_REPLY)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state not_running&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state not_running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;SL Mailbox switched OFF. Say @ON to switch it back on.&amp;quot;);&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// on_rez() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// listen() ////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer chan, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string command=llToUpper(message);&lt;br /&gt;
        &lt;br /&gt;
        if (command == COMMAND_ON)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state Error&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state Error&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Error in SL Mail: not all component scripts found.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// End SL Mail V1.2.lsl&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Address Book V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Read and interpret the contents of the Address Book.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail AddressBook V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// &lt;br /&gt;
//  Read the Address Book from a notecard named &amp;quot;Address Book&amp;quot;.&lt;br /&gt;
//&lt;br /&gt;
//  The Address Book has the following format:&lt;br /&gt;
//  &lt;br /&gt;
//  [ADDRESS BOOK]&lt;br /&gt;
//  Name1=username@yourdomain.com&lt;br /&gt;
//  Name2=otheruser@otherdomain.com&lt;br /&gt;
//  ...&lt;br /&gt;
//  [GROUP]&lt;br /&gt;
//  group1=Name1, Name2&lt;br /&gt;
//  ...&lt;br /&gt;
//&lt;br /&gt;
//  Notes:&lt;br /&gt;
//  1. Group and Name share the same namespace, and must be unique.&lt;br /&gt;
//  2. It is allowed to have a name in the addressbook with multiple addresses, seperated by comma&#039;s.&lt;br /&gt;
// &lt;br /&gt;
/////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string  CurrentMailAddress = &amp;quot;&amp;quot;;&lt;br /&gt;
string  CurrentMailSubject = &amp;quot;&amp;quot;;&lt;br /&gt;
integer StatusOnline = FALSE;&lt;br /&gt;
&lt;br /&gt;
// Fetch or Send notecard&lt;br /&gt;
&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Names&lt;br /&gt;
&lt;br /&gt;
list    AddressBookList=[];&lt;br /&gt;
list    MailAddressList=[];&lt;br /&gt;
&lt;br /&gt;
string  STRING_HOME=&amp;quot;HOME&amp;quot;;&lt;br /&gt;
string  STRING_SELF=&amp;quot;SELF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Groups&lt;br /&gt;
&lt;br /&gt;
list   GroupList=[];&lt;br /&gt;
list   GroupNameList=[];&lt;br /&gt;
&lt;br /&gt;
string LSL_DOMAIN = &amp;quot;lsl.secondlife.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Read Address Book notecard&lt;br /&gt;
&lt;br /&gt;
string  ADDRESSBOOK_NOTECARD=&amp;quot;Address Book&amp;quot;;&lt;br /&gt;
integer Line=0;&lt;br /&gt;
key     reqAddressBook=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
integer Section=0;&lt;br /&gt;
integer SECTION_ADDRESS_BOOK=1;&lt;br /&gt;
integer SECTION_GROUP=2;&lt;br /&gt;
string  STRING_ADDRESS_BOOK=&amp;quot;ADDRESS BOOK&amp;quot;;&lt;br /&gt;
string  STRING_GROUP=&amp;quot;GROUP&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Links messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
integer MSG_MESSAGE_NOTIFY              = 90900;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED            = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR            = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// GetSelfAddress() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
string GetSelfAddress()&lt;br /&gt;
{&lt;br /&gt;
    return (string)llGetKey() + &amp;quot;@&amp;quot; + LSL_DOMAIN;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Info() /////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Info()&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;The mail address for this object is: &amp;quot; &lt;br /&gt;
                    + GetSelfAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// IsValidKeyFormat() //////////////////////&lt;br /&gt;
&lt;br /&gt;
integer IsValidKeyFormat(string str)&lt;br /&gt;
{&lt;br /&gt;
    string keychars = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    if (llStringLength(str) != 36)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    if( (llGetSubString( str, 8, 8 )   != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 13, 13 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 18, 18 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 23, 23 )  != &amp;quot;-&amp;quot; ) )&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 9; i &amp;lt; 13; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 14; i &amp;lt; 18; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 19; i &amp;lt; 23; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 24; i &amp;lt; 36; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// ValidMailAddress() ////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer ValidMailAddress(string arg)&lt;br /&gt;
{&lt;br /&gt;
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));&lt;br /&gt;
    &lt;br /&gt;
    if (adress == &amp;quot;&amp;quot;)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    list parse = llParseStringKeepNulls(adress, [ &amp;quot;@&amp;quot; ], []);&lt;br /&gt;
    string account = llList2String(parse,0);&lt;br /&gt;
    string domain  = llList2String(parse,1);&lt;br /&gt;
    &lt;br /&gt;
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    &lt;br /&gt;
    if (domain == LSL_DOMAIN)&lt;br /&gt;
    {&lt;br /&gt;
        return IsValidKeyFormat(account);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list parsedomain = llParseString2List(domain, [ &amp;quot;.&amp;quot; ], []);&lt;br /&gt;
    &lt;br /&gt;
        if (llGetListLength(parsedomain) &amp;lt; 2)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        &lt;br /&gt;
        integer num = llGetListLength(parsedomain);&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llStringLength(llList2String(parsedomain,i)) &amp;lt; 2)&lt;br /&gt;
            {&lt;br /&gt;
                return FALSE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetAddressStr() ///////////////////&lt;br /&gt;
&lt;br /&gt;
string GetAndCheckAddressStr(string address)&lt;br /&gt;
{&lt;br /&gt;
    list addresslist = llCSV2List(address);&lt;br /&gt;
    integer num=llGetListLength(addresslist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    string addressstr=&amp;quot;&amp;quot;;&lt;br /&gt;
    string curaddress=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        curaddress=llList2String(addresslist,i);&lt;br /&gt;
        &lt;br /&gt;
        if (ValidMailAddress(curaddress))&lt;br /&gt;
        {&lt;br /&gt;
            addressstr = (addressstr=&amp;quot;&amp;quot;) + addressstr + curaddress + &amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address string: &#039;&amp;quot; &lt;br /&gt;
                            + curaddress + &amp;quot;&#039;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return llGetSubString(addressstr, 0, -2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ProcessLine() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
ProcessLine(string rawline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(rawline,STRING_TRIM);&lt;br /&gt;
    string first=llGetSubString(line,0,0);&lt;br /&gt;
    string last=llGetSubString(line,-1,-1);&lt;br /&gt;
    &lt;br /&gt;
    // Ignore a blank line or comment line&lt;br /&gt;
    if (line == &amp;quot;&amp;quot; || first == &amp;quot;#&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // Check for the right section&lt;br /&gt;
    &lt;br /&gt;
    if (first == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; last == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        string sectionstr=llToUpper(llStringTrim(llGetSubString(line,1,-2),STRING_TRIM));&lt;br /&gt;
        &lt;br /&gt;
        if (sectionstr == STRING_ADDRESS_BOOK)&lt;br /&gt;
        {&lt;br /&gt;
            Section = SECTION_ADDRESS_BOOK;&lt;br /&gt;
        }&lt;br /&gt;
        else if (sectionstr == STRING_GROUP)&lt;br /&gt;
        {&lt;br /&gt;
            if (Section == 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                        + &amp;quot;. Group section defined before Address Book section.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Section = SECTION_GROUP;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid section header &#039;&amp;quot; + sectionstr &lt;br /&gt;
                        + &amp;quot;&#039; in &amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Must be in a section&lt;br /&gt;
    &lt;br /&gt;
    if (Section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;. No section header.&amp;quot;, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    list     parse=llParseString2List(line, [ &amp;quot;=&amp;quot; ], []);&lt;br /&gt;
    integer  num=llGetListLength(parse);&lt;br /&gt;
    &lt;br /&gt;
    // Format must be correct&lt;br /&gt;
    &lt;br /&gt;
    if (num != 2)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; +  (string)(Line+1) + &amp;quot;:\n&amp;quot; + rawline, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (Section == SECTION_ADDRESS_BOOK)&lt;br /&gt;
    {&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(name) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + name &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ name ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            string address=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
            string addressstr=GetAndCheckAddressStr(address);&lt;br /&gt;
            &lt;br /&gt;
            if (addressstr != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                AddressBookList     = (AddressBookList=[])     + AddressBookList     + [ name ];&lt;br /&gt;
                MailAddressList     = (MailAddressList=[])     + MailAddressList     + [ addressstr ];&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;No valid mail address for &#039;&amp;quot; + name &lt;br /&gt;
                    + &amp;quot;&#039;. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                    + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name &lt;br /&gt;
                + &amp;quot;&#039; already defined. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // Group&lt;br /&gt;
    {&lt;br /&gt;
        string group=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(group) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + group &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ group ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(GroupList, [ group ]) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                string names=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
                list   namelist=llCSV2List(names);&lt;br /&gt;
                integer num=llGetListLength(namelist);&lt;br /&gt;
                integer i;&lt;br /&gt;
                integer index;&lt;br /&gt;
                string  name;&lt;br /&gt;
                string  namestr=&amp;quot;&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
                for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                    name=llList2String(namelist,i);&lt;br /&gt;
                    index=llListFindList(AddressBookList, [ name ]);&lt;br /&gt;
            &lt;br /&gt;
                    if (index == -1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name + &amp;quot;&#039; defined in Group &#039;&amp;quot; &lt;br /&gt;
                                + group + &amp;quot;&#039; not found in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY); &lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        namestr = (namestr=&amp;quot;&amp;quot;) + namestr + name + &amp;quot;,&amp;quot;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (namestr != &amp;quot;&amp;quot;)&lt;br /&gt;
                {    &lt;br /&gt;
                    namestr=llGetSubString(namestr,0,-2);&lt;br /&gt;
                    GroupList         = (GroupList=[])         + GroupList     + [ group ];&lt;br /&gt;
                    GroupNameList     = (GroupNameList=[])    + GroupNameList + [ namestr ];&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                        + &amp;quot;&#039; has no valid names. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                        + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                    + &amp;quot;&#039; already defined in Group. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                    + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group&lt;br /&gt;
                + &amp;quot;&#039; already defined in Address Book. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// GetGroupAddressList ///////////////&lt;br /&gt;
&lt;br /&gt;
string GetGroupAddressList(string group)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(GroupList, [ group ]);&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(GroupList);&lt;br /&gt;
    string  grouplist=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        for (i = index; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2String(GroupList,i) == group)&lt;br /&gt;
            {&lt;br /&gt;
                grouplist = (grouplist=&amp;quot;&amp;quot;) + grouplist + llList2String(GroupNameList,i) + &amp;quot;,&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (grouplist != &amp;quot;&amp;quot;) grouplist=llGetSubString(grouplist,0,-2);   // remove last &amp;quot;,&amp;quot;&lt;br /&gt;
        return grouplist;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// SetMailAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetMailAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ address ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        index=llListFindList(GroupList, [ address ]);&lt;br /&gt;
        &lt;br /&gt;
        if (index == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llToUpper(address) == STRING_SELF)&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = GetSelfAddress();&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if(ValidMailAddress(address))&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = address;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Mail adress &amp;quot; + address &lt;br /&gt;
                            + &amp;quot; : not found in adress book or invalid format.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailAddress = GetGroupAddressList(address);&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        CurrentMailAddress = llList2String(MailAddressList,index);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                        + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string message)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No mail address defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No subject defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list mailaddresslist=llCSV2List(CurrentMailAddress);&lt;br /&gt;
        integer num=llGetListLength(mailaddresslist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(mailaddresslist,i);&lt;br /&gt;
            llEmail(address, CurrentMailSubject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMailHome() ////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMailHome(string message, string subject)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, STRING_HOME &lt;br /&gt;
                + &amp;quot; not set. Set your home adress with @HOME &amp;lt;address&amp;gt;.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        string homeaddress=llList2String(AddressBookList,index);&lt;br /&gt;
        list   homelist=llCSV2List(homeaddress);&lt;br /&gt;
        integer num=llGetListLength(homelist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(homelist,i);&lt;br /&gt;
            llEmail(address, subject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
string GetHomeAddress()&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;not set&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2String(MailAddressList,index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetHomeAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        AddressBookList     = (AddressBookList=[]) + [ STRING_HOME ] + AddressBookList;&lt;br /&gt;
        MailAddressList     = (MailAddressList=[]) + [ GetAndCheckAddressStr(address) ]  + MailAddressList;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MailAddressList = llListReplaceList(MailAddressList, [ GetAndCheckAddressStr(address) ], index, index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        Line=0;&lt;br /&gt;
        Section=0;&lt;br /&gt;
        llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// dataserver() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqAddressBook)&lt;br /&gt;
        {&lt;br /&gt;
            reqAddressBook = NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                ProcessLine(data);&lt;br /&gt;
                reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Address Book loaded.&amp;quot;, NULL_KEY);&lt;br /&gt;
                state running;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// timer() ///////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_ERROR, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Could not read Address Book: &amp;quot; &lt;br /&gt;
                            + ADDRESSBOOK_NOTECARD + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// link_message() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_MESSAGE_GETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is empty.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailSubject = message;&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is empty.&amp;quot;, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            SetMailAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Body of message to send is empty. &amp;quot; &lt;br /&gt;
                                +  &amp;quot;No mail is send.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SENDHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SendMailHome(message, (string)id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetInventoryType(message) == INVENTORY_NOTECARD)&lt;br /&gt;
            {&lt;br /&gt;
                Notecard2Fetch = message;                &lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_READ, message, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + message + &amp;quot; not found.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_NOTECARD_FETCHED)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + Notecard2Fetch &lt;br /&gt;
                            + &amp;quot; was empty or could not be read.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Home address is: &amp;quot; + GetHomeAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SetHomeAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_INFO)&lt;br /&gt;
        {&lt;br /&gt;
            Info();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
// End SL Mail AddressBook V1.2.lsl&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail FetchNotecard V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch the contents of a notecard and return it via link message as a string.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Notecard&lt;br /&gt;
&lt;br /&gt;
integer Line=0;&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
key     reqNotecard=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=10.0;&lt;br /&gt;
integer Fetched=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Lines&lt;br /&gt;
&lt;br /&gt;
list LineList=[];&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    /////////////////////// dataserver() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqNotecard)&lt;br /&gt;
        {&lt;br /&gt;
            reqNotecard=NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                LineList = (LineList=[]) + LineList + [ data ];&lt;br /&gt;
                reqNotecard = llGetNotecardLine(Notecard2Fetch, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Fetched=TRUE;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, llDumpList2String(LineList, &amp;quot;\n&amp;quot;), NULL_KEY);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /////////////////////// timer() ///////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        if (!Fetched)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            llSetTimerEvent(0.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer send, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_NOTECARD_READ)&lt;br /&gt;
        {&lt;br /&gt;
            Line=0;&lt;br /&gt;
            Notecard2Fetch=message;&lt;br /&gt;
            LineList=[];&lt;br /&gt;
            Fetched=FALSE;&lt;br /&gt;
            reqNotecard=llGetNotecardLine(Notecard2Fetch, Line);&lt;br /&gt;
            llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL OnlineStatus V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch online status of owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Online status&lt;br /&gt;
&lt;br /&gt;
key     reqOnlineStatus=NULL_KEY;&lt;br /&gt;
float   STATUS_INTERVAL=2.0;&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_STATUS_ONLINE       = 30000;&lt;br /&gt;
integer MS_STATUS_OFFLINE       = 30100;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus=llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
        llSetTimerEvent(STATUS_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// dataserver() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqOnlineStatus)&lt;br /&gt;
        {&lt;br /&gt;
            reqOnlineStatus = NULL_KEY;&lt;br /&gt;
        &lt;br /&gt;
            if (data==&amp;quot;1&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_STATUS_ONLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if (data==&amp;quot;0&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MS_STATUS_OFFLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus = llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Help V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Display help information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail Help V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP    = 10000;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Help() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Help()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;HELP for SL Mail V1.2.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;COMMANDS:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HELP               - displays help info.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@INFO               - display mailaddress of this object.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RECORD             - start recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CONTINUE           - continue recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@STOP               - stop recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@IGNORE             - ignore the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SHOW               - show what your recorded.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SEND               - send the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@MAIL &amp;lt;mailadress&amp;gt;  - set the mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SUBJECT subject    - set the mail subject.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LIST               - list messages in mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SELECT &amp;lt;message&amp;gt;   - select message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@READ               - read current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@NEXT               - read next message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@PREV               - read previous message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@FIRST              - read first message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LAST               - read last message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@DELETE             - delete current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CLEAR              - clear the mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@REPLY              - reply to current message.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RESET              - reset the script.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HOME               - set the home mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@OFF                - switch mailbox OFF.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@ON                 - switch mailbox ON.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_HELP)&lt;br /&gt;
        {&lt;br /&gt;
            Help();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail Help V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}&lt;/div&gt;</description>
			<pubDate>Sun, 07 Oct 2007 11:14:43 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:SL_Mail_V1.2</comments>
		</item>
		<item>
			<title>SL Mail V1.2</title>
			<link>https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34591</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34591</guid>
			<description>&lt;p&gt;Flennan Roffo: /* &amp;#039;&amp;#039;&amp;#039;PRODUCTION &amp;amp; MAINTANENCE&amp;#039;&amp;#039;&amp;#039; */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}} __NOTOC__&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=&#039;&#039;&#039;Second Life mail client&#039;&#039;&#039;=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Send and receive email from within Second Life from and to any address.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implemented with Address Book function (in a notecard named &#039;Address Book&#039;) to stores addresses by name  and to compile groups of named addresses. Current version is stand-alone (no server functionality) and uses chat commands only.&lt;br /&gt;
&lt;br /&gt;
[[Image:BannerSLMail.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=Release Notes V1.2=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 Release notes (edition 2, 4 sept 2007)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LICENCE INFO&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is released under GNU free software licence&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;PRODUCTION &amp;amp; MAINTANENCE&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
by Logic Scripted Products and Script Services&lt;br /&gt;
&lt;br /&gt;
[http://www.logicscripts.org {{Server}}/wiki/images/Logicbanner1.jpg]&lt;br /&gt;
&lt;br /&gt;
SLurl:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Contact: [[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
&lt;br /&gt;
Email: [mailto:info@slmail.info &#039;&#039;&#039;info&#039;&#039;&#039;] or [mailto:Flennan.Roffo@slmail.info &#039;&#039;&#039;Flennan Roffo&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;DESCRIPTION&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is a simple tool to send and receive mail from within SL.&lt;br /&gt;
You can either compose a message yourself using chat recording, or choose a notecard from inventory to send. The Address Book functionality allows you to use short names for mail recipients stored in a notecard. The current version does not have a persisent mail address. Watch out for the upcoming next release (V1.3) which will facilitate persisent in-world mail addresses and will be enhanced with many new features (See: Requests For Change (RFC).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;COMMANDS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Help&#039;&#039;&#039;&lt;br /&gt;
||Show Help about available commands&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Record&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording (for owner only).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Stop&#039;&#039;&#039;&lt;br /&gt;
||Stops the chat recording without sending&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Continue&#039;&#039;&#039;&lt;br /&gt;
||Continues a previously stopped chat recording. Lines will be appended to you recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Show&#039;&#039;&#039;&lt;br /&gt;
||Shows the content of the recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send&#039;&#039;&#039;&lt;br /&gt;
||If recording, stops the recording, and sends the mail (need to supply mail address and subject first!)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send &amp;lt;notecard&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Sends the content of the notecard, instead of the chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Ignore&#039;&#039;&#039;&lt;br /&gt;
||Ignores your current chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject &amp;lt;subject&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the subject of the mail.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail subject.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Set the HOME address of the owner (mail will be forwarder to this address when offline).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home&#039;&#039;&#039;&lt;br /&gt;
||Show the HOME address.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Info&#039;&#039;&#039;&lt;br /&gt;
||Shows the mail address the object this script is running in uses (e.g. &amp;lt;object-key&amp;gt;@lsl.secondlife.com).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Read&#039;&#039;&#039;&lt;br /&gt;
||Reads the current message from the mail buffer (the mail buffer gets filled with mail you receive)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Select &amp;lt;msg&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Select a message number from the availabe messages in the mail buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Next&#039;&#039;&#039;&lt;br /&gt;
||Make next message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Prev&#039;&#039;&#039;&lt;br /&gt;
||Make previous message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@First&#039;&#039;&#039;&lt;br /&gt;
||Make the first message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Last&#039;&#039;&#039;&lt;br /&gt;
||Make the last message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Clear&#039;&#039;&#039;&lt;br /&gt;
||Clear the mail buffer&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Delete&#039;&#039;&#039;&lt;br /&gt;
||Deletes only the current message&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Reply&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording to reply to the current message. Mail adress and subject are filled in automatically.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* Commands are case insensitive (&amp;quot;@read&amp;quot; == &amp;quot;@READ&amp;quot;). Arguments might not be case insensitive.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;ADDRESS BOOK FORMAT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
A notecard of the name &#039;Address Book&#039; is read during initialization which may contain Address Book items and Groups.&lt;br /&gt;
The notecard is split in two sections, which need to be defined in that particular order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[ADDRESS BOOK]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Defines the section in which you can put names for mail addresses,  like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name1=account@thisdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name2=user@otherdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[GROUP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define groups of previously defined names under a new name, like for instance:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyGroup=Name1, Name2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note that names of groups and individual mail adresses share the same namespace and must be unique.&lt;br /&gt;
&lt;br /&gt;
So when you filled in your mail adresses in the Address Book, you can now use:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail Name1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to  &amp;lt;account@thisdomain.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail MyGroup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to &amp;lt;account@thisdomain.com&amp;gt; and &amp;lt;user@otherdomain.com&amp;gt;&lt;br /&gt;
Mails will be sent one after another.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* Names for Addreses and Groups are case insensitive (e.g. &amp;quot;mary&amp;quot;  == &amp;quot;MARY&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* The special address &#039;Self&#039; can be used in commands where otherwise an address specification can be used. &#039;Self&#039; is case insensitive (e.g. &amp;quot;self&amp;quot; == &amp;quot;SELF&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LIMITATIONS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
The current version is limited by the following:&lt;br /&gt;
&lt;br /&gt;
* Chat recording lines are limited by the 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Output of lines from the mail buffer are also limited by this 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Incoming mail is limited to a 1000 (1024?) byte limit&lt;br /&gt;
&lt;br /&gt;
* Outgoing mai is limited by a 4096 byte limit, which includes the standard mail header (region/location info on the first two lines)&lt;br /&gt;
&lt;br /&gt;
We are making adjustments to this release to help overcome these limitations. At least the line lenght limit can be overcome by introducing a line continuation character (for example a hyphen &#039;-&#039;) that when used at the end of a line appends the next line, so lines longer then 255 bytes are possible then.&lt;br /&gt;
&lt;br /&gt;
To overcome the outgoing mail length limit, the mail can be broken textualy into parts, and each part can be send seperatedely, with an indication in the subject or in an introduced primary line of the mail body to indicate that the mail was split into parts.&lt;br /&gt;
For incoming mail and at least to receive mail from other SL Mail programs, a protocol will be introduced to receive mail in parts that are joined together after receiving them to form a single mail.&lt;br /&gt;
&lt;br /&gt;
These enhancements will be made available in the next release (V1.3) of SL Mail &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;BUGS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Report any bugs you find in this release to Logic (IM: Flennan Roffo).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;REQUEST FOR CHANGE (RFC)&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Do you have additional wishes for enhancement of this product?&lt;br /&gt;
Contact Flennan Roffo and we will see if they can be implemented in the next release.&lt;br /&gt;
&lt;br /&gt;
Existing RFC&#039;s are:&lt;br /&gt;
&lt;br /&gt;
* Menu support for commands.&lt;br /&gt;
&lt;br /&gt;
* Lines on incoming/outgoing mail longer than 255 bytes.&lt;br /&gt;
&lt;br /&gt;
* Send messages longer than 4096 (minus SL mail header) bytes.&lt;br /&gt;
&lt;br /&gt;
* Receive messages longer than 1024 bytes.&lt;br /&gt;
&lt;br /&gt;
* Permanent mail addresses for the SL Mail client (like: &amp;lt;Flennan.Roffo@somedomain.sl&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Add your RFC!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In-world join the group &amp;quot;SL Mail&amp;quot; for bug reports, feature requests, the latest SL Mail release, and notices about development issues.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scripts=&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==Script: SL Mail v1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail core module which scans for incoming mail messages and executes commands used by the owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail V1.2.lsl&lt;br /&gt;
// (c) 2007 Logic Scripted Products and Script Services&lt;br /&gt;
// Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
// VERSION&lt;br /&gt;
// Version: 1.2&lt;br /&gt;
&lt;br /&gt;
// HISTORY&lt;br /&gt;
// Date         Version     Author              Comment&lt;br /&gt;
// --------------------------------------------------------------------------------------&lt;br /&gt;
// 28 aug 2007  V 1.0       Flennan Roffo       Created&lt;br /&gt;
//&lt;br /&gt;
//  1 sep 2007  V 1.1       Flennan Roffo       @Reply empties the recording buffer.&lt;br /&gt;
//                                                @Send while recording ends recording&lt;br /&gt;
//                                                and sends the mail if a mail address&lt;br /&gt;
//                                                and subject are supplied.&lt;br /&gt;
//                                                Fixed incorrect date in Unix2DateTime.&lt;br /&gt;
//  3 sep 2007  V 1.2       Flennan Roffo       Notification options:&lt;br /&gt;
//                                              - When online, send an IM when mail is received.&lt;br /&gt;
//                                              - When offline, send to HOME mail adress.&lt;br /&gt;
//                                              Adressbook&lt;br /&gt;
//                                              - Read adress book from config notecard.&lt;br /&gt;
&lt;br /&gt;
// LICENCE&lt;br /&gt;
// This program is free software; you can redistribute it and/or&lt;br /&gt;
// modify it under the terms of the GNU General Public License&lt;br /&gt;
// as published by the Free Software Foundation; either version 2&lt;br /&gt;
// of the License, or (at your option) any later version.&lt;br /&gt;
// &lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
// &lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program; if not, write to the Free Software&lt;br /&gt;
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
// (Also available at http://www.gnu.org/copyleft/gpl.html) &lt;br /&gt;
&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// Let&#039;s you record a message and sent to email and get messages and reply to messages.&lt;br /&gt;
// Must supply a valid mail adress and non-empty subject using chat commands.&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
// 1) Check for the maximum length of an email message (including newline and header).&lt;br /&gt;
// 2) Read adress book from notecard.                                    *DONE*&lt;br /&gt;
// 3) Send incoming mail to personal mail adress when offline.            *DONE*&lt;br /&gt;
// 4) Alert with an IM when online upon receiving new mail.                *DONE*&lt;br /&gt;
&lt;br /&gt;
string   SL_MAIL_VERSION = &amp;quot;V 1.2&amp;quot;;&lt;br /&gt;
string   SL_MAIL_DATE    = &amp;quot; 2 sep 2007&amp;quot;;&lt;br /&gt;
integer  ErrorFlag         = FALSE;&lt;br /&gt;
list     ScriptList        = [ &amp;quot;SL Mail Help V1.2&amp;quot;, &amp;quot;SL Mail AddressBook V1.2&amp;quot;, &lt;br /&gt;
                                &amp;quot;SL Mail OnlineStatus V1.2&amp;quot;, &amp;quot;SL Mail FetchNotecard V1.2&amp;quot; ];    &lt;br /&gt;
string   LSL_DOMAIN=&amp;quot;lsl.secondlife.com&amp;quot;; &lt;br /&gt;
integer  StatusOnline=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Commands&lt;br /&gt;
&lt;br /&gt;
string  COMMAND_RECORD     = &amp;quot;@RECORD&amp;quot;;&lt;br /&gt;
string  COMMAND_CONTINUE   = &amp;quot;@CONTINUE&amp;quot;;&lt;br /&gt;
string  COMMAND_STOP       = &amp;quot;@STOP&amp;quot;;&lt;br /&gt;
string  COMMAND_MAIL       = &amp;quot;@MAIL&amp;quot;;&lt;br /&gt;
string  COMMAND_SUBJECT    = &amp;quot;@SUBJECT&amp;quot;;&lt;br /&gt;
string  COMMAND_SEND       = &amp;quot;@SEND&amp;quot;;&lt;br /&gt;
string  COMMAND_SEE        = &amp;quot;@SEE&amp;quot;;&lt;br /&gt;
string  COMMAND_IGNORE     = &amp;quot;@IGNORE&amp;quot;;&lt;br /&gt;
string  COMMAND_READ       = &amp;quot;@READ&amp;quot;;&lt;br /&gt;
string  COMMAND_DELETE     = &amp;quot;@DELETE&amp;quot;;&lt;br /&gt;
string  COMMAND_CLEAR      = &amp;quot;@CLEAR&amp;quot;;&lt;br /&gt;
string  COMMAND_REPLY      = &amp;quot;@REPLY&amp;quot;;&lt;br /&gt;
string  COMMAND_NEXT       = &amp;quot;@NEXT&amp;quot;;&lt;br /&gt;
string  COMMAND_PREV       = &amp;quot;@PREV&amp;quot;;&lt;br /&gt;
string  COMMAND_FIRST      = &amp;quot;@FIRST&amp;quot;;&lt;br /&gt;
string  COMMAND_LAST       = &amp;quot;@LAST&amp;quot;;&lt;br /&gt;
string  COMMAND_LIST       = &amp;quot;@LIST&amp;quot;;&lt;br /&gt;
string  COMMAND_SELECT     = &amp;quot;@SELECT&amp;quot;;&lt;br /&gt;
string  COMMAND_HELP       = &amp;quot;@HELP&amp;quot;;&lt;br /&gt;
string  COMMAND_INFO       = &amp;quot;@INFO&amp;quot;;&lt;br /&gt;
string  COMMAND_RESET      = &amp;quot;@RESET&amp;quot;;&lt;br /&gt;
string  COMMAND_SHOW       = &amp;quot;@SHOW&amp;quot;;&lt;br /&gt;
string  COMMAND_ON         = &amp;quot;@ON&amp;quot;;&lt;br /&gt;
string  COMMAND_OFF        = &amp;quot;@OFF&amp;quot;;&lt;br /&gt;
string  COMMAND_HOME       = &amp;quot;@HOME&amp;quot;;&lt;br /&gt;
string  COMMAND_LOAD       = &amp;quot;@LOAD&amp;quot;;&lt;br /&gt;
string  COMMAND_ADDRESS    = &amp;quot;@ADDRESS&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Recording&lt;br /&gt;
&lt;br /&gt;
integer Recording = FALSE;&lt;br /&gt;
&lt;br /&gt;
list    ChatRecording=[];&lt;br /&gt;
integer NumLines=0;&lt;br /&gt;
integer Length=0;&lt;br /&gt;
&lt;br /&gt;
list     TimeList=[];&lt;br /&gt;
list     AddressList=[];&lt;br /&gt;
list     SubjectList=[];&lt;br /&gt;
list     BodyList=[];&lt;br /&gt;
integer  NumMessages=0;&lt;br /&gt;
integer  CurrentMessage=-1;&lt;br /&gt;
&lt;br /&gt;
float    MAIL_FETCH_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
// Link Messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP                        = 10000;&lt;br /&gt;
integer MSG_STATUS_ONLINE               = 30000;&lt;br /&gt;
integer MSG_STATUS_OFFLINE              = 30100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED          = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR           = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Unix Time conversion //////////////////&lt;br /&gt;
&lt;br /&gt;
integer DAYS_PER_YEAR        = 365;                // Non leap year&lt;br /&gt;
integer SECONDS_PER_YEAR     = 31536000;          // Non leap year&lt;br /&gt;
integer SECONDS_PER_DAY      = 86400;&lt;br /&gt;
integer SECONDS_PER_HOUR     = 3600;&lt;br /&gt;
integer SECONDS_PER_MINUTE   = 60;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// LeapYear() /////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer LeapYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (year % 4 == 0)&lt;br /&gt;
    {&lt;br /&gt;
        if (year % 100 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (year % 400 == 0)&lt;br /&gt;
            {&lt;br /&gt;
                return 1;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// DaysPerMonth() ///////////////////////////////////////&lt;br /&gt;
                &lt;br /&gt;
integer DaysPerMonth(integer year,integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;lt; 8)&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (month == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if (LeapYear(year))&lt;br /&gt;
                {&lt;br /&gt;
                    return 29;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    return 28;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 30;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 30;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////// DaysPerYear() ////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DaysPerYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (LeapYear(year))&lt;br /&gt;
        return DAYS_PER_YEAR + 1;&lt;br /&gt;
    else&lt;br /&gt;
        return DAYS_PER_YEAR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Unix2DataTime() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list Unix2DateTime(integer unixtime)&lt;br /&gt;
{&lt;br /&gt;
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;&lt;br /&gt;
    integer day = days_since_1_1_1970 + 1;&lt;br /&gt;
    integer year  = 1970;&lt;br /&gt;
    integer days_per_year = DaysPerYear(year);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_year)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_year;&lt;br /&gt;
        ++year;&lt;br /&gt;
        days_per_year = DaysPerYear(year);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer month = 1;&lt;br /&gt;
    integer days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_month)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_month;&lt;br /&gt;
        &lt;br /&gt;
        if (++month &amp;gt; 12)&lt;br /&gt;
        {    &lt;br /&gt;
            ++year;&lt;br /&gt;
            month = 1;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;&lt;br /&gt;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;&lt;br /&gt;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;&lt;br /&gt;
    integer minute      = second / SECONDS_PER_MINUTE;&lt;br /&gt;
    second               = second % SECONDS_PER_MINUTE;&lt;br /&gt;
    &lt;br /&gt;
    return [ year, month, day, hour, minute, second ];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// MonthName() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list MonthNameList = [     &amp;quot;JAN&amp;quot;, &amp;quot;FEB&amp;quot;, &amp;quot;MAR&amp;quot;, &amp;quot;APR&amp;quot;, &amp;quot;MAY&amp;quot;, &amp;quot;JUN&amp;quot;, &lt;br /&gt;
                        &amp;quot;JUL&amp;quot;, &amp;quot;AUG&amp;quot;, &amp;quot;SEP&amp;quot;, &amp;quot;OCT&amp;quot; , &amp;quot;NOV&amp;quot;, &amp;quot;DEC&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
string MonthName(integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;gt;= 0 &amp;amp;&amp;amp; month &amp;lt; 12)&lt;br /&gt;
        return llList2String(MonthNameList, month);&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// DateString() ///////////////////////////&lt;br /&gt;
&lt;br /&gt;
string DateString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer year       = llList2Integer(timelist,0);&lt;br /&gt;
    integer month      = llList2Integer(timelist,1);&lt;br /&gt;
    integer day        = llList2Integer(timelist,2);&lt;br /&gt;
    &lt;br /&gt;
    return (string)day + &amp;quot;-&amp;quot; + MonthName(month - 1) + &amp;quot;-&amp;quot; + (string)year;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// TimeString() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string TimeString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer hour          = llList2Integer(timelist,3);&lt;br /&gt;
    integer minute         = llList2Integer(timelist,4);&lt;br /&gt;
    integer second         = llList2Integer(timelist,5);&lt;br /&gt;
    string  hourstr     = (string)hour;&lt;br /&gt;
    string  minutestr   = (string)minute;&lt;br /&gt;
    string  secondstr   = (string)second;&lt;br /&gt;
    &lt;br /&gt;
    if (hour &amp;lt; 10)         hourstr     = &amp;quot;0&amp;quot; + hourstr;&lt;br /&gt;
    if (minute &amp;lt; 10)     minutestr     = &amp;quot;0&amp;quot; + minutestr;&lt;br /&gt;
    if (second &amp;lt; 10)    secondstr    = &amp;quot;0&amp;quot; + secondstr;&lt;br /&gt;
    return hourstr + &amp;quot;:&amp;quot; + minutestr + &amp;quot;:&amp;quot; + secondstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() /////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string body)&lt;br /&gt;
{&lt;br /&gt;
    // llOwnerSay(&amp;quot;Sending message to &#039;&amp;quot; + address + &amp;quot;&#039; with subject &#039;&amp;quot; + subject +&amp;quot;&#039;.&amp;quot;);&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND, body, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// SendHome() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendHome(string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SENDHOME, body, (key)subject);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Show() ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Show()&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;Current chat recording is:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; NumLines; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(ChatRecording,i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;Lines is &amp;quot; + (string)NumLines);&lt;br /&gt;
    llOwnerSay(&amp;quot;Message length is &amp;quot; + (string)Length);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Read() /////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Read()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;Reading message &amp;quot; + (string)CurrentMessage + &amp;quot; from mail buffer.&amp;quot;);&lt;br /&gt;
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);&lt;br /&gt;
    list timelist=Unix2DateTime(time);&lt;br /&gt;
    string Address = llList2String(AddressList,CurrentMessage);&lt;br /&gt;
    string Subject = llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
    string Body    = llList2String(BodyList,CurrentMessage);&lt;br /&gt;
    llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Address: &amp;quot; + Address);&lt;br /&gt;
    llOwnerSay(&amp;quot;Subject: &amp;quot; + Subject);&lt;br /&gt;
    llOwnerSay(&amp;quot;Begin of message body:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    list bodylist=llParseStringKeepNulls(Body, [ &amp;quot;\n&amp;quot; ], []);&lt;br /&gt;
    integer num=llGetListLength(bodylist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(bodylist,i));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;End of message body.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////// List ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
List()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;The mail buffer contains the following messages:\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; NumMessages; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer time=llList2Integer(TimeList,i);&lt;br /&gt;
        list timelist=Unix2DateTime(time);&lt;br /&gt;
        if (i &amp;gt; 0) llOwnerSay(&amp;quot;+-+-+-+-+-+-+-+-+-+-+-+-&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Message: &amp;quot; + (string)i);&lt;br /&gt;
        llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;From:    &amp;quot; + llList2String(AddressList,i));&lt;br /&gt;
        llOwnerSay(&amp;quot;Subject: &amp;quot; + llList2String(SubjectList,i));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////// NotifyNewMail() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
NotifyNewMail(string time, string address, string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    list timelist=Unix2DateTime((integer)time);&lt;br /&gt;
&lt;br /&gt;
    if (StatusOnline)&lt;br /&gt;
    {&lt;br /&gt;
        llInstantMessage(llGetOwner(), &amp;quot;You received a new mail message on &amp;quot; &lt;br /&gt;
                                    + DateString(timelist) + &amp;quot; at &amp;quot; + TimeString(timelist)&lt;br /&gt;
                                    + &amp;quot; from &amp;quot; + address &lt;br /&gt;
                                    + &amp;quot; with the subject &amp;quot; + subject);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        SendHome(&amp;quot;FW: &amp;quot; + subject, &amp;quot;Received at: &amp;quot; + DateString(timelist) + &amp;quot; &amp;quot; + TimeString(timelist) + &amp;quot;\nFrom: &amp;quot; +  address &lt;br /&gt;
                    + &amp;quot;\nBegin message body:\n-------------------\n&amp;quot; + body + &amp;quot;\n-------------------\nEnd message body.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ResetOtherScripts() //////////////////////&lt;br /&gt;
&lt;br /&gt;
ResetOtherScripts()&lt;br /&gt;
{&lt;br /&gt;
    string     name;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(ScriptList);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        name = llList2String(ScriptList,i);&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(name) == INVENTORY_SCRIPT)&lt;br /&gt;
        {&lt;br /&gt;
            llResetOtherScript(name);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Error - script &#039;&amp;quot; + name + &amp;quot;&#039; not found.&amp;quot;);&lt;br /&gt;
            ErrorFlag = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
// default &lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ////////////////////// state_entry() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Welcome to SL Mail, released under GNU software licence.&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Version &amp;quot; + SL_MAIL_VERSION + &amp;quot; &amp;quot; + SL_MAIL_DATE);&lt;br /&gt;
        llOwnerSay(&amp;quot;Produced by Logic Scripted Products &amp;amp; Product Services&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Free memory: &amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
        ResetOtherScripts();&lt;br /&gt;
        &lt;br /&gt;
        if (ErrorFlag)&lt;br /&gt;
            state Error;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// on_rez() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// changed() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_LOADED)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_ERROR)&lt;br /&gt;
        {&lt;br /&gt;
            state Error;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() //////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(MAIL_FETCH_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //////////////////////// on_rez() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// listen() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string trimmessage=llStringTrim(message,STRING_TRIM);&lt;br /&gt;
        list   parse = llParseStringKeepNulls(trimmessage, [ &amp;quot; &amp;quot;], []);&lt;br /&gt;
        string command = llToUpper(llList2String(parse,0));&lt;br /&gt;
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        integer nargs  = llGetListLength(parse);&lt;br /&gt;
        string argstr=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (nargs &amp;gt; 1) argstr=llGetSubString(message, llSubStringIndex(message, &amp;quot; &amp;quot;) + 1, -1);&lt;br /&gt;
            &lt;br /&gt;
        if (Recording)&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Recording stopped. Type @SHOW to see the message you have entered,&amp;quot;&lt;br /&gt;
                            + &amp;quot; or @SEND to send it.&amp;quot;);&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                &lt;br /&gt;
                SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];&lt;br /&gt;
                ++NumLines;&lt;br /&gt;
                Length += llStringLength(message) + 2;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_RECORD)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Start recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                ChatRecording = [];&lt;br /&gt;
                NumLines=0;&lt;br /&gt;
                Length=0;&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CONTINUE)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Continue recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_REPLY)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    string address=llList2String(AddressList,CurrentMessage);&lt;br /&gt;
                    string subject=&amp;quot;Re: &amp;quot; + llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, address, NULL_KEY);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, subject, NULL_KEY);&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines=0;&lt;br /&gt;
                    Length=0;&lt;br /&gt;
                    Recording = TRUE;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_MAIL)&lt;br /&gt;
            {&lt;br /&gt;
                string mailaddress=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailaddress != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, mailaddress, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETADDRESS, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SUBJECT)&lt;br /&gt;
            {&lt;br /&gt;
                string mailsubject=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailsubject != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, mailsubject, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETSUBJECT, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Not recording.&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    if (NumLines == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND_NOTECARD, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_IGNORE)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines = 0;&lt;br /&gt;
                    Length = 0;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Show();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_READ)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumMessages == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Read();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        ++CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        --CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_FIRST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = 0;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LAST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LIST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    List();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SELECT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;Need to supply a message number.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    integer msgnum = (integer)arg;&lt;br /&gt;
                     &lt;br /&gt;
                    if (msgnum &amp;lt; 0 || msgnum &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Message number &amp;quot; + arg + &amp;quot; not in mail buffer.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = msgnum;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_DELETE)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    --NumMessages;&lt;br /&gt;
                     &lt;br /&gt;
                    if (NumMessages == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = -1;&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (CurrentMessage &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CLEAR)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList=[];&lt;br /&gt;
                    AddressList=[];&lt;br /&gt;
                    SubjectList=[];&lt;br /&gt;
                    BodyList=[];&lt;br /&gt;
                    NumMessages=0;&lt;br /&gt;
                    CurrentMessage=-1;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_HELP, arg, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_INFO)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                Show();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_RESET)&lt;br /&gt;
            {&lt;br /&gt;
                llResetScript();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                state not_running;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HOME)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs==1)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETHOME, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETHOME, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// email() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    email(string time, string address, string subject, string body, integer queued)&lt;br /&gt;
    {&lt;br /&gt;
        NotifyNewMail(time, address, subject, body);&lt;br /&gt;
        TimeList = (TimeList=[]) + TimeList + [time];&lt;br /&gt;
        AddressList = (AddressList=[]) + AddressList + [address];&lt;br /&gt;
        SubjectList = (SubjectList=[]) + SubjectList + [subject];&lt;br /&gt;
        BodyList = (BodyList=[]) + BodyList + [body];&lt;br /&gt;
        ++NumMessages;&lt;br /&gt;
        &lt;br /&gt;
        if (CurrentMessage == -1)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = NumMessages - 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_REPLY)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state not_running&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state not_running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;SL Mailbox switched OFF. Say @ON to switch it back on.&amp;quot;);&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// on_rez() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// listen() ////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer chan, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string command=llToUpper(message);&lt;br /&gt;
        &lt;br /&gt;
        if (command == COMMAND_ON)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state Error&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state Error&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Error in SL Mail: not all component scripts found.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// End SL Mail V1.2.lsl&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Address Book V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Read and interpret the contents of the Address Book.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail AddressBook V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// &lt;br /&gt;
//  Read the Address Book from a notecard named &amp;quot;Address Book&amp;quot;.&lt;br /&gt;
//&lt;br /&gt;
//  The Address Book has the following format:&lt;br /&gt;
//  &lt;br /&gt;
//  [ADDRESS BOOK]&lt;br /&gt;
//  Name1=username@yourdomain.com&lt;br /&gt;
//  Name2=otheruser@otherdomain.com&lt;br /&gt;
//  ...&lt;br /&gt;
//  [GROUP]&lt;br /&gt;
//  group1=Name1, Name2&lt;br /&gt;
//  ...&lt;br /&gt;
//&lt;br /&gt;
//  Notes:&lt;br /&gt;
//  1. Group and Name share the same namespace, and must be unique.&lt;br /&gt;
//  2. It is allowed to have a name in the addressbook with multiple addresses, seperated by comma&#039;s.&lt;br /&gt;
// &lt;br /&gt;
/////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string  CurrentMailAddress = &amp;quot;&amp;quot;;&lt;br /&gt;
string  CurrentMailSubject = &amp;quot;&amp;quot;;&lt;br /&gt;
integer StatusOnline = FALSE;&lt;br /&gt;
&lt;br /&gt;
// Fetch or Send notecard&lt;br /&gt;
&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Names&lt;br /&gt;
&lt;br /&gt;
list    AddressBookList=[];&lt;br /&gt;
list    MailAddressList=[];&lt;br /&gt;
&lt;br /&gt;
string  STRING_HOME=&amp;quot;HOME&amp;quot;;&lt;br /&gt;
string  STRING_SELF=&amp;quot;SELF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Groups&lt;br /&gt;
&lt;br /&gt;
list   GroupList=[];&lt;br /&gt;
list   GroupNameList=[];&lt;br /&gt;
&lt;br /&gt;
string LSL_DOMAIN = &amp;quot;lsl.secondlife.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Read Address Book notecard&lt;br /&gt;
&lt;br /&gt;
string  ADDRESSBOOK_NOTECARD=&amp;quot;Address Book&amp;quot;;&lt;br /&gt;
integer Line=0;&lt;br /&gt;
key     reqAddressBook=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
integer Section=0;&lt;br /&gt;
integer SECTION_ADDRESS_BOOK=1;&lt;br /&gt;
integer SECTION_GROUP=2;&lt;br /&gt;
string  STRING_ADDRESS_BOOK=&amp;quot;ADDRESS BOOK&amp;quot;;&lt;br /&gt;
string  STRING_GROUP=&amp;quot;GROUP&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Links messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
integer MSG_MESSAGE_NOTIFY              = 90900;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED            = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR            = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// GetSelfAddress() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
string GetSelfAddress()&lt;br /&gt;
{&lt;br /&gt;
    return (string)llGetKey() + &amp;quot;@&amp;quot; + LSL_DOMAIN;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Info() /////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Info()&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;The mail address for this object is: &amp;quot; &lt;br /&gt;
                    + GetSelfAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// IsValidKeyFormat() //////////////////////&lt;br /&gt;
&lt;br /&gt;
integer IsValidKeyFormat(string str)&lt;br /&gt;
{&lt;br /&gt;
    string keychars = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    if (llStringLength(str) != 36)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    if( (llGetSubString( str, 8, 8 )   != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 13, 13 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 18, 18 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 23, 23 )  != &amp;quot;-&amp;quot; ) )&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 9; i &amp;lt; 13; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 14; i &amp;lt; 18; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 19; i &amp;lt; 23; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 24; i &amp;lt; 36; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// ValidMailAddress() ////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer ValidMailAddress(string arg)&lt;br /&gt;
{&lt;br /&gt;
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));&lt;br /&gt;
    &lt;br /&gt;
    if (adress == &amp;quot;&amp;quot;)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    list parse = llParseStringKeepNulls(adress, [ &amp;quot;@&amp;quot; ], []);&lt;br /&gt;
    string account = llList2String(parse,0);&lt;br /&gt;
    string domain  = llList2String(parse,1);&lt;br /&gt;
    &lt;br /&gt;
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    &lt;br /&gt;
    if (domain == LSL_DOMAIN)&lt;br /&gt;
    {&lt;br /&gt;
        return IsValidKeyFormat(account);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list parsedomain = llParseString2List(domain, [ &amp;quot;.&amp;quot; ], []);&lt;br /&gt;
    &lt;br /&gt;
        if (llGetListLength(parsedomain) &amp;lt; 2)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        &lt;br /&gt;
        integer num = llGetListLength(parsedomain);&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llStringLength(llList2String(parsedomain,i)) &amp;lt; 2)&lt;br /&gt;
            {&lt;br /&gt;
                return FALSE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetAddressStr() ///////////////////&lt;br /&gt;
&lt;br /&gt;
string GetAndCheckAddressStr(string address)&lt;br /&gt;
{&lt;br /&gt;
    list addresslist = llCSV2List(address);&lt;br /&gt;
    integer num=llGetListLength(addresslist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    string addressstr=&amp;quot;&amp;quot;;&lt;br /&gt;
    string curaddress=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        curaddress=llList2String(addresslist,i);&lt;br /&gt;
        &lt;br /&gt;
        if (ValidMailAddress(curaddress))&lt;br /&gt;
        {&lt;br /&gt;
            addressstr = (addressstr=&amp;quot;&amp;quot;) + addressstr + curaddress + &amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address string: &#039;&amp;quot; &lt;br /&gt;
                            + curaddress + &amp;quot;&#039;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return llGetSubString(addressstr, 0, -2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ProcessLine() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
ProcessLine(string rawline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(rawline,STRING_TRIM);&lt;br /&gt;
    string first=llGetSubString(line,0,0);&lt;br /&gt;
    string last=llGetSubString(line,-1,-1);&lt;br /&gt;
    &lt;br /&gt;
    // Ignore a blank line or comment line&lt;br /&gt;
    if (line == &amp;quot;&amp;quot; || first == &amp;quot;#&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // Check for the right section&lt;br /&gt;
    &lt;br /&gt;
    if (first == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; last == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        string sectionstr=llToUpper(llStringTrim(llGetSubString(line,1,-2),STRING_TRIM));&lt;br /&gt;
        &lt;br /&gt;
        if (sectionstr == STRING_ADDRESS_BOOK)&lt;br /&gt;
        {&lt;br /&gt;
            Section = SECTION_ADDRESS_BOOK;&lt;br /&gt;
        }&lt;br /&gt;
        else if (sectionstr == STRING_GROUP)&lt;br /&gt;
        {&lt;br /&gt;
            if (Section == 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                        + &amp;quot;. Group section defined before Address Book section.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Section = SECTION_GROUP;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid section header &#039;&amp;quot; + sectionstr &lt;br /&gt;
                        + &amp;quot;&#039; in &amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Must be in a section&lt;br /&gt;
    &lt;br /&gt;
    if (Section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;. No section header.&amp;quot;, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    list     parse=llParseString2List(line, [ &amp;quot;=&amp;quot; ], []);&lt;br /&gt;
    integer  num=llGetListLength(parse);&lt;br /&gt;
    &lt;br /&gt;
    // Format must be correct&lt;br /&gt;
    &lt;br /&gt;
    if (num != 2)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; +  (string)(Line+1) + &amp;quot;:\n&amp;quot; + rawline, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (Section == SECTION_ADDRESS_BOOK)&lt;br /&gt;
    {&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(name) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + name &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ name ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            string address=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
            string addressstr=GetAndCheckAddressStr(address);&lt;br /&gt;
            &lt;br /&gt;
            if (addressstr != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                AddressBookList     = (AddressBookList=[])     + AddressBookList     + [ name ];&lt;br /&gt;
                MailAddressList     = (MailAddressList=[])     + MailAddressList     + [ addressstr ];&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;No valid mail address for &#039;&amp;quot; + name &lt;br /&gt;
                    + &amp;quot;&#039;. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                    + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name &lt;br /&gt;
                + &amp;quot;&#039; already defined. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // Group&lt;br /&gt;
    {&lt;br /&gt;
        string group=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(group) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + group &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ group ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(GroupList, [ group ]) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                string names=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
                list   namelist=llCSV2List(names);&lt;br /&gt;
                integer num=llGetListLength(namelist);&lt;br /&gt;
                integer i;&lt;br /&gt;
                integer index;&lt;br /&gt;
                string  name;&lt;br /&gt;
                string  namestr=&amp;quot;&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
                for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                    name=llList2String(namelist,i);&lt;br /&gt;
                    index=llListFindList(AddressBookList, [ name ]);&lt;br /&gt;
            &lt;br /&gt;
                    if (index == -1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name + &amp;quot;&#039; defined in Group &#039;&amp;quot; &lt;br /&gt;
                                + group + &amp;quot;&#039; not found in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY); &lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        namestr = (namestr=&amp;quot;&amp;quot;) + namestr + name + &amp;quot;,&amp;quot;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (namestr != &amp;quot;&amp;quot;)&lt;br /&gt;
                {    &lt;br /&gt;
                    namestr=llGetSubString(namestr,0,-2);&lt;br /&gt;
                    GroupList         = (GroupList=[])         + GroupList     + [ group ];&lt;br /&gt;
                    GroupNameList     = (GroupNameList=[])    + GroupNameList + [ namestr ];&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                        + &amp;quot;&#039; has no valid names. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                        + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                    + &amp;quot;&#039; already defined in Group. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                    + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group&lt;br /&gt;
                + &amp;quot;&#039; already defined in Address Book. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// GetGroupAddressList ///////////////&lt;br /&gt;
&lt;br /&gt;
string GetGroupAddressList(string group)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(GroupList, [ group ]);&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(GroupList);&lt;br /&gt;
    string  grouplist=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        for (i = index; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2String(GroupList,i) == group)&lt;br /&gt;
            {&lt;br /&gt;
                grouplist = (grouplist=&amp;quot;&amp;quot;) + grouplist + llList2String(GroupNameList,i) + &amp;quot;,&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (grouplist != &amp;quot;&amp;quot;) grouplist=llGetSubString(grouplist,0,-2);   // remove last &amp;quot;,&amp;quot;&lt;br /&gt;
        return grouplist;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// SetMailAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetMailAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ address ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        index=llListFindList(GroupList, [ address ]);&lt;br /&gt;
        &lt;br /&gt;
        if (index == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llToUpper(address) == STRING_SELF)&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = GetSelfAddress();&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if(ValidMailAddress(address))&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = address;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Mail adress &amp;quot; + address &lt;br /&gt;
                            + &amp;quot; : not found in adress book or invalid format.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailAddress = GetGroupAddressList(address);&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        CurrentMailAddress = llList2String(MailAddressList,index);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                        + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string message)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No mail address defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No subject defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list mailaddresslist=llCSV2List(CurrentMailAddress);&lt;br /&gt;
        integer num=llGetListLength(mailaddresslist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(mailaddresslist,i);&lt;br /&gt;
            llEmail(address, CurrentMailSubject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMailHome() ////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMailHome(string message, string subject)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, STRING_HOME &lt;br /&gt;
                + &amp;quot; not set. Set your home adress with @HOME &amp;lt;address&amp;gt;.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        string homeaddress=llList2String(AddressBookList,index);&lt;br /&gt;
        list   homelist=llCSV2List(homeaddress);&lt;br /&gt;
        integer num=llGetListLength(homelist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(homelist,i);&lt;br /&gt;
            llEmail(address, subject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
string GetHomeAddress()&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;not set&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2String(MailAddressList,index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetHomeAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        AddressBookList     = (AddressBookList=[]) + [ STRING_HOME ] + AddressBookList;&lt;br /&gt;
        MailAddressList     = (MailAddressList=[]) + [ GetAndCheckAddressStr(address) ]  + MailAddressList;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MailAddressList = llListReplaceList(MailAddressList, [ GetAndCheckAddressStr(address) ], index, index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        Line=0;&lt;br /&gt;
        Section=0;&lt;br /&gt;
        llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// dataserver() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqAddressBook)&lt;br /&gt;
        {&lt;br /&gt;
            reqAddressBook = NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                ProcessLine(data);&lt;br /&gt;
                reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Address Book loaded.&amp;quot;, NULL_KEY);&lt;br /&gt;
                state running;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// timer() ///////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_ERROR, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Could not read Address Book: &amp;quot; &lt;br /&gt;
                            + ADDRESSBOOK_NOTECARD + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// link_message() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_MESSAGE_GETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is empty.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailSubject = message;&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is empty.&amp;quot;, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            SetMailAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Body of message to send is empty. &amp;quot; &lt;br /&gt;
                                +  &amp;quot;No mail is send.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SENDHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SendMailHome(message, (string)id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetInventoryType(message) == INVENTORY_NOTECARD)&lt;br /&gt;
            {&lt;br /&gt;
                Notecard2Fetch = message;                &lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_READ, message, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + message + &amp;quot; not found.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_NOTECARD_FETCHED)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + Notecard2Fetch &lt;br /&gt;
                            + &amp;quot; was empty or could not be read.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Home address is: &amp;quot; + GetHomeAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SetHomeAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_INFO)&lt;br /&gt;
        {&lt;br /&gt;
            Info();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
// End SL Mail AddressBook V1.2.lsl&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail FetchNotecard V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch the contents of a notecard and return it via link message as a string.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Notecard&lt;br /&gt;
&lt;br /&gt;
integer Line=0;&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
key     reqNotecard=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=10.0;&lt;br /&gt;
integer Fetched=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Lines&lt;br /&gt;
&lt;br /&gt;
list LineList=[];&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    /////////////////////// dataserver() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqNotecard)&lt;br /&gt;
        {&lt;br /&gt;
            reqNotecard=NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                LineList = (LineList=[]) + LineList + [ data ];&lt;br /&gt;
                reqNotecard = llGetNotecardLine(Notecard2Fetch, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Fetched=TRUE;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, llDumpList2String(LineList, &amp;quot;\n&amp;quot;), NULL_KEY);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /////////////////////// timer() ///////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        if (!Fetched)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            llSetTimerEvent(0.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer send, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_NOTECARD_READ)&lt;br /&gt;
        {&lt;br /&gt;
            Line=0;&lt;br /&gt;
            Notecard2Fetch=message;&lt;br /&gt;
            LineList=[];&lt;br /&gt;
            Fetched=FALSE;&lt;br /&gt;
            reqNotecard=llGetNotecardLine(Notecard2Fetch, Line);&lt;br /&gt;
            llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL OnlineStatus V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch online status of owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Online status&lt;br /&gt;
&lt;br /&gt;
key     reqOnlineStatus=NULL_KEY;&lt;br /&gt;
float   STATUS_INTERVAL=2.0;&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_STATUS_ONLINE       = 30000;&lt;br /&gt;
integer MS_STATUS_OFFLINE       = 30100;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus=llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
        llSetTimerEvent(STATUS_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// dataserver() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqOnlineStatus)&lt;br /&gt;
        {&lt;br /&gt;
            reqOnlineStatus = NULL_KEY;&lt;br /&gt;
        &lt;br /&gt;
            if (data==&amp;quot;1&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_STATUS_ONLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if (data==&amp;quot;0&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MS_STATUS_OFFLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus = llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Help V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Display help information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail Help V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP    = 10000;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Help() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Help()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;HELP for SL Mail V1.2.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;COMMANDS:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HELP               - displays help info.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@INFO               - display mailaddress of this object.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RECORD             - start recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CONTINUE           - continue recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@STOP               - stop recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@IGNORE             - ignore the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SHOW               - show what your recorded.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SEND               - send the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@MAIL &amp;lt;mailadress&amp;gt;  - set the mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SUBJECT subject    - set the mail subject.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LIST               - list messages in mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SELECT &amp;lt;message&amp;gt;   - select message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@READ               - read current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@NEXT               - read next message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@PREV               - read previous message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@FIRST              - read first message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LAST               - read last message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@DELETE             - delete current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CLEAR              - clear the mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@REPLY              - reply to current message.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RESET              - reset the script.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HOME               - set the home mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@OFF                - switch mailbox OFF.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@ON                 - switch mailbox ON.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_HELP)&lt;br /&gt;
        {&lt;br /&gt;
            Help();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail Help V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}&lt;/div&gt;</description>
			<pubDate>Sun, 07 Oct 2007 11:14:37 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:SL_Mail_V1.2</comments>
		</item>
		<item>
			<title>SL Mail V1.2</title>
			<link>https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34590</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34590</guid>
			<description>&lt;p&gt;Flennan Roffo: /* &amp;#039;&amp;#039;&amp;#039;PRODUCTION &amp;amp; MAINTANENCE&amp;#039;&amp;#039;&amp;#039; */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}} __NOTOC__&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=&#039;&#039;&#039;Second Life mail client&#039;&#039;&#039;=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Send and receive email from within Second Life from and to any address.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implemented with Address Book function (in a notecard named &#039;Address Book&#039;) to stores addresses by name  and to compile groups of named addresses. Current version is stand-alone (no server functionality) and uses chat commands only.&lt;br /&gt;
&lt;br /&gt;
[[Image:BannerSLMail.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=Release Notes V1.2=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 Release notes (edition 2, 4 sept 2007)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LICENCE INFO&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is released under GNU free software licence&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;PRODUCTION &amp;amp; MAINTANENCE&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
by Logic Scripted Products and Script Services&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
SLurl:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Contact: [[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
&lt;br /&gt;
Email: [mailto:info@slmail.info &#039;&#039;&#039;info&#039;&#039;&#039;] or [mailto:Flennan.Roffo@slmail.info &#039;&#039;&#039;Flennan Roffo&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;DESCRIPTION&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is a simple tool to send and receive mail from within SL.&lt;br /&gt;
You can either compose a message yourself using chat recording, or choose a notecard from inventory to send. The Address Book functionality allows you to use short names for mail recipients stored in a notecard. The current version does not have a persisent mail address. Watch out for the upcoming next release (V1.3) which will facilitate persisent in-world mail addresses and will be enhanced with many new features (See: Requests For Change (RFC).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;COMMANDS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Help&#039;&#039;&#039;&lt;br /&gt;
||Show Help about available commands&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Record&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording (for owner only).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Stop&#039;&#039;&#039;&lt;br /&gt;
||Stops the chat recording without sending&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Continue&#039;&#039;&#039;&lt;br /&gt;
||Continues a previously stopped chat recording. Lines will be appended to you recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Show&#039;&#039;&#039;&lt;br /&gt;
||Shows the content of the recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send&#039;&#039;&#039;&lt;br /&gt;
||If recording, stops the recording, and sends the mail (need to supply mail address and subject first!)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send &amp;lt;notecard&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Sends the content of the notecard, instead of the chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Ignore&#039;&#039;&#039;&lt;br /&gt;
||Ignores your current chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject &amp;lt;subject&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the subject of the mail.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail subject.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Set the HOME address of the owner (mail will be forwarder to this address when offline).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home&#039;&#039;&#039;&lt;br /&gt;
||Show the HOME address.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Info&#039;&#039;&#039;&lt;br /&gt;
||Shows the mail address the object this script is running in uses (e.g. &amp;lt;object-key&amp;gt;@lsl.secondlife.com).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Read&#039;&#039;&#039;&lt;br /&gt;
||Reads the current message from the mail buffer (the mail buffer gets filled with mail you receive)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Select &amp;lt;msg&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Select a message number from the availabe messages in the mail buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Next&#039;&#039;&#039;&lt;br /&gt;
||Make next message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Prev&#039;&#039;&#039;&lt;br /&gt;
||Make previous message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@First&#039;&#039;&#039;&lt;br /&gt;
||Make the first message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Last&#039;&#039;&#039;&lt;br /&gt;
||Make the last message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Clear&#039;&#039;&#039;&lt;br /&gt;
||Clear the mail buffer&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Delete&#039;&#039;&#039;&lt;br /&gt;
||Deletes only the current message&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Reply&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording to reply to the current message. Mail adress and subject are filled in automatically.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* Commands are case insensitive (&amp;quot;@read&amp;quot; == &amp;quot;@READ&amp;quot;). Arguments might not be case insensitive.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;ADDRESS BOOK FORMAT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
A notecard of the name &#039;Address Book&#039; is read during initialization which may contain Address Book items and Groups.&lt;br /&gt;
The notecard is split in two sections, which need to be defined in that particular order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[ADDRESS BOOK]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Defines the section in which you can put names for mail addresses,  like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name1=account@thisdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name2=user@otherdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[GROUP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define groups of previously defined names under a new name, like for instance:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyGroup=Name1, Name2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note that names of groups and individual mail adresses share the same namespace and must be unique.&lt;br /&gt;
&lt;br /&gt;
So when you filled in your mail adresses in the Address Book, you can now use:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail Name1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to  &amp;lt;account@thisdomain.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail MyGroup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to &amp;lt;account@thisdomain.com&amp;gt; and &amp;lt;user@otherdomain.com&amp;gt;&lt;br /&gt;
Mails will be sent one after another.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* Names for Addreses and Groups are case insensitive (e.g. &amp;quot;mary&amp;quot;  == &amp;quot;MARY&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* The special address &#039;Self&#039; can be used in commands where otherwise an address specification can be used. &#039;Self&#039; is case insensitive (e.g. &amp;quot;self&amp;quot; == &amp;quot;SELF&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LIMITATIONS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
The current version is limited by the following:&lt;br /&gt;
&lt;br /&gt;
* Chat recording lines are limited by the 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Output of lines from the mail buffer are also limited by this 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Incoming mail is limited to a 1000 (1024?) byte limit&lt;br /&gt;
&lt;br /&gt;
* Outgoing mai is limited by a 4096 byte limit, which includes the standard mail header (region/location info on the first two lines)&lt;br /&gt;
&lt;br /&gt;
We are making adjustments to this release to help overcome these limitations. At least the line lenght limit can be overcome by introducing a line continuation character (for example a hyphen &#039;-&#039;) that when used at the end of a line appends the next line, so lines longer then 255 bytes are possible then.&lt;br /&gt;
&lt;br /&gt;
To overcome the outgoing mail length limit, the mail can be broken textualy into parts, and each part can be send seperatedely, with an indication in the subject or in an introduced primary line of the mail body to indicate that the mail was split into parts.&lt;br /&gt;
For incoming mail and at least to receive mail from other SL Mail programs, a protocol will be introduced to receive mail in parts that are joined together after receiving them to form a single mail.&lt;br /&gt;
&lt;br /&gt;
These enhancements will be made available in the next release (V1.3) of SL Mail &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;BUGS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Report any bugs you find in this release to Logic (IM: Flennan Roffo).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;REQUEST FOR CHANGE (RFC)&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Do you have additional wishes for enhancement of this product?&lt;br /&gt;
Contact Flennan Roffo and we will see if they can be implemented in the next release.&lt;br /&gt;
&lt;br /&gt;
Existing RFC&#039;s are:&lt;br /&gt;
&lt;br /&gt;
* Menu support for commands.&lt;br /&gt;
&lt;br /&gt;
* Lines on incoming/outgoing mail longer than 255 bytes.&lt;br /&gt;
&lt;br /&gt;
* Send messages longer than 4096 (minus SL mail header) bytes.&lt;br /&gt;
&lt;br /&gt;
* Receive messages longer than 1024 bytes.&lt;br /&gt;
&lt;br /&gt;
* Permanent mail addresses for the SL Mail client (like: &amp;lt;Flennan.Roffo@somedomain.sl&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Add your RFC!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In-world join the group &amp;quot;SL Mail&amp;quot; for bug reports, feature requests, the latest SL Mail release, and notices about development issues.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scripts=&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==Script: SL Mail v1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail core module which scans for incoming mail messages and executes commands used by the owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail V1.2.lsl&lt;br /&gt;
// (c) 2007 Logic Scripted Products and Script Services&lt;br /&gt;
// Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
// VERSION&lt;br /&gt;
// Version: 1.2&lt;br /&gt;
&lt;br /&gt;
// HISTORY&lt;br /&gt;
// Date         Version     Author              Comment&lt;br /&gt;
// --------------------------------------------------------------------------------------&lt;br /&gt;
// 28 aug 2007  V 1.0       Flennan Roffo       Created&lt;br /&gt;
//&lt;br /&gt;
//  1 sep 2007  V 1.1       Flennan Roffo       @Reply empties the recording buffer.&lt;br /&gt;
//                                                @Send while recording ends recording&lt;br /&gt;
//                                                and sends the mail if a mail address&lt;br /&gt;
//                                                and subject are supplied.&lt;br /&gt;
//                                                Fixed incorrect date in Unix2DateTime.&lt;br /&gt;
//  3 sep 2007  V 1.2       Flennan Roffo       Notification options:&lt;br /&gt;
//                                              - When online, send an IM when mail is received.&lt;br /&gt;
//                                              - When offline, send to HOME mail adress.&lt;br /&gt;
//                                              Adressbook&lt;br /&gt;
//                                              - Read adress book from config notecard.&lt;br /&gt;
&lt;br /&gt;
// LICENCE&lt;br /&gt;
// This program is free software; you can redistribute it and/or&lt;br /&gt;
// modify it under the terms of the GNU General Public License&lt;br /&gt;
// as published by the Free Software Foundation; either version 2&lt;br /&gt;
// of the License, or (at your option) any later version.&lt;br /&gt;
// &lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
// &lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program; if not, write to the Free Software&lt;br /&gt;
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
// (Also available at http://www.gnu.org/copyleft/gpl.html) &lt;br /&gt;
&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// Let&#039;s you record a message and sent to email and get messages and reply to messages.&lt;br /&gt;
// Must supply a valid mail adress and non-empty subject using chat commands.&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
// 1) Check for the maximum length of an email message (including newline and header).&lt;br /&gt;
// 2) Read adress book from notecard.                                    *DONE*&lt;br /&gt;
// 3) Send incoming mail to personal mail adress when offline.            *DONE*&lt;br /&gt;
// 4) Alert with an IM when online upon receiving new mail.                *DONE*&lt;br /&gt;
&lt;br /&gt;
string   SL_MAIL_VERSION = &amp;quot;V 1.2&amp;quot;;&lt;br /&gt;
string   SL_MAIL_DATE    = &amp;quot; 2 sep 2007&amp;quot;;&lt;br /&gt;
integer  ErrorFlag         = FALSE;&lt;br /&gt;
list     ScriptList        = [ &amp;quot;SL Mail Help V1.2&amp;quot;, &amp;quot;SL Mail AddressBook V1.2&amp;quot;, &lt;br /&gt;
                                &amp;quot;SL Mail OnlineStatus V1.2&amp;quot;, &amp;quot;SL Mail FetchNotecard V1.2&amp;quot; ];    &lt;br /&gt;
string   LSL_DOMAIN=&amp;quot;lsl.secondlife.com&amp;quot;; &lt;br /&gt;
integer  StatusOnline=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Commands&lt;br /&gt;
&lt;br /&gt;
string  COMMAND_RECORD     = &amp;quot;@RECORD&amp;quot;;&lt;br /&gt;
string  COMMAND_CONTINUE   = &amp;quot;@CONTINUE&amp;quot;;&lt;br /&gt;
string  COMMAND_STOP       = &amp;quot;@STOP&amp;quot;;&lt;br /&gt;
string  COMMAND_MAIL       = &amp;quot;@MAIL&amp;quot;;&lt;br /&gt;
string  COMMAND_SUBJECT    = &amp;quot;@SUBJECT&amp;quot;;&lt;br /&gt;
string  COMMAND_SEND       = &amp;quot;@SEND&amp;quot;;&lt;br /&gt;
string  COMMAND_SEE        = &amp;quot;@SEE&amp;quot;;&lt;br /&gt;
string  COMMAND_IGNORE     = &amp;quot;@IGNORE&amp;quot;;&lt;br /&gt;
string  COMMAND_READ       = &amp;quot;@READ&amp;quot;;&lt;br /&gt;
string  COMMAND_DELETE     = &amp;quot;@DELETE&amp;quot;;&lt;br /&gt;
string  COMMAND_CLEAR      = &amp;quot;@CLEAR&amp;quot;;&lt;br /&gt;
string  COMMAND_REPLY      = &amp;quot;@REPLY&amp;quot;;&lt;br /&gt;
string  COMMAND_NEXT       = &amp;quot;@NEXT&amp;quot;;&lt;br /&gt;
string  COMMAND_PREV       = &amp;quot;@PREV&amp;quot;;&lt;br /&gt;
string  COMMAND_FIRST      = &amp;quot;@FIRST&amp;quot;;&lt;br /&gt;
string  COMMAND_LAST       = &amp;quot;@LAST&amp;quot;;&lt;br /&gt;
string  COMMAND_LIST       = &amp;quot;@LIST&amp;quot;;&lt;br /&gt;
string  COMMAND_SELECT     = &amp;quot;@SELECT&amp;quot;;&lt;br /&gt;
string  COMMAND_HELP       = &amp;quot;@HELP&amp;quot;;&lt;br /&gt;
string  COMMAND_INFO       = &amp;quot;@INFO&amp;quot;;&lt;br /&gt;
string  COMMAND_RESET      = &amp;quot;@RESET&amp;quot;;&lt;br /&gt;
string  COMMAND_SHOW       = &amp;quot;@SHOW&amp;quot;;&lt;br /&gt;
string  COMMAND_ON         = &amp;quot;@ON&amp;quot;;&lt;br /&gt;
string  COMMAND_OFF        = &amp;quot;@OFF&amp;quot;;&lt;br /&gt;
string  COMMAND_HOME       = &amp;quot;@HOME&amp;quot;;&lt;br /&gt;
string  COMMAND_LOAD       = &amp;quot;@LOAD&amp;quot;;&lt;br /&gt;
string  COMMAND_ADDRESS    = &amp;quot;@ADDRESS&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Recording&lt;br /&gt;
&lt;br /&gt;
integer Recording = FALSE;&lt;br /&gt;
&lt;br /&gt;
list    ChatRecording=[];&lt;br /&gt;
integer NumLines=0;&lt;br /&gt;
integer Length=0;&lt;br /&gt;
&lt;br /&gt;
list     TimeList=[];&lt;br /&gt;
list     AddressList=[];&lt;br /&gt;
list     SubjectList=[];&lt;br /&gt;
list     BodyList=[];&lt;br /&gt;
integer  NumMessages=0;&lt;br /&gt;
integer  CurrentMessage=-1;&lt;br /&gt;
&lt;br /&gt;
float    MAIL_FETCH_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
// Link Messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP                        = 10000;&lt;br /&gt;
integer MSG_STATUS_ONLINE               = 30000;&lt;br /&gt;
integer MSG_STATUS_OFFLINE              = 30100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED          = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR           = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Unix Time conversion //////////////////&lt;br /&gt;
&lt;br /&gt;
integer DAYS_PER_YEAR        = 365;                // Non leap year&lt;br /&gt;
integer SECONDS_PER_YEAR     = 31536000;          // Non leap year&lt;br /&gt;
integer SECONDS_PER_DAY      = 86400;&lt;br /&gt;
integer SECONDS_PER_HOUR     = 3600;&lt;br /&gt;
integer SECONDS_PER_MINUTE   = 60;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// LeapYear() /////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer LeapYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (year % 4 == 0)&lt;br /&gt;
    {&lt;br /&gt;
        if (year % 100 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (year % 400 == 0)&lt;br /&gt;
            {&lt;br /&gt;
                return 1;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// DaysPerMonth() ///////////////////////////////////////&lt;br /&gt;
                &lt;br /&gt;
integer DaysPerMonth(integer year,integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;lt; 8)&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (month == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if (LeapYear(year))&lt;br /&gt;
                {&lt;br /&gt;
                    return 29;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    return 28;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 30;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 30;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////// DaysPerYear() ////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DaysPerYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (LeapYear(year))&lt;br /&gt;
        return DAYS_PER_YEAR + 1;&lt;br /&gt;
    else&lt;br /&gt;
        return DAYS_PER_YEAR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Unix2DataTime() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list Unix2DateTime(integer unixtime)&lt;br /&gt;
{&lt;br /&gt;
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;&lt;br /&gt;
    integer day = days_since_1_1_1970 + 1;&lt;br /&gt;
    integer year  = 1970;&lt;br /&gt;
    integer days_per_year = DaysPerYear(year);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_year)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_year;&lt;br /&gt;
        ++year;&lt;br /&gt;
        days_per_year = DaysPerYear(year);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer month = 1;&lt;br /&gt;
    integer days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_month)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_month;&lt;br /&gt;
        &lt;br /&gt;
        if (++month &amp;gt; 12)&lt;br /&gt;
        {    &lt;br /&gt;
            ++year;&lt;br /&gt;
            month = 1;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;&lt;br /&gt;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;&lt;br /&gt;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;&lt;br /&gt;
    integer minute      = second / SECONDS_PER_MINUTE;&lt;br /&gt;
    second               = second % SECONDS_PER_MINUTE;&lt;br /&gt;
    &lt;br /&gt;
    return [ year, month, day, hour, minute, second ];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// MonthName() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list MonthNameList = [     &amp;quot;JAN&amp;quot;, &amp;quot;FEB&amp;quot;, &amp;quot;MAR&amp;quot;, &amp;quot;APR&amp;quot;, &amp;quot;MAY&amp;quot;, &amp;quot;JUN&amp;quot;, &lt;br /&gt;
                        &amp;quot;JUL&amp;quot;, &amp;quot;AUG&amp;quot;, &amp;quot;SEP&amp;quot;, &amp;quot;OCT&amp;quot; , &amp;quot;NOV&amp;quot;, &amp;quot;DEC&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
string MonthName(integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;gt;= 0 &amp;amp;&amp;amp; month &amp;lt; 12)&lt;br /&gt;
        return llList2String(MonthNameList, month);&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// DateString() ///////////////////////////&lt;br /&gt;
&lt;br /&gt;
string DateString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer year       = llList2Integer(timelist,0);&lt;br /&gt;
    integer month      = llList2Integer(timelist,1);&lt;br /&gt;
    integer day        = llList2Integer(timelist,2);&lt;br /&gt;
    &lt;br /&gt;
    return (string)day + &amp;quot;-&amp;quot; + MonthName(month - 1) + &amp;quot;-&amp;quot; + (string)year;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// TimeString() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string TimeString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer hour          = llList2Integer(timelist,3);&lt;br /&gt;
    integer minute         = llList2Integer(timelist,4);&lt;br /&gt;
    integer second         = llList2Integer(timelist,5);&lt;br /&gt;
    string  hourstr     = (string)hour;&lt;br /&gt;
    string  minutestr   = (string)minute;&lt;br /&gt;
    string  secondstr   = (string)second;&lt;br /&gt;
    &lt;br /&gt;
    if (hour &amp;lt; 10)         hourstr     = &amp;quot;0&amp;quot; + hourstr;&lt;br /&gt;
    if (minute &amp;lt; 10)     minutestr     = &amp;quot;0&amp;quot; + minutestr;&lt;br /&gt;
    if (second &amp;lt; 10)    secondstr    = &amp;quot;0&amp;quot; + secondstr;&lt;br /&gt;
    return hourstr + &amp;quot;:&amp;quot; + minutestr + &amp;quot;:&amp;quot; + secondstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() /////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string body)&lt;br /&gt;
{&lt;br /&gt;
    // llOwnerSay(&amp;quot;Sending message to &#039;&amp;quot; + address + &amp;quot;&#039; with subject &#039;&amp;quot; + subject +&amp;quot;&#039;.&amp;quot;);&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND, body, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// SendHome() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendHome(string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SENDHOME, body, (key)subject);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Show() ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Show()&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;Current chat recording is:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; NumLines; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(ChatRecording,i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;Lines is &amp;quot; + (string)NumLines);&lt;br /&gt;
    llOwnerSay(&amp;quot;Message length is &amp;quot; + (string)Length);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Read() /////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Read()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;Reading message &amp;quot; + (string)CurrentMessage + &amp;quot; from mail buffer.&amp;quot;);&lt;br /&gt;
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);&lt;br /&gt;
    list timelist=Unix2DateTime(time);&lt;br /&gt;
    string Address = llList2String(AddressList,CurrentMessage);&lt;br /&gt;
    string Subject = llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
    string Body    = llList2String(BodyList,CurrentMessage);&lt;br /&gt;
    llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Address: &amp;quot; + Address);&lt;br /&gt;
    llOwnerSay(&amp;quot;Subject: &amp;quot; + Subject);&lt;br /&gt;
    llOwnerSay(&amp;quot;Begin of message body:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    list bodylist=llParseStringKeepNulls(Body, [ &amp;quot;\n&amp;quot; ], []);&lt;br /&gt;
    integer num=llGetListLength(bodylist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(bodylist,i));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;End of message body.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////// List ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
List()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;The mail buffer contains the following messages:\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; NumMessages; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer time=llList2Integer(TimeList,i);&lt;br /&gt;
        list timelist=Unix2DateTime(time);&lt;br /&gt;
        if (i &amp;gt; 0) llOwnerSay(&amp;quot;+-+-+-+-+-+-+-+-+-+-+-+-&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Message: &amp;quot; + (string)i);&lt;br /&gt;
        llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;From:    &amp;quot; + llList2String(AddressList,i));&lt;br /&gt;
        llOwnerSay(&amp;quot;Subject: &amp;quot; + llList2String(SubjectList,i));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////// NotifyNewMail() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
NotifyNewMail(string time, string address, string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    list timelist=Unix2DateTime((integer)time);&lt;br /&gt;
&lt;br /&gt;
    if (StatusOnline)&lt;br /&gt;
    {&lt;br /&gt;
        llInstantMessage(llGetOwner(), &amp;quot;You received a new mail message on &amp;quot; &lt;br /&gt;
                                    + DateString(timelist) + &amp;quot; at &amp;quot; + TimeString(timelist)&lt;br /&gt;
                                    + &amp;quot; from &amp;quot; + address &lt;br /&gt;
                                    + &amp;quot; with the subject &amp;quot; + subject);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        SendHome(&amp;quot;FW: &amp;quot; + subject, &amp;quot;Received at: &amp;quot; + DateString(timelist) + &amp;quot; &amp;quot; + TimeString(timelist) + &amp;quot;\nFrom: &amp;quot; +  address &lt;br /&gt;
                    + &amp;quot;\nBegin message body:\n-------------------\n&amp;quot; + body + &amp;quot;\n-------------------\nEnd message body.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ResetOtherScripts() //////////////////////&lt;br /&gt;
&lt;br /&gt;
ResetOtherScripts()&lt;br /&gt;
{&lt;br /&gt;
    string     name;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(ScriptList);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        name = llList2String(ScriptList,i);&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(name) == INVENTORY_SCRIPT)&lt;br /&gt;
        {&lt;br /&gt;
            llResetOtherScript(name);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Error - script &#039;&amp;quot; + name + &amp;quot;&#039; not found.&amp;quot;);&lt;br /&gt;
            ErrorFlag = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
// default &lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ////////////////////// state_entry() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Welcome to SL Mail, released under GNU software licence.&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Version &amp;quot; + SL_MAIL_VERSION + &amp;quot; &amp;quot; + SL_MAIL_DATE);&lt;br /&gt;
        llOwnerSay(&amp;quot;Produced by Logic Scripted Products &amp;amp; Product Services&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Free memory: &amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
        ResetOtherScripts();&lt;br /&gt;
        &lt;br /&gt;
        if (ErrorFlag)&lt;br /&gt;
            state Error;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// on_rez() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// changed() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_LOADED)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_ERROR)&lt;br /&gt;
        {&lt;br /&gt;
            state Error;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() //////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(MAIL_FETCH_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //////////////////////// on_rez() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// listen() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string trimmessage=llStringTrim(message,STRING_TRIM);&lt;br /&gt;
        list   parse = llParseStringKeepNulls(trimmessage, [ &amp;quot; &amp;quot;], []);&lt;br /&gt;
        string command = llToUpper(llList2String(parse,0));&lt;br /&gt;
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        integer nargs  = llGetListLength(parse);&lt;br /&gt;
        string argstr=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (nargs &amp;gt; 1) argstr=llGetSubString(message, llSubStringIndex(message, &amp;quot; &amp;quot;) + 1, -1);&lt;br /&gt;
            &lt;br /&gt;
        if (Recording)&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Recording stopped. Type @SHOW to see the message you have entered,&amp;quot;&lt;br /&gt;
                            + &amp;quot; or @SEND to send it.&amp;quot;);&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                &lt;br /&gt;
                SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];&lt;br /&gt;
                ++NumLines;&lt;br /&gt;
                Length += llStringLength(message) + 2;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_RECORD)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Start recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                ChatRecording = [];&lt;br /&gt;
                NumLines=0;&lt;br /&gt;
                Length=0;&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CONTINUE)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Continue recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_REPLY)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    string address=llList2String(AddressList,CurrentMessage);&lt;br /&gt;
                    string subject=&amp;quot;Re: &amp;quot; + llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, address, NULL_KEY);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, subject, NULL_KEY);&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines=0;&lt;br /&gt;
                    Length=0;&lt;br /&gt;
                    Recording = TRUE;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_MAIL)&lt;br /&gt;
            {&lt;br /&gt;
                string mailaddress=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailaddress != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, mailaddress, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETADDRESS, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SUBJECT)&lt;br /&gt;
            {&lt;br /&gt;
                string mailsubject=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailsubject != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, mailsubject, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETSUBJECT, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Not recording.&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    if (NumLines == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND_NOTECARD, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_IGNORE)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines = 0;&lt;br /&gt;
                    Length = 0;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Show();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_READ)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumMessages == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Read();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        ++CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        --CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_FIRST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = 0;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LAST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LIST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    List();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SELECT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;Need to supply a message number.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    integer msgnum = (integer)arg;&lt;br /&gt;
                     &lt;br /&gt;
                    if (msgnum &amp;lt; 0 || msgnum &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Message number &amp;quot; + arg + &amp;quot; not in mail buffer.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = msgnum;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_DELETE)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    --NumMessages;&lt;br /&gt;
                     &lt;br /&gt;
                    if (NumMessages == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = -1;&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (CurrentMessage &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CLEAR)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList=[];&lt;br /&gt;
                    AddressList=[];&lt;br /&gt;
                    SubjectList=[];&lt;br /&gt;
                    BodyList=[];&lt;br /&gt;
                    NumMessages=0;&lt;br /&gt;
                    CurrentMessage=-1;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_HELP, arg, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_INFO)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                Show();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_RESET)&lt;br /&gt;
            {&lt;br /&gt;
                llResetScript();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                state not_running;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HOME)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs==1)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETHOME, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETHOME, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// email() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    email(string time, string address, string subject, string body, integer queued)&lt;br /&gt;
    {&lt;br /&gt;
        NotifyNewMail(time, address, subject, body);&lt;br /&gt;
        TimeList = (TimeList=[]) + TimeList + [time];&lt;br /&gt;
        AddressList = (AddressList=[]) + AddressList + [address];&lt;br /&gt;
        SubjectList = (SubjectList=[]) + SubjectList + [subject];&lt;br /&gt;
        BodyList = (BodyList=[]) + BodyList + [body];&lt;br /&gt;
        ++NumMessages;&lt;br /&gt;
        &lt;br /&gt;
        if (CurrentMessage == -1)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = NumMessages - 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_REPLY)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state not_running&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state not_running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;SL Mailbox switched OFF. Say @ON to switch it back on.&amp;quot;);&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// on_rez() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// listen() ////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer chan, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string command=llToUpper(message);&lt;br /&gt;
        &lt;br /&gt;
        if (command == COMMAND_ON)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state Error&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state Error&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Error in SL Mail: not all component scripts found.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// End SL Mail V1.2.lsl&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Address Book V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Read and interpret the contents of the Address Book.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail AddressBook V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// &lt;br /&gt;
//  Read the Address Book from a notecard named &amp;quot;Address Book&amp;quot;.&lt;br /&gt;
//&lt;br /&gt;
//  The Address Book has the following format:&lt;br /&gt;
//  &lt;br /&gt;
//  [ADDRESS BOOK]&lt;br /&gt;
//  Name1=username@yourdomain.com&lt;br /&gt;
//  Name2=otheruser@otherdomain.com&lt;br /&gt;
//  ...&lt;br /&gt;
//  [GROUP]&lt;br /&gt;
//  group1=Name1, Name2&lt;br /&gt;
//  ...&lt;br /&gt;
//&lt;br /&gt;
//  Notes:&lt;br /&gt;
//  1. Group and Name share the same namespace, and must be unique.&lt;br /&gt;
//  2. It is allowed to have a name in the addressbook with multiple addresses, seperated by comma&#039;s.&lt;br /&gt;
// &lt;br /&gt;
/////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string  CurrentMailAddress = &amp;quot;&amp;quot;;&lt;br /&gt;
string  CurrentMailSubject = &amp;quot;&amp;quot;;&lt;br /&gt;
integer StatusOnline = FALSE;&lt;br /&gt;
&lt;br /&gt;
// Fetch or Send notecard&lt;br /&gt;
&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Names&lt;br /&gt;
&lt;br /&gt;
list    AddressBookList=[];&lt;br /&gt;
list    MailAddressList=[];&lt;br /&gt;
&lt;br /&gt;
string  STRING_HOME=&amp;quot;HOME&amp;quot;;&lt;br /&gt;
string  STRING_SELF=&amp;quot;SELF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Groups&lt;br /&gt;
&lt;br /&gt;
list   GroupList=[];&lt;br /&gt;
list   GroupNameList=[];&lt;br /&gt;
&lt;br /&gt;
string LSL_DOMAIN = &amp;quot;lsl.secondlife.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Read Address Book notecard&lt;br /&gt;
&lt;br /&gt;
string  ADDRESSBOOK_NOTECARD=&amp;quot;Address Book&amp;quot;;&lt;br /&gt;
integer Line=0;&lt;br /&gt;
key     reqAddressBook=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
integer Section=0;&lt;br /&gt;
integer SECTION_ADDRESS_BOOK=1;&lt;br /&gt;
integer SECTION_GROUP=2;&lt;br /&gt;
string  STRING_ADDRESS_BOOK=&amp;quot;ADDRESS BOOK&amp;quot;;&lt;br /&gt;
string  STRING_GROUP=&amp;quot;GROUP&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Links messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
integer MSG_MESSAGE_NOTIFY              = 90900;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED            = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR            = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// GetSelfAddress() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
string GetSelfAddress()&lt;br /&gt;
{&lt;br /&gt;
    return (string)llGetKey() + &amp;quot;@&amp;quot; + LSL_DOMAIN;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Info() /////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Info()&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;The mail address for this object is: &amp;quot; &lt;br /&gt;
                    + GetSelfAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// IsValidKeyFormat() //////////////////////&lt;br /&gt;
&lt;br /&gt;
integer IsValidKeyFormat(string str)&lt;br /&gt;
{&lt;br /&gt;
    string keychars = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    if (llStringLength(str) != 36)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    if( (llGetSubString( str, 8, 8 )   != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 13, 13 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 18, 18 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 23, 23 )  != &amp;quot;-&amp;quot; ) )&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 9; i &amp;lt; 13; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 14; i &amp;lt; 18; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 19; i &amp;lt; 23; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 24; i &amp;lt; 36; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// ValidMailAddress() ////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer ValidMailAddress(string arg)&lt;br /&gt;
{&lt;br /&gt;
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));&lt;br /&gt;
    &lt;br /&gt;
    if (adress == &amp;quot;&amp;quot;)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    list parse = llParseStringKeepNulls(adress, [ &amp;quot;@&amp;quot; ], []);&lt;br /&gt;
    string account = llList2String(parse,0);&lt;br /&gt;
    string domain  = llList2String(parse,1);&lt;br /&gt;
    &lt;br /&gt;
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    &lt;br /&gt;
    if (domain == LSL_DOMAIN)&lt;br /&gt;
    {&lt;br /&gt;
        return IsValidKeyFormat(account);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list parsedomain = llParseString2List(domain, [ &amp;quot;.&amp;quot; ], []);&lt;br /&gt;
    &lt;br /&gt;
        if (llGetListLength(parsedomain) &amp;lt; 2)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        &lt;br /&gt;
        integer num = llGetListLength(parsedomain);&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llStringLength(llList2String(parsedomain,i)) &amp;lt; 2)&lt;br /&gt;
            {&lt;br /&gt;
                return FALSE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetAddressStr() ///////////////////&lt;br /&gt;
&lt;br /&gt;
string GetAndCheckAddressStr(string address)&lt;br /&gt;
{&lt;br /&gt;
    list addresslist = llCSV2List(address);&lt;br /&gt;
    integer num=llGetListLength(addresslist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    string addressstr=&amp;quot;&amp;quot;;&lt;br /&gt;
    string curaddress=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        curaddress=llList2String(addresslist,i);&lt;br /&gt;
        &lt;br /&gt;
        if (ValidMailAddress(curaddress))&lt;br /&gt;
        {&lt;br /&gt;
            addressstr = (addressstr=&amp;quot;&amp;quot;) + addressstr + curaddress + &amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address string: &#039;&amp;quot; &lt;br /&gt;
                            + curaddress + &amp;quot;&#039;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return llGetSubString(addressstr, 0, -2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ProcessLine() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
ProcessLine(string rawline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(rawline,STRING_TRIM);&lt;br /&gt;
    string first=llGetSubString(line,0,0);&lt;br /&gt;
    string last=llGetSubString(line,-1,-1);&lt;br /&gt;
    &lt;br /&gt;
    // Ignore a blank line or comment line&lt;br /&gt;
    if (line == &amp;quot;&amp;quot; || first == &amp;quot;#&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // Check for the right section&lt;br /&gt;
    &lt;br /&gt;
    if (first == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; last == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        string sectionstr=llToUpper(llStringTrim(llGetSubString(line,1,-2),STRING_TRIM));&lt;br /&gt;
        &lt;br /&gt;
        if (sectionstr == STRING_ADDRESS_BOOK)&lt;br /&gt;
        {&lt;br /&gt;
            Section = SECTION_ADDRESS_BOOK;&lt;br /&gt;
        }&lt;br /&gt;
        else if (sectionstr == STRING_GROUP)&lt;br /&gt;
        {&lt;br /&gt;
            if (Section == 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                        + &amp;quot;. Group section defined before Address Book section.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Section = SECTION_GROUP;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid section header &#039;&amp;quot; + sectionstr &lt;br /&gt;
                        + &amp;quot;&#039; in &amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Must be in a section&lt;br /&gt;
    &lt;br /&gt;
    if (Section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;. No section header.&amp;quot;, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    list     parse=llParseString2List(line, [ &amp;quot;=&amp;quot; ], []);&lt;br /&gt;
    integer  num=llGetListLength(parse);&lt;br /&gt;
    &lt;br /&gt;
    // Format must be correct&lt;br /&gt;
    &lt;br /&gt;
    if (num != 2)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; +  (string)(Line+1) + &amp;quot;:\n&amp;quot; + rawline, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (Section == SECTION_ADDRESS_BOOK)&lt;br /&gt;
    {&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(name) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + name &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ name ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            string address=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
            string addressstr=GetAndCheckAddressStr(address);&lt;br /&gt;
            &lt;br /&gt;
            if (addressstr != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                AddressBookList     = (AddressBookList=[])     + AddressBookList     + [ name ];&lt;br /&gt;
                MailAddressList     = (MailAddressList=[])     + MailAddressList     + [ addressstr ];&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;No valid mail address for &#039;&amp;quot; + name &lt;br /&gt;
                    + &amp;quot;&#039;. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                    + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name &lt;br /&gt;
                + &amp;quot;&#039; already defined. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // Group&lt;br /&gt;
    {&lt;br /&gt;
        string group=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(group) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + group &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ group ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(GroupList, [ group ]) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                string names=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
                list   namelist=llCSV2List(names);&lt;br /&gt;
                integer num=llGetListLength(namelist);&lt;br /&gt;
                integer i;&lt;br /&gt;
                integer index;&lt;br /&gt;
                string  name;&lt;br /&gt;
                string  namestr=&amp;quot;&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
                for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                    name=llList2String(namelist,i);&lt;br /&gt;
                    index=llListFindList(AddressBookList, [ name ]);&lt;br /&gt;
            &lt;br /&gt;
                    if (index == -1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name + &amp;quot;&#039; defined in Group &#039;&amp;quot; &lt;br /&gt;
                                + group + &amp;quot;&#039; not found in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY); &lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        namestr = (namestr=&amp;quot;&amp;quot;) + namestr + name + &amp;quot;,&amp;quot;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (namestr != &amp;quot;&amp;quot;)&lt;br /&gt;
                {    &lt;br /&gt;
                    namestr=llGetSubString(namestr,0,-2);&lt;br /&gt;
                    GroupList         = (GroupList=[])         + GroupList     + [ group ];&lt;br /&gt;
                    GroupNameList     = (GroupNameList=[])    + GroupNameList + [ namestr ];&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                        + &amp;quot;&#039; has no valid names. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                        + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                    + &amp;quot;&#039; already defined in Group. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                    + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group&lt;br /&gt;
                + &amp;quot;&#039; already defined in Address Book. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// GetGroupAddressList ///////////////&lt;br /&gt;
&lt;br /&gt;
string GetGroupAddressList(string group)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(GroupList, [ group ]);&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(GroupList);&lt;br /&gt;
    string  grouplist=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        for (i = index; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2String(GroupList,i) == group)&lt;br /&gt;
            {&lt;br /&gt;
                grouplist = (grouplist=&amp;quot;&amp;quot;) + grouplist + llList2String(GroupNameList,i) + &amp;quot;,&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (grouplist != &amp;quot;&amp;quot;) grouplist=llGetSubString(grouplist,0,-2);   // remove last &amp;quot;,&amp;quot;&lt;br /&gt;
        return grouplist;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// SetMailAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetMailAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ address ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        index=llListFindList(GroupList, [ address ]);&lt;br /&gt;
        &lt;br /&gt;
        if (index == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llToUpper(address) == STRING_SELF)&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = GetSelfAddress();&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if(ValidMailAddress(address))&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = address;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Mail adress &amp;quot; + address &lt;br /&gt;
                            + &amp;quot; : not found in adress book or invalid format.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailAddress = GetGroupAddressList(address);&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        CurrentMailAddress = llList2String(MailAddressList,index);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                        + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string message)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No mail address defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No subject defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list mailaddresslist=llCSV2List(CurrentMailAddress);&lt;br /&gt;
        integer num=llGetListLength(mailaddresslist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(mailaddresslist,i);&lt;br /&gt;
            llEmail(address, CurrentMailSubject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMailHome() ////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMailHome(string message, string subject)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, STRING_HOME &lt;br /&gt;
                + &amp;quot; not set. Set your home adress with @HOME &amp;lt;address&amp;gt;.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        string homeaddress=llList2String(AddressBookList,index);&lt;br /&gt;
        list   homelist=llCSV2List(homeaddress);&lt;br /&gt;
        integer num=llGetListLength(homelist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(homelist,i);&lt;br /&gt;
            llEmail(address, subject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
string GetHomeAddress()&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;not set&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2String(MailAddressList,index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetHomeAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        AddressBookList     = (AddressBookList=[]) + [ STRING_HOME ] + AddressBookList;&lt;br /&gt;
        MailAddressList     = (MailAddressList=[]) + [ GetAndCheckAddressStr(address) ]  + MailAddressList;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MailAddressList = llListReplaceList(MailAddressList, [ GetAndCheckAddressStr(address) ], index, index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        Line=0;&lt;br /&gt;
        Section=0;&lt;br /&gt;
        llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// dataserver() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqAddressBook)&lt;br /&gt;
        {&lt;br /&gt;
            reqAddressBook = NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                ProcessLine(data);&lt;br /&gt;
                reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Address Book loaded.&amp;quot;, NULL_KEY);&lt;br /&gt;
                state running;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// timer() ///////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_ERROR, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Could not read Address Book: &amp;quot; &lt;br /&gt;
                            + ADDRESSBOOK_NOTECARD + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// link_message() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_MESSAGE_GETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is empty.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailSubject = message;&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is empty.&amp;quot;, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            SetMailAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Body of message to send is empty. &amp;quot; &lt;br /&gt;
                                +  &amp;quot;No mail is send.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SENDHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SendMailHome(message, (string)id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetInventoryType(message) == INVENTORY_NOTECARD)&lt;br /&gt;
            {&lt;br /&gt;
                Notecard2Fetch = message;                &lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_READ, message, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + message + &amp;quot; not found.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_NOTECARD_FETCHED)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + Notecard2Fetch &lt;br /&gt;
                            + &amp;quot; was empty or could not be read.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Home address is: &amp;quot; + GetHomeAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SetHomeAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_INFO)&lt;br /&gt;
        {&lt;br /&gt;
            Info();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
// End SL Mail AddressBook V1.2.lsl&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail FetchNotecard V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch the contents of a notecard and return it via link message as a string.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Notecard&lt;br /&gt;
&lt;br /&gt;
integer Line=0;&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
key     reqNotecard=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=10.0;&lt;br /&gt;
integer Fetched=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Lines&lt;br /&gt;
&lt;br /&gt;
list LineList=[];&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    /////////////////////// dataserver() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqNotecard)&lt;br /&gt;
        {&lt;br /&gt;
            reqNotecard=NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                LineList = (LineList=[]) + LineList + [ data ];&lt;br /&gt;
                reqNotecard = llGetNotecardLine(Notecard2Fetch, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Fetched=TRUE;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, llDumpList2String(LineList, &amp;quot;\n&amp;quot;), NULL_KEY);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /////////////////////// timer() ///////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        if (!Fetched)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            llSetTimerEvent(0.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer send, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_NOTECARD_READ)&lt;br /&gt;
        {&lt;br /&gt;
            Line=0;&lt;br /&gt;
            Notecard2Fetch=message;&lt;br /&gt;
            LineList=[];&lt;br /&gt;
            Fetched=FALSE;&lt;br /&gt;
            reqNotecard=llGetNotecardLine(Notecard2Fetch, Line);&lt;br /&gt;
            llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL OnlineStatus V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch online status of owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Online status&lt;br /&gt;
&lt;br /&gt;
key     reqOnlineStatus=NULL_KEY;&lt;br /&gt;
float   STATUS_INTERVAL=2.0;&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_STATUS_ONLINE       = 30000;&lt;br /&gt;
integer MS_STATUS_OFFLINE       = 30100;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus=llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
        llSetTimerEvent(STATUS_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// dataserver() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqOnlineStatus)&lt;br /&gt;
        {&lt;br /&gt;
            reqOnlineStatus = NULL_KEY;&lt;br /&gt;
        &lt;br /&gt;
            if (data==&amp;quot;1&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_STATUS_ONLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if (data==&amp;quot;0&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MS_STATUS_OFFLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus = llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Help V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Display help information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail Help V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP    = 10000;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Help() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Help()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;HELP for SL Mail V1.2.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;COMMANDS:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HELP               - displays help info.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@INFO               - display mailaddress of this object.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RECORD             - start recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CONTINUE           - continue recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@STOP               - stop recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@IGNORE             - ignore the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SHOW               - show what your recorded.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SEND               - send the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@MAIL &amp;lt;mailadress&amp;gt;  - set the mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SUBJECT subject    - set the mail subject.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LIST               - list messages in mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SELECT &amp;lt;message&amp;gt;   - select message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@READ               - read current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@NEXT               - read next message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@PREV               - read previous message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@FIRST              - read first message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LAST               - read last message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@DELETE             - delete current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CLEAR              - clear the mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@REPLY              - reply to current message.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RESET              - reset the script.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HOME               - set the home mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@OFF                - switch mailbox OFF.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@ON                 - switch mailbox ON.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_HELP)&lt;br /&gt;
        {&lt;br /&gt;
            Help();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail Help V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}&lt;/div&gt;</description>
			<pubDate>Sun, 07 Oct 2007 11:09:58 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:SL_Mail_V1.2</comments>
		</item>
		<item>
			<title>SL Mail V1.2</title>
			<link>https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34589</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34589</guid>
			<description>&lt;p&gt;Flennan Roffo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}} __NOTOC__&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=&#039;&#039;&#039;Second Life mail client&#039;&#039;&#039;=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Send and receive email from within Second Life from and to any address.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implemented with Address Book function (in a notecard named &#039;Address Book&#039;) to stores addresses by name  and to compile groups of named addresses. Current version is stand-alone (no server functionality) and uses chat commands only.&lt;br /&gt;
&lt;br /&gt;
[[Image:BannerSLMail.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=Release Notes V1.2=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 Release notes (edition 2, 4 sept 2007)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LICENCE INFO&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is released under GNU free software licence&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;PRODUCTION &amp;amp; MAINTANENCE&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
by Logic Scripted Products and Script Services&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
SLurl:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Contact: [[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
&lt;br /&gt;
Email: [mailto:info@slmail.info &#039;&#039;&#039;info@slmail.info&#039;&#039;&#039;] or [mailto:Flennan.Roffo@slmail.info &#039;&#039;&#039;Flennan.Roffo@slmail.info&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;DESCRIPTION&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is a simple tool to send and receive mail from within SL.&lt;br /&gt;
You can either compose a message yourself using chat recording, or choose a notecard from inventory to send. The Address Book functionality allows you to use short names for mail recipients stored in a notecard. The current version does not have a persisent mail address. Watch out for the upcoming next release (V1.3) which will facilitate persisent in-world mail addresses and will be enhanced with many new features (See: Requests For Change (RFC).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;COMMANDS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Help&#039;&#039;&#039;&lt;br /&gt;
||Show Help about available commands&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Record&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording (for owner only).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Stop&#039;&#039;&#039;&lt;br /&gt;
||Stops the chat recording without sending&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Continue&#039;&#039;&#039;&lt;br /&gt;
||Continues a previously stopped chat recording. Lines will be appended to you recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Show&#039;&#039;&#039;&lt;br /&gt;
||Shows the content of the recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send&#039;&#039;&#039;&lt;br /&gt;
||If recording, stops the recording, and sends the mail (need to supply mail address and subject first!)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send &amp;lt;notecard&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Sends the content of the notecard, instead of the chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Ignore&#039;&#039;&#039;&lt;br /&gt;
||Ignores your current chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject &amp;lt;subject&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the subject of the mail.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail subject.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Set the HOME address of the owner (mail will be forwarder to this address when offline).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home&#039;&#039;&#039;&lt;br /&gt;
||Show the HOME address.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Info&#039;&#039;&#039;&lt;br /&gt;
||Shows the mail address the object this script is running in uses (e.g. &amp;lt;object-key&amp;gt;@lsl.secondlife.com).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Read&#039;&#039;&#039;&lt;br /&gt;
||Reads the current message from the mail buffer (the mail buffer gets filled with mail you receive)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Select &amp;lt;msg&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Select a message number from the availabe messages in the mail buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Next&#039;&#039;&#039;&lt;br /&gt;
||Make next message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Prev&#039;&#039;&#039;&lt;br /&gt;
||Make previous message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@First&#039;&#039;&#039;&lt;br /&gt;
||Make the first message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Last&#039;&#039;&#039;&lt;br /&gt;
||Make the last message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Clear&#039;&#039;&#039;&lt;br /&gt;
||Clear the mail buffer&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Delete&#039;&#039;&#039;&lt;br /&gt;
||Deletes only the current message&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Reply&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording to reply to the current message. Mail adress and subject are filled in automatically.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* Commands are case insensitive (&amp;quot;@read&amp;quot; == &amp;quot;@READ&amp;quot;). Arguments might not be case insensitive.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;ADDRESS BOOK FORMAT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
A notecard of the name &#039;Address Book&#039; is read during initialization which may contain Address Book items and Groups.&lt;br /&gt;
The notecard is split in two sections, which need to be defined in that particular order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[ADDRESS BOOK]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Defines the section in which you can put names for mail addresses,  like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name1=account@thisdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name2=user@otherdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[GROUP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define groups of previously defined names under a new name, like for instance:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyGroup=Name1, Name2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note that names of groups and individual mail adresses share the same namespace and must be unique.&lt;br /&gt;
&lt;br /&gt;
So when you filled in your mail adresses in the Address Book, you can now use:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail Name1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to  &amp;lt;account@thisdomain.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail MyGroup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to &amp;lt;account@thisdomain.com&amp;gt; and &amp;lt;user@otherdomain.com&amp;gt;&lt;br /&gt;
Mails will be sent one after another.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* Names for Addreses and Groups are case insensitive (e.g. &amp;quot;mary&amp;quot;  == &amp;quot;MARY&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* The special address &#039;Self&#039; can be used in commands where otherwise an address specification can be used. &#039;Self&#039; is case insensitive (e.g. &amp;quot;self&amp;quot; == &amp;quot;SELF&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LIMITATIONS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
The current version is limited by the following:&lt;br /&gt;
&lt;br /&gt;
* Chat recording lines are limited by the 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Output of lines from the mail buffer are also limited by this 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Incoming mail is limited to a 1000 (1024?) byte limit&lt;br /&gt;
&lt;br /&gt;
* Outgoing mai is limited by a 4096 byte limit, which includes the standard mail header (region/location info on the first two lines)&lt;br /&gt;
&lt;br /&gt;
We are making adjustments to this release to help overcome these limitations. At least the line lenght limit can be overcome by introducing a line continuation character (for example a hyphen &#039;-&#039;) that when used at the end of a line appends the next line, so lines longer then 255 bytes are possible then.&lt;br /&gt;
&lt;br /&gt;
To overcome the outgoing mail length limit, the mail can be broken textualy into parts, and each part can be send seperatedely, with an indication in the subject or in an introduced primary line of the mail body to indicate that the mail was split into parts.&lt;br /&gt;
For incoming mail and at least to receive mail from other SL Mail programs, a protocol will be introduced to receive mail in parts that are joined together after receiving them to form a single mail.&lt;br /&gt;
&lt;br /&gt;
These enhancements will be made available in the next release (V1.3) of SL Mail &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;BUGS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Report any bugs you find in this release to Logic (IM: Flennan Roffo).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;REQUEST FOR CHANGE (RFC)&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Do you have additional wishes for enhancement of this product?&lt;br /&gt;
Contact Flennan Roffo and we will see if they can be implemented in the next release.&lt;br /&gt;
&lt;br /&gt;
Existing RFC&#039;s are:&lt;br /&gt;
&lt;br /&gt;
* Menu support for commands.&lt;br /&gt;
&lt;br /&gt;
* Lines on incoming/outgoing mail longer than 255 bytes.&lt;br /&gt;
&lt;br /&gt;
* Send messages longer than 4096 (minus SL mail header) bytes.&lt;br /&gt;
&lt;br /&gt;
* Receive messages longer than 1024 bytes.&lt;br /&gt;
&lt;br /&gt;
* Permanent mail addresses for the SL Mail client (like: &amp;lt;Flennan.Roffo@somedomain.sl&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Add your RFC!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In-world join the group &amp;quot;SL Mail&amp;quot; for bug reports, feature requests, the latest SL Mail release, and notices about development issues.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scripts=&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==Script: SL Mail v1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail core module which scans for incoming mail messages and executes commands used by the owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail V1.2.lsl&lt;br /&gt;
// (c) 2007 Logic Scripted Products and Script Services&lt;br /&gt;
// Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
// VERSION&lt;br /&gt;
// Version: 1.2&lt;br /&gt;
&lt;br /&gt;
// HISTORY&lt;br /&gt;
// Date         Version     Author              Comment&lt;br /&gt;
// --------------------------------------------------------------------------------------&lt;br /&gt;
// 28 aug 2007  V 1.0       Flennan Roffo       Created&lt;br /&gt;
//&lt;br /&gt;
//  1 sep 2007  V 1.1       Flennan Roffo       @Reply empties the recording buffer.&lt;br /&gt;
//                                                @Send while recording ends recording&lt;br /&gt;
//                                                and sends the mail if a mail address&lt;br /&gt;
//                                                and subject are supplied.&lt;br /&gt;
//                                                Fixed incorrect date in Unix2DateTime.&lt;br /&gt;
//  3 sep 2007  V 1.2       Flennan Roffo       Notification options:&lt;br /&gt;
//                                              - When online, send an IM when mail is received.&lt;br /&gt;
//                                              - When offline, send to HOME mail adress.&lt;br /&gt;
//                                              Adressbook&lt;br /&gt;
//                                              - Read adress book from config notecard.&lt;br /&gt;
&lt;br /&gt;
// LICENCE&lt;br /&gt;
// This program is free software; you can redistribute it and/or&lt;br /&gt;
// modify it under the terms of the GNU General Public License&lt;br /&gt;
// as published by the Free Software Foundation; either version 2&lt;br /&gt;
// of the License, or (at your option) any later version.&lt;br /&gt;
// &lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
// &lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program; if not, write to the Free Software&lt;br /&gt;
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
// (Also available at http://www.gnu.org/copyleft/gpl.html) &lt;br /&gt;
&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// Let&#039;s you record a message and sent to email and get messages and reply to messages.&lt;br /&gt;
// Must supply a valid mail adress and non-empty subject using chat commands.&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
// 1) Check for the maximum length of an email message (including newline and header).&lt;br /&gt;
// 2) Read adress book from notecard.                                    *DONE*&lt;br /&gt;
// 3) Send incoming mail to personal mail adress when offline.            *DONE*&lt;br /&gt;
// 4) Alert with an IM when online upon receiving new mail.                *DONE*&lt;br /&gt;
&lt;br /&gt;
string   SL_MAIL_VERSION = &amp;quot;V 1.2&amp;quot;;&lt;br /&gt;
string   SL_MAIL_DATE    = &amp;quot; 2 sep 2007&amp;quot;;&lt;br /&gt;
integer  ErrorFlag         = FALSE;&lt;br /&gt;
list     ScriptList        = [ &amp;quot;SL Mail Help V1.2&amp;quot;, &amp;quot;SL Mail AddressBook V1.2&amp;quot;, &lt;br /&gt;
                                &amp;quot;SL Mail OnlineStatus V1.2&amp;quot;, &amp;quot;SL Mail FetchNotecard V1.2&amp;quot; ];    &lt;br /&gt;
string   LSL_DOMAIN=&amp;quot;lsl.secondlife.com&amp;quot;; &lt;br /&gt;
integer  StatusOnline=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Commands&lt;br /&gt;
&lt;br /&gt;
string  COMMAND_RECORD     = &amp;quot;@RECORD&amp;quot;;&lt;br /&gt;
string  COMMAND_CONTINUE   = &amp;quot;@CONTINUE&amp;quot;;&lt;br /&gt;
string  COMMAND_STOP       = &amp;quot;@STOP&amp;quot;;&lt;br /&gt;
string  COMMAND_MAIL       = &amp;quot;@MAIL&amp;quot;;&lt;br /&gt;
string  COMMAND_SUBJECT    = &amp;quot;@SUBJECT&amp;quot;;&lt;br /&gt;
string  COMMAND_SEND       = &amp;quot;@SEND&amp;quot;;&lt;br /&gt;
string  COMMAND_SEE        = &amp;quot;@SEE&amp;quot;;&lt;br /&gt;
string  COMMAND_IGNORE     = &amp;quot;@IGNORE&amp;quot;;&lt;br /&gt;
string  COMMAND_READ       = &amp;quot;@READ&amp;quot;;&lt;br /&gt;
string  COMMAND_DELETE     = &amp;quot;@DELETE&amp;quot;;&lt;br /&gt;
string  COMMAND_CLEAR      = &amp;quot;@CLEAR&amp;quot;;&lt;br /&gt;
string  COMMAND_REPLY      = &amp;quot;@REPLY&amp;quot;;&lt;br /&gt;
string  COMMAND_NEXT       = &amp;quot;@NEXT&amp;quot;;&lt;br /&gt;
string  COMMAND_PREV       = &amp;quot;@PREV&amp;quot;;&lt;br /&gt;
string  COMMAND_FIRST      = &amp;quot;@FIRST&amp;quot;;&lt;br /&gt;
string  COMMAND_LAST       = &amp;quot;@LAST&amp;quot;;&lt;br /&gt;
string  COMMAND_LIST       = &amp;quot;@LIST&amp;quot;;&lt;br /&gt;
string  COMMAND_SELECT     = &amp;quot;@SELECT&amp;quot;;&lt;br /&gt;
string  COMMAND_HELP       = &amp;quot;@HELP&amp;quot;;&lt;br /&gt;
string  COMMAND_INFO       = &amp;quot;@INFO&amp;quot;;&lt;br /&gt;
string  COMMAND_RESET      = &amp;quot;@RESET&amp;quot;;&lt;br /&gt;
string  COMMAND_SHOW       = &amp;quot;@SHOW&amp;quot;;&lt;br /&gt;
string  COMMAND_ON         = &amp;quot;@ON&amp;quot;;&lt;br /&gt;
string  COMMAND_OFF        = &amp;quot;@OFF&amp;quot;;&lt;br /&gt;
string  COMMAND_HOME       = &amp;quot;@HOME&amp;quot;;&lt;br /&gt;
string  COMMAND_LOAD       = &amp;quot;@LOAD&amp;quot;;&lt;br /&gt;
string  COMMAND_ADDRESS    = &amp;quot;@ADDRESS&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Recording&lt;br /&gt;
&lt;br /&gt;
integer Recording = FALSE;&lt;br /&gt;
&lt;br /&gt;
list    ChatRecording=[];&lt;br /&gt;
integer NumLines=0;&lt;br /&gt;
integer Length=0;&lt;br /&gt;
&lt;br /&gt;
list     TimeList=[];&lt;br /&gt;
list     AddressList=[];&lt;br /&gt;
list     SubjectList=[];&lt;br /&gt;
list     BodyList=[];&lt;br /&gt;
integer  NumMessages=0;&lt;br /&gt;
integer  CurrentMessage=-1;&lt;br /&gt;
&lt;br /&gt;
float    MAIL_FETCH_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
// Link Messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP                        = 10000;&lt;br /&gt;
integer MSG_STATUS_ONLINE               = 30000;&lt;br /&gt;
integer MSG_STATUS_OFFLINE              = 30100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED          = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR           = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Unix Time conversion //////////////////&lt;br /&gt;
&lt;br /&gt;
integer DAYS_PER_YEAR        = 365;                // Non leap year&lt;br /&gt;
integer SECONDS_PER_YEAR     = 31536000;          // Non leap year&lt;br /&gt;
integer SECONDS_PER_DAY      = 86400;&lt;br /&gt;
integer SECONDS_PER_HOUR     = 3600;&lt;br /&gt;
integer SECONDS_PER_MINUTE   = 60;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// LeapYear() /////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer LeapYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (year % 4 == 0)&lt;br /&gt;
    {&lt;br /&gt;
        if (year % 100 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (year % 400 == 0)&lt;br /&gt;
            {&lt;br /&gt;
                return 1;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// DaysPerMonth() ///////////////////////////////////////&lt;br /&gt;
                &lt;br /&gt;
integer DaysPerMonth(integer year,integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;lt; 8)&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (month == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if (LeapYear(year))&lt;br /&gt;
                {&lt;br /&gt;
                    return 29;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    return 28;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 30;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 30;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////// DaysPerYear() ////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DaysPerYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (LeapYear(year))&lt;br /&gt;
        return DAYS_PER_YEAR + 1;&lt;br /&gt;
    else&lt;br /&gt;
        return DAYS_PER_YEAR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Unix2DataTime() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list Unix2DateTime(integer unixtime)&lt;br /&gt;
{&lt;br /&gt;
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;&lt;br /&gt;
    integer day = days_since_1_1_1970 + 1;&lt;br /&gt;
    integer year  = 1970;&lt;br /&gt;
    integer days_per_year = DaysPerYear(year);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_year)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_year;&lt;br /&gt;
        ++year;&lt;br /&gt;
        days_per_year = DaysPerYear(year);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer month = 1;&lt;br /&gt;
    integer days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_month)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_month;&lt;br /&gt;
        &lt;br /&gt;
        if (++month &amp;gt; 12)&lt;br /&gt;
        {    &lt;br /&gt;
            ++year;&lt;br /&gt;
            month = 1;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;&lt;br /&gt;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;&lt;br /&gt;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;&lt;br /&gt;
    integer minute      = second / SECONDS_PER_MINUTE;&lt;br /&gt;
    second               = second % SECONDS_PER_MINUTE;&lt;br /&gt;
    &lt;br /&gt;
    return [ year, month, day, hour, minute, second ];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// MonthName() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list MonthNameList = [     &amp;quot;JAN&amp;quot;, &amp;quot;FEB&amp;quot;, &amp;quot;MAR&amp;quot;, &amp;quot;APR&amp;quot;, &amp;quot;MAY&amp;quot;, &amp;quot;JUN&amp;quot;, &lt;br /&gt;
                        &amp;quot;JUL&amp;quot;, &amp;quot;AUG&amp;quot;, &amp;quot;SEP&amp;quot;, &amp;quot;OCT&amp;quot; , &amp;quot;NOV&amp;quot;, &amp;quot;DEC&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
string MonthName(integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;gt;= 0 &amp;amp;&amp;amp; month &amp;lt; 12)&lt;br /&gt;
        return llList2String(MonthNameList, month);&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// DateString() ///////////////////////////&lt;br /&gt;
&lt;br /&gt;
string DateString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer year       = llList2Integer(timelist,0);&lt;br /&gt;
    integer month      = llList2Integer(timelist,1);&lt;br /&gt;
    integer day        = llList2Integer(timelist,2);&lt;br /&gt;
    &lt;br /&gt;
    return (string)day + &amp;quot;-&amp;quot; + MonthName(month - 1) + &amp;quot;-&amp;quot; + (string)year;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// TimeString() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string TimeString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer hour          = llList2Integer(timelist,3);&lt;br /&gt;
    integer minute         = llList2Integer(timelist,4);&lt;br /&gt;
    integer second         = llList2Integer(timelist,5);&lt;br /&gt;
    string  hourstr     = (string)hour;&lt;br /&gt;
    string  minutestr   = (string)minute;&lt;br /&gt;
    string  secondstr   = (string)second;&lt;br /&gt;
    &lt;br /&gt;
    if (hour &amp;lt; 10)         hourstr     = &amp;quot;0&amp;quot; + hourstr;&lt;br /&gt;
    if (minute &amp;lt; 10)     minutestr     = &amp;quot;0&amp;quot; + minutestr;&lt;br /&gt;
    if (second &amp;lt; 10)    secondstr    = &amp;quot;0&amp;quot; + secondstr;&lt;br /&gt;
    return hourstr + &amp;quot;:&amp;quot; + minutestr + &amp;quot;:&amp;quot; + secondstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() /////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string body)&lt;br /&gt;
{&lt;br /&gt;
    // llOwnerSay(&amp;quot;Sending message to &#039;&amp;quot; + address + &amp;quot;&#039; with subject &#039;&amp;quot; + subject +&amp;quot;&#039;.&amp;quot;);&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND, body, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// SendHome() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendHome(string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SENDHOME, body, (key)subject);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Show() ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Show()&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;Current chat recording is:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; NumLines; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(ChatRecording,i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;Lines is &amp;quot; + (string)NumLines);&lt;br /&gt;
    llOwnerSay(&amp;quot;Message length is &amp;quot; + (string)Length);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Read() /////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Read()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;Reading message &amp;quot; + (string)CurrentMessage + &amp;quot; from mail buffer.&amp;quot;);&lt;br /&gt;
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);&lt;br /&gt;
    list timelist=Unix2DateTime(time);&lt;br /&gt;
    string Address = llList2String(AddressList,CurrentMessage);&lt;br /&gt;
    string Subject = llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
    string Body    = llList2String(BodyList,CurrentMessage);&lt;br /&gt;
    llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Address: &amp;quot; + Address);&lt;br /&gt;
    llOwnerSay(&amp;quot;Subject: &amp;quot; + Subject);&lt;br /&gt;
    llOwnerSay(&amp;quot;Begin of message body:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    list bodylist=llParseStringKeepNulls(Body, [ &amp;quot;\n&amp;quot; ], []);&lt;br /&gt;
    integer num=llGetListLength(bodylist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(bodylist,i));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;End of message body.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////// List ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
List()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;The mail buffer contains the following messages:\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; NumMessages; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer time=llList2Integer(TimeList,i);&lt;br /&gt;
        list timelist=Unix2DateTime(time);&lt;br /&gt;
        if (i &amp;gt; 0) llOwnerSay(&amp;quot;+-+-+-+-+-+-+-+-+-+-+-+-&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Message: &amp;quot; + (string)i);&lt;br /&gt;
        llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;From:    &amp;quot; + llList2String(AddressList,i));&lt;br /&gt;
        llOwnerSay(&amp;quot;Subject: &amp;quot; + llList2String(SubjectList,i));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////// NotifyNewMail() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
NotifyNewMail(string time, string address, string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    list timelist=Unix2DateTime((integer)time);&lt;br /&gt;
&lt;br /&gt;
    if (StatusOnline)&lt;br /&gt;
    {&lt;br /&gt;
        llInstantMessage(llGetOwner(), &amp;quot;You received a new mail message on &amp;quot; &lt;br /&gt;
                                    + DateString(timelist) + &amp;quot; at &amp;quot; + TimeString(timelist)&lt;br /&gt;
                                    + &amp;quot; from &amp;quot; + address &lt;br /&gt;
                                    + &amp;quot; with the subject &amp;quot; + subject);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        SendHome(&amp;quot;FW: &amp;quot; + subject, &amp;quot;Received at: &amp;quot; + DateString(timelist) + &amp;quot; &amp;quot; + TimeString(timelist) + &amp;quot;\nFrom: &amp;quot; +  address &lt;br /&gt;
                    + &amp;quot;\nBegin message body:\n-------------------\n&amp;quot; + body + &amp;quot;\n-------------------\nEnd message body.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ResetOtherScripts() //////////////////////&lt;br /&gt;
&lt;br /&gt;
ResetOtherScripts()&lt;br /&gt;
{&lt;br /&gt;
    string     name;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(ScriptList);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        name = llList2String(ScriptList,i);&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(name) == INVENTORY_SCRIPT)&lt;br /&gt;
        {&lt;br /&gt;
            llResetOtherScript(name);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Error - script &#039;&amp;quot; + name + &amp;quot;&#039; not found.&amp;quot;);&lt;br /&gt;
            ErrorFlag = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
// default &lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ////////////////////// state_entry() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Welcome to SL Mail, released under GNU software licence.&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Version &amp;quot; + SL_MAIL_VERSION + &amp;quot; &amp;quot; + SL_MAIL_DATE);&lt;br /&gt;
        llOwnerSay(&amp;quot;Produced by Logic Scripted Products &amp;amp; Product Services&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Free memory: &amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
        ResetOtherScripts();&lt;br /&gt;
        &lt;br /&gt;
        if (ErrorFlag)&lt;br /&gt;
            state Error;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// on_rez() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// changed() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_LOADED)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_ERROR)&lt;br /&gt;
        {&lt;br /&gt;
            state Error;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() //////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(MAIL_FETCH_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //////////////////////// on_rez() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// listen() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string trimmessage=llStringTrim(message,STRING_TRIM);&lt;br /&gt;
        list   parse = llParseStringKeepNulls(trimmessage, [ &amp;quot; &amp;quot;], []);&lt;br /&gt;
        string command = llToUpper(llList2String(parse,0));&lt;br /&gt;
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        integer nargs  = llGetListLength(parse);&lt;br /&gt;
        string argstr=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (nargs &amp;gt; 1) argstr=llGetSubString(message, llSubStringIndex(message, &amp;quot; &amp;quot;) + 1, -1);&lt;br /&gt;
            &lt;br /&gt;
        if (Recording)&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Recording stopped. Type @SHOW to see the message you have entered,&amp;quot;&lt;br /&gt;
                            + &amp;quot; or @SEND to send it.&amp;quot;);&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                &lt;br /&gt;
                SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];&lt;br /&gt;
                ++NumLines;&lt;br /&gt;
                Length += llStringLength(message) + 2;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_RECORD)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Start recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                ChatRecording = [];&lt;br /&gt;
                NumLines=0;&lt;br /&gt;
                Length=0;&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CONTINUE)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Continue recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_REPLY)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    string address=llList2String(AddressList,CurrentMessage);&lt;br /&gt;
                    string subject=&amp;quot;Re: &amp;quot; + llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, address, NULL_KEY);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, subject, NULL_KEY);&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines=0;&lt;br /&gt;
                    Length=0;&lt;br /&gt;
                    Recording = TRUE;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_MAIL)&lt;br /&gt;
            {&lt;br /&gt;
                string mailaddress=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailaddress != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, mailaddress, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETADDRESS, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SUBJECT)&lt;br /&gt;
            {&lt;br /&gt;
                string mailsubject=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailsubject != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, mailsubject, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETSUBJECT, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Not recording.&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    if (NumLines == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND_NOTECARD, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_IGNORE)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines = 0;&lt;br /&gt;
                    Length = 0;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Show();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_READ)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumMessages == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Read();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        ++CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        --CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_FIRST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = 0;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LAST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LIST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    List();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SELECT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;Need to supply a message number.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    integer msgnum = (integer)arg;&lt;br /&gt;
                     &lt;br /&gt;
                    if (msgnum &amp;lt; 0 || msgnum &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Message number &amp;quot; + arg + &amp;quot; not in mail buffer.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = msgnum;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_DELETE)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    --NumMessages;&lt;br /&gt;
                     &lt;br /&gt;
                    if (NumMessages == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = -1;&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (CurrentMessage &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CLEAR)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList=[];&lt;br /&gt;
                    AddressList=[];&lt;br /&gt;
                    SubjectList=[];&lt;br /&gt;
                    BodyList=[];&lt;br /&gt;
                    NumMessages=0;&lt;br /&gt;
                    CurrentMessage=-1;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_HELP, arg, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_INFO)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                Show();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_RESET)&lt;br /&gt;
            {&lt;br /&gt;
                llResetScript();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                state not_running;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HOME)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs==1)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETHOME, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETHOME, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// email() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    email(string time, string address, string subject, string body, integer queued)&lt;br /&gt;
    {&lt;br /&gt;
        NotifyNewMail(time, address, subject, body);&lt;br /&gt;
        TimeList = (TimeList=[]) + TimeList + [time];&lt;br /&gt;
        AddressList = (AddressList=[]) + AddressList + [address];&lt;br /&gt;
        SubjectList = (SubjectList=[]) + SubjectList + [subject];&lt;br /&gt;
        BodyList = (BodyList=[]) + BodyList + [body];&lt;br /&gt;
        ++NumMessages;&lt;br /&gt;
        &lt;br /&gt;
        if (CurrentMessage == -1)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = NumMessages - 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_REPLY)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state not_running&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state not_running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;SL Mailbox switched OFF. Say @ON to switch it back on.&amp;quot;);&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// on_rez() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// listen() ////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer chan, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string command=llToUpper(message);&lt;br /&gt;
        &lt;br /&gt;
        if (command == COMMAND_ON)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state Error&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state Error&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Error in SL Mail: not all component scripts found.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// End SL Mail V1.2.lsl&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Address Book V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Read and interpret the contents of the Address Book.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail AddressBook V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// &lt;br /&gt;
//  Read the Address Book from a notecard named &amp;quot;Address Book&amp;quot;.&lt;br /&gt;
//&lt;br /&gt;
//  The Address Book has the following format:&lt;br /&gt;
//  &lt;br /&gt;
//  [ADDRESS BOOK]&lt;br /&gt;
//  Name1=username@yourdomain.com&lt;br /&gt;
//  Name2=otheruser@otherdomain.com&lt;br /&gt;
//  ...&lt;br /&gt;
//  [GROUP]&lt;br /&gt;
//  group1=Name1, Name2&lt;br /&gt;
//  ...&lt;br /&gt;
//&lt;br /&gt;
//  Notes:&lt;br /&gt;
//  1. Group and Name share the same namespace, and must be unique.&lt;br /&gt;
//  2. It is allowed to have a name in the addressbook with multiple addresses, seperated by comma&#039;s.&lt;br /&gt;
// &lt;br /&gt;
/////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string  CurrentMailAddress = &amp;quot;&amp;quot;;&lt;br /&gt;
string  CurrentMailSubject = &amp;quot;&amp;quot;;&lt;br /&gt;
integer StatusOnline = FALSE;&lt;br /&gt;
&lt;br /&gt;
// Fetch or Send notecard&lt;br /&gt;
&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Names&lt;br /&gt;
&lt;br /&gt;
list    AddressBookList=[];&lt;br /&gt;
list    MailAddressList=[];&lt;br /&gt;
&lt;br /&gt;
string  STRING_HOME=&amp;quot;HOME&amp;quot;;&lt;br /&gt;
string  STRING_SELF=&amp;quot;SELF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Groups&lt;br /&gt;
&lt;br /&gt;
list   GroupList=[];&lt;br /&gt;
list   GroupNameList=[];&lt;br /&gt;
&lt;br /&gt;
string LSL_DOMAIN = &amp;quot;lsl.secondlife.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Read Address Book notecard&lt;br /&gt;
&lt;br /&gt;
string  ADDRESSBOOK_NOTECARD=&amp;quot;Address Book&amp;quot;;&lt;br /&gt;
integer Line=0;&lt;br /&gt;
key     reqAddressBook=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
integer Section=0;&lt;br /&gt;
integer SECTION_ADDRESS_BOOK=1;&lt;br /&gt;
integer SECTION_GROUP=2;&lt;br /&gt;
string  STRING_ADDRESS_BOOK=&amp;quot;ADDRESS BOOK&amp;quot;;&lt;br /&gt;
string  STRING_GROUP=&amp;quot;GROUP&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Links messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
integer MSG_MESSAGE_NOTIFY              = 90900;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED            = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR            = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// GetSelfAddress() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
string GetSelfAddress()&lt;br /&gt;
{&lt;br /&gt;
    return (string)llGetKey() + &amp;quot;@&amp;quot; + LSL_DOMAIN;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Info() /////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Info()&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;The mail address for this object is: &amp;quot; &lt;br /&gt;
                    + GetSelfAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// IsValidKeyFormat() //////////////////////&lt;br /&gt;
&lt;br /&gt;
integer IsValidKeyFormat(string str)&lt;br /&gt;
{&lt;br /&gt;
    string keychars = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    if (llStringLength(str) != 36)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    if( (llGetSubString( str, 8, 8 )   != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 13, 13 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 18, 18 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 23, 23 )  != &amp;quot;-&amp;quot; ) )&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 9; i &amp;lt; 13; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 14; i &amp;lt; 18; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 19; i &amp;lt; 23; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 24; i &amp;lt; 36; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// ValidMailAddress() ////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer ValidMailAddress(string arg)&lt;br /&gt;
{&lt;br /&gt;
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));&lt;br /&gt;
    &lt;br /&gt;
    if (adress == &amp;quot;&amp;quot;)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    list parse = llParseStringKeepNulls(adress, [ &amp;quot;@&amp;quot; ], []);&lt;br /&gt;
    string account = llList2String(parse,0);&lt;br /&gt;
    string domain  = llList2String(parse,1);&lt;br /&gt;
    &lt;br /&gt;
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    &lt;br /&gt;
    if (domain == LSL_DOMAIN)&lt;br /&gt;
    {&lt;br /&gt;
        return IsValidKeyFormat(account);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list parsedomain = llParseString2List(domain, [ &amp;quot;.&amp;quot; ], []);&lt;br /&gt;
    &lt;br /&gt;
        if (llGetListLength(parsedomain) &amp;lt; 2)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        &lt;br /&gt;
        integer num = llGetListLength(parsedomain);&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llStringLength(llList2String(parsedomain,i)) &amp;lt; 2)&lt;br /&gt;
            {&lt;br /&gt;
                return FALSE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetAddressStr() ///////////////////&lt;br /&gt;
&lt;br /&gt;
string GetAndCheckAddressStr(string address)&lt;br /&gt;
{&lt;br /&gt;
    list addresslist = llCSV2List(address);&lt;br /&gt;
    integer num=llGetListLength(addresslist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    string addressstr=&amp;quot;&amp;quot;;&lt;br /&gt;
    string curaddress=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        curaddress=llList2String(addresslist,i);&lt;br /&gt;
        &lt;br /&gt;
        if (ValidMailAddress(curaddress))&lt;br /&gt;
        {&lt;br /&gt;
            addressstr = (addressstr=&amp;quot;&amp;quot;) + addressstr + curaddress + &amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address string: &#039;&amp;quot; &lt;br /&gt;
                            + curaddress + &amp;quot;&#039;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return llGetSubString(addressstr, 0, -2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ProcessLine() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
ProcessLine(string rawline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(rawline,STRING_TRIM);&lt;br /&gt;
    string first=llGetSubString(line,0,0);&lt;br /&gt;
    string last=llGetSubString(line,-1,-1);&lt;br /&gt;
    &lt;br /&gt;
    // Ignore a blank line or comment line&lt;br /&gt;
    if (line == &amp;quot;&amp;quot; || first == &amp;quot;#&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // Check for the right section&lt;br /&gt;
    &lt;br /&gt;
    if (first == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; last == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        string sectionstr=llToUpper(llStringTrim(llGetSubString(line,1,-2),STRING_TRIM));&lt;br /&gt;
        &lt;br /&gt;
        if (sectionstr == STRING_ADDRESS_BOOK)&lt;br /&gt;
        {&lt;br /&gt;
            Section = SECTION_ADDRESS_BOOK;&lt;br /&gt;
        }&lt;br /&gt;
        else if (sectionstr == STRING_GROUP)&lt;br /&gt;
        {&lt;br /&gt;
            if (Section == 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                        + &amp;quot;. Group section defined before Address Book section.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Section = SECTION_GROUP;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid section header &#039;&amp;quot; + sectionstr &lt;br /&gt;
                        + &amp;quot;&#039; in &amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Must be in a section&lt;br /&gt;
    &lt;br /&gt;
    if (Section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;. No section header.&amp;quot;, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    list     parse=llParseString2List(line, [ &amp;quot;=&amp;quot; ], []);&lt;br /&gt;
    integer  num=llGetListLength(parse);&lt;br /&gt;
    &lt;br /&gt;
    // Format must be correct&lt;br /&gt;
    &lt;br /&gt;
    if (num != 2)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; +  (string)(Line+1) + &amp;quot;:\n&amp;quot; + rawline, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (Section == SECTION_ADDRESS_BOOK)&lt;br /&gt;
    {&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(name) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + name &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ name ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            string address=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
            string addressstr=GetAndCheckAddressStr(address);&lt;br /&gt;
            &lt;br /&gt;
            if (addressstr != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                AddressBookList     = (AddressBookList=[])     + AddressBookList     + [ name ];&lt;br /&gt;
                MailAddressList     = (MailAddressList=[])     + MailAddressList     + [ addressstr ];&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;No valid mail address for &#039;&amp;quot; + name &lt;br /&gt;
                    + &amp;quot;&#039;. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                    + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name &lt;br /&gt;
                + &amp;quot;&#039; already defined. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // Group&lt;br /&gt;
    {&lt;br /&gt;
        string group=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(group) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + group &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ group ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(GroupList, [ group ]) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                string names=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
                list   namelist=llCSV2List(names);&lt;br /&gt;
                integer num=llGetListLength(namelist);&lt;br /&gt;
                integer i;&lt;br /&gt;
                integer index;&lt;br /&gt;
                string  name;&lt;br /&gt;
                string  namestr=&amp;quot;&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
                for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                    name=llList2String(namelist,i);&lt;br /&gt;
                    index=llListFindList(AddressBookList, [ name ]);&lt;br /&gt;
            &lt;br /&gt;
                    if (index == -1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name + &amp;quot;&#039; defined in Group &#039;&amp;quot; &lt;br /&gt;
                                + group + &amp;quot;&#039; not found in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY); &lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        namestr = (namestr=&amp;quot;&amp;quot;) + namestr + name + &amp;quot;,&amp;quot;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (namestr != &amp;quot;&amp;quot;)&lt;br /&gt;
                {    &lt;br /&gt;
                    namestr=llGetSubString(namestr,0,-2);&lt;br /&gt;
                    GroupList         = (GroupList=[])         + GroupList     + [ group ];&lt;br /&gt;
                    GroupNameList     = (GroupNameList=[])    + GroupNameList + [ namestr ];&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                        + &amp;quot;&#039; has no valid names. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                        + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                    + &amp;quot;&#039; already defined in Group. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                    + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group&lt;br /&gt;
                + &amp;quot;&#039; already defined in Address Book. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// GetGroupAddressList ///////////////&lt;br /&gt;
&lt;br /&gt;
string GetGroupAddressList(string group)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(GroupList, [ group ]);&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(GroupList);&lt;br /&gt;
    string  grouplist=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        for (i = index; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2String(GroupList,i) == group)&lt;br /&gt;
            {&lt;br /&gt;
                grouplist = (grouplist=&amp;quot;&amp;quot;) + grouplist + llList2String(GroupNameList,i) + &amp;quot;,&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (grouplist != &amp;quot;&amp;quot;) grouplist=llGetSubString(grouplist,0,-2);   // remove last &amp;quot;,&amp;quot;&lt;br /&gt;
        return grouplist;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// SetMailAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetMailAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ address ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        index=llListFindList(GroupList, [ address ]);&lt;br /&gt;
        &lt;br /&gt;
        if (index == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llToUpper(address) == STRING_SELF)&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = GetSelfAddress();&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if(ValidMailAddress(address))&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = address;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Mail adress &amp;quot; + address &lt;br /&gt;
                            + &amp;quot; : not found in adress book or invalid format.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailAddress = GetGroupAddressList(address);&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        CurrentMailAddress = llList2String(MailAddressList,index);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                        + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string message)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No mail address defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No subject defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list mailaddresslist=llCSV2List(CurrentMailAddress);&lt;br /&gt;
        integer num=llGetListLength(mailaddresslist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(mailaddresslist,i);&lt;br /&gt;
            llEmail(address, CurrentMailSubject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMailHome() ////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMailHome(string message, string subject)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, STRING_HOME &lt;br /&gt;
                + &amp;quot; not set. Set your home adress with @HOME &amp;lt;address&amp;gt;.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        string homeaddress=llList2String(AddressBookList,index);&lt;br /&gt;
        list   homelist=llCSV2List(homeaddress);&lt;br /&gt;
        integer num=llGetListLength(homelist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(homelist,i);&lt;br /&gt;
            llEmail(address, subject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
string GetHomeAddress()&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;not set&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2String(MailAddressList,index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetHomeAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        AddressBookList     = (AddressBookList=[]) + [ STRING_HOME ] + AddressBookList;&lt;br /&gt;
        MailAddressList     = (MailAddressList=[]) + [ GetAndCheckAddressStr(address) ]  + MailAddressList;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MailAddressList = llListReplaceList(MailAddressList, [ GetAndCheckAddressStr(address) ], index, index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        Line=0;&lt;br /&gt;
        Section=0;&lt;br /&gt;
        llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// dataserver() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqAddressBook)&lt;br /&gt;
        {&lt;br /&gt;
            reqAddressBook = NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                ProcessLine(data);&lt;br /&gt;
                reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Address Book loaded.&amp;quot;, NULL_KEY);&lt;br /&gt;
                state running;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// timer() ///////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_ERROR, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Could not read Address Book: &amp;quot; &lt;br /&gt;
                            + ADDRESSBOOK_NOTECARD + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// link_message() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_MESSAGE_GETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is empty.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailSubject = message;&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is empty.&amp;quot;, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            SetMailAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Body of message to send is empty. &amp;quot; &lt;br /&gt;
                                +  &amp;quot;No mail is send.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SENDHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SendMailHome(message, (string)id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetInventoryType(message) == INVENTORY_NOTECARD)&lt;br /&gt;
            {&lt;br /&gt;
                Notecard2Fetch = message;                &lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_READ, message, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + message + &amp;quot; not found.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_NOTECARD_FETCHED)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + Notecard2Fetch &lt;br /&gt;
                            + &amp;quot; was empty or could not be read.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Home address is: &amp;quot; + GetHomeAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SetHomeAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_INFO)&lt;br /&gt;
        {&lt;br /&gt;
            Info();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
// End SL Mail AddressBook V1.2.lsl&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail FetchNotecard V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch the contents of a notecard and return it via link message as a string.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Notecard&lt;br /&gt;
&lt;br /&gt;
integer Line=0;&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
key     reqNotecard=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=10.0;&lt;br /&gt;
integer Fetched=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Lines&lt;br /&gt;
&lt;br /&gt;
list LineList=[];&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    /////////////////////// dataserver() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqNotecard)&lt;br /&gt;
        {&lt;br /&gt;
            reqNotecard=NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                LineList = (LineList=[]) + LineList + [ data ];&lt;br /&gt;
                reqNotecard = llGetNotecardLine(Notecard2Fetch, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Fetched=TRUE;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, llDumpList2String(LineList, &amp;quot;\n&amp;quot;), NULL_KEY);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /////////////////////// timer() ///////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        if (!Fetched)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            llSetTimerEvent(0.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer send, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_NOTECARD_READ)&lt;br /&gt;
        {&lt;br /&gt;
            Line=0;&lt;br /&gt;
            Notecard2Fetch=message;&lt;br /&gt;
            LineList=[];&lt;br /&gt;
            Fetched=FALSE;&lt;br /&gt;
            reqNotecard=llGetNotecardLine(Notecard2Fetch, Line);&lt;br /&gt;
            llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL OnlineStatus V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch online status of owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Online status&lt;br /&gt;
&lt;br /&gt;
key     reqOnlineStatus=NULL_KEY;&lt;br /&gt;
float   STATUS_INTERVAL=2.0;&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_STATUS_ONLINE       = 30000;&lt;br /&gt;
integer MS_STATUS_OFFLINE       = 30100;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus=llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
        llSetTimerEvent(STATUS_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// dataserver() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqOnlineStatus)&lt;br /&gt;
        {&lt;br /&gt;
            reqOnlineStatus = NULL_KEY;&lt;br /&gt;
        &lt;br /&gt;
            if (data==&amp;quot;1&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_STATUS_ONLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if (data==&amp;quot;0&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MS_STATUS_OFFLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus = llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Help V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Display help information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail Help V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP    = 10000;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Help() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Help()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;HELP for SL Mail V1.2.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;COMMANDS:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HELP               - displays help info.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@INFO               - display mailaddress of this object.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RECORD             - start recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CONTINUE           - continue recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@STOP               - stop recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@IGNORE             - ignore the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SHOW               - show what your recorded.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SEND               - send the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@MAIL &amp;lt;mailadress&amp;gt;  - set the mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SUBJECT subject    - set the mail subject.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LIST               - list messages in mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SELECT &amp;lt;message&amp;gt;   - select message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@READ               - read current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@NEXT               - read next message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@PREV               - read previous message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@FIRST              - read first message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LAST               - read last message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@DELETE             - delete current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CLEAR              - clear the mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@REPLY              - reply to current message.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RESET              - reset the script.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HOME               - set the home mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@OFF                - switch mailbox OFF.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@ON                 - switch mailbox ON.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_HELP)&lt;br /&gt;
        {&lt;br /&gt;
            Help();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail Help V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}&lt;/div&gt;</description>
			<pubDate>Sun, 07 Oct 2007 11:09:39 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:SL_Mail_V1.2</comments>
		</item>
		<item>
			<title>SL Mail V1.2</title>
			<link>https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34588</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34588</guid>
			<description>&lt;p&gt;Flennan Roffo: /* &amp;#039;&amp;#039;&amp;#039;PRODUCTION &amp;amp; MAINTANENCE&amp;#039;&amp;#039;&amp;#039; */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}} __NOTOC__&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=&#039;&#039;&#039;Second Life mail client&#039;&#039;&#039;=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Send and receive email from within Second Life from and to any address.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implemented with Address Book function (in a notecard named &#039;Address Book&#039;) to stores addresses by name  and to compile groups of named addresses. Current version is stand-alone (no server functionality) and uses chat commands only.&lt;br /&gt;
&lt;br /&gt;
[[Image:BannerSLMail.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=Release Notes V1.2=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 Release notes (edition 2, 4 sept 2007)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LICENCE INFO&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is released under GNU free software licence&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;PRODUCTION &amp;amp; MAINTANENCE&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
by Logic Scripted Products and Script Services&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicbanner1.jpg|[http://www.logicscripts.org]]]&lt;br /&gt;
&lt;br /&gt;
SLurl:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Contact: [[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
&lt;br /&gt;
Email: &#039;&#039;&#039;info@slmail.info&#039;&#039;&#039; or &#039;&#039;&#039;Flennan.Roffo@slmail.info&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;DESCRIPTION&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is a simple tool to send and receive mail from within SL.&lt;br /&gt;
You can either compose a message yourself using chat recording, or choose a notecard from inventory to send. The Address Book functionality allows you to use short names for mail recipients stored in a notecard. The current version does not have a persisent mail address. Watch out for the upcoming next release (V1.3) which will facilitate persisent in-world mail addresses and will be enhanced with many new features (See: Requests For Change (RFC).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;COMMANDS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Help&#039;&#039;&#039;&lt;br /&gt;
||Show Help about available commands&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Record&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording (for owner only).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Stop&#039;&#039;&#039;&lt;br /&gt;
||Stops the chat recording without sending&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Continue&#039;&#039;&#039;&lt;br /&gt;
||Continues a previously stopped chat recording. Lines will be appended to you recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Show&#039;&#039;&#039;&lt;br /&gt;
||Shows the content of the recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send&#039;&#039;&#039;&lt;br /&gt;
||If recording, stops the recording, and sends the mail (need to supply mail address and subject first!)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send &amp;lt;notecard&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Sends the content of the notecard, instead of the chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Ignore&#039;&#039;&#039;&lt;br /&gt;
||Ignores your current chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject &amp;lt;subject&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the subject of the mail.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail subject.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Set the HOME address of the owner (mail will be forwarder to this address when offline).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home&#039;&#039;&#039;&lt;br /&gt;
||Show the HOME address.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Info&#039;&#039;&#039;&lt;br /&gt;
||Shows the mail address the object this script is running in uses (e.g. &amp;lt;object-key&amp;gt;@lsl.secondlife.com).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Read&#039;&#039;&#039;&lt;br /&gt;
||Reads the current message from the mail buffer (the mail buffer gets filled with mail you receive)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Select &amp;lt;msg&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Select a message number from the availabe messages in the mail buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Next&#039;&#039;&#039;&lt;br /&gt;
||Make next message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Prev&#039;&#039;&#039;&lt;br /&gt;
||Make previous message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@First&#039;&#039;&#039;&lt;br /&gt;
||Make the first message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Last&#039;&#039;&#039;&lt;br /&gt;
||Make the last message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Clear&#039;&#039;&#039;&lt;br /&gt;
||Clear the mail buffer&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Delete&#039;&#039;&#039;&lt;br /&gt;
||Deletes only the current message&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Reply&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording to reply to the current message. Mail adress and subject are filled in automatically.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* Commands are case insensitive (&amp;quot;@read&amp;quot; == &amp;quot;@READ&amp;quot;). Arguments might not be case insensitive.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;ADDRESS BOOK FORMAT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
A notecard of the name &#039;Address Book&#039; is read during initialization which may contain Address Book items and Groups.&lt;br /&gt;
The notecard is split in two sections, which need to be defined in that particular order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[ADDRESS BOOK]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Defines the section in which you can put names for mail addresses,  like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name1=account@thisdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name2=user@otherdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[GROUP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define groups of previously defined names under a new name, like for instance:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyGroup=Name1, Name2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note that names of groups and individual mail adresses share the same namespace and must be unique.&lt;br /&gt;
&lt;br /&gt;
So when you filled in your mail adresses in the Address Book, you can now use:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail Name1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to  &amp;lt;account@thisdomain.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail MyGroup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to &amp;lt;account@thisdomain.com&amp;gt; and &amp;lt;user@otherdomain.com&amp;gt;&lt;br /&gt;
Mails will be sent one after another.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* Names for Addreses and Groups are case insensitive (e.g. &amp;quot;mary&amp;quot;  == &amp;quot;MARY&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* The special address &#039;Self&#039; can be used in commands where otherwise an address specification can be used. &#039;Self&#039; is case insensitive (e.g. &amp;quot;self&amp;quot; == &amp;quot;SELF&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LIMITATIONS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
The current version is limited by the following:&lt;br /&gt;
&lt;br /&gt;
* Chat recording lines are limited by the 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Output of lines from the mail buffer are also limited by this 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Incoming mail is limited to a 1000 (1024?) byte limit&lt;br /&gt;
&lt;br /&gt;
* Outgoing mai is limited by a 4096 byte limit, which includes the standard mail header (region/location info on the first two lines)&lt;br /&gt;
&lt;br /&gt;
We are making adjustments to this release to help overcome these limitations. At least the line lenght limit can be overcome by introducing a line continuation character (for example a hyphen &#039;-&#039;) that when used at the end of a line appends the next line, so lines longer then 255 bytes are possible then.&lt;br /&gt;
&lt;br /&gt;
To overcome the outgoing mail length limit, the mail can be broken textualy into parts, and each part can be send seperatedely, with an indication in the subject or in an introduced primary line of the mail body to indicate that the mail was split into parts.&lt;br /&gt;
For incoming mail and at least to receive mail from other SL Mail programs, a protocol will be introduced to receive mail in parts that are joined together after receiving them to form a single mail.&lt;br /&gt;
&lt;br /&gt;
These enhancements will be made available in the next release (V1.3) of SL Mail &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;BUGS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Report any bugs you find in this release to Logic (IM: Flennan Roffo).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;REQUEST FOR CHANGE (RFC)&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Do you have additional wishes for enhancement of this product?&lt;br /&gt;
Contact Flennan Roffo and we will see if they can be implemented in the next release.&lt;br /&gt;
&lt;br /&gt;
Existing RFC&#039;s are:&lt;br /&gt;
&lt;br /&gt;
* Menu support for commands.&lt;br /&gt;
&lt;br /&gt;
* Lines on incoming/outgoing mail longer than 255 bytes.&lt;br /&gt;
&lt;br /&gt;
* Send messages longer than 4096 (minus SL mail header) bytes.&lt;br /&gt;
&lt;br /&gt;
* Receive messages longer than 1024 bytes.&lt;br /&gt;
&lt;br /&gt;
* Permanent mail addresses for the SL Mail client (like: &amp;lt;Flennan.Roffo@somedomain.sl&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Add your RFC!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In-world join the group &amp;quot;SL Mail&amp;quot; for bug reports, feature requests, the latest SL Mail release, and notices about development issues.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scripts=&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==Script: SL Mail v1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail core module which scans for incoming mail messages and executes commands used by the owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail V1.2.lsl&lt;br /&gt;
// (c) 2007 Logic Scripted Products and Script Services&lt;br /&gt;
// Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
// VERSION&lt;br /&gt;
// Version: 1.2&lt;br /&gt;
&lt;br /&gt;
// HISTORY&lt;br /&gt;
// Date         Version     Author              Comment&lt;br /&gt;
// --------------------------------------------------------------------------------------&lt;br /&gt;
// 28 aug 2007  V 1.0       Flennan Roffo       Created&lt;br /&gt;
//&lt;br /&gt;
//  1 sep 2007  V 1.1       Flennan Roffo       @Reply empties the recording buffer.&lt;br /&gt;
//                                                @Send while recording ends recording&lt;br /&gt;
//                                                and sends the mail if a mail address&lt;br /&gt;
//                                                and subject are supplied.&lt;br /&gt;
//                                                Fixed incorrect date in Unix2DateTime.&lt;br /&gt;
//  3 sep 2007  V 1.2       Flennan Roffo       Notification options:&lt;br /&gt;
//                                              - When online, send an IM when mail is received.&lt;br /&gt;
//                                              - When offline, send to HOME mail adress.&lt;br /&gt;
//                                              Adressbook&lt;br /&gt;
//                                              - Read adress book from config notecard.&lt;br /&gt;
&lt;br /&gt;
// LICENCE&lt;br /&gt;
// This program is free software; you can redistribute it and/or&lt;br /&gt;
// modify it under the terms of the GNU General Public License&lt;br /&gt;
// as published by the Free Software Foundation; either version 2&lt;br /&gt;
// of the License, or (at your option) any later version.&lt;br /&gt;
// &lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
// &lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program; if not, write to the Free Software&lt;br /&gt;
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
// (Also available at http://www.gnu.org/copyleft/gpl.html) &lt;br /&gt;
&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// Let&#039;s you record a message and sent to email and get messages and reply to messages.&lt;br /&gt;
// Must supply a valid mail adress and non-empty subject using chat commands.&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
// 1) Check for the maximum length of an email message (including newline and header).&lt;br /&gt;
// 2) Read adress book from notecard.                                    *DONE*&lt;br /&gt;
// 3) Send incoming mail to personal mail adress when offline.            *DONE*&lt;br /&gt;
// 4) Alert with an IM when online upon receiving new mail.                *DONE*&lt;br /&gt;
&lt;br /&gt;
string   SL_MAIL_VERSION = &amp;quot;V 1.2&amp;quot;;&lt;br /&gt;
string   SL_MAIL_DATE    = &amp;quot; 2 sep 2007&amp;quot;;&lt;br /&gt;
integer  ErrorFlag         = FALSE;&lt;br /&gt;
list     ScriptList        = [ &amp;quot;SL Mail Help V1.2&amp;quot;, &amp;quot;SL Mail AddressBook V1.2&amp;quot;, &lt;br /&gt;
                                &amp;quot;SL Mail OnlineStatus V1.2&amp;quot;, &amp;quot;SL Mail FetchNotecard V1.2&amp;quot; ];    &lt;br /&gt;
string   LSL_DOMAIN=&amp;quot;lsl.secondlife.com&amp;quot;; &lt;br /&gt;
integer  StatusOnline=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Commands&lt;br /&gt;
&lt;br /&gt;
string  COMMAND_RECORD     = &amp;quot;@RECORD&amp;quot;;&lt;br /&gt;
string  COMMAND_CONTINUE   = &amp;quot;@CONTINUE&amp;quot;;&lt;br /&gt;
string  COMMAND_STOP       = &amp;quot;@STOP&amp;quot;;&lt;br /&gt;
string  COMMAND_MAIL       = &amp;quot;@MAIL&amp;quot;;&lt;br /&gt;
string  COMMAND_SUBJECT    = &amp;quot;@SUBJECT&amp;quot;;&lt;br /&gt;
string  COMMAND_SEND       = &amp;quot;@SEND&amp;quot;;&lt;br /&gt;
string  COMMAND_SEE        = &amp;quot;@SEE&amp;quot;;&lt;br /&gt;
string  COMMAND_IGNORE     = &amp;quot;@IGNORE&amp;quot;;&lt;br /&gt;
string  COMMAND_READ       = &amp;quot;@READ&amp;quot;;&lt;br /&gt;
string  COMMAND_DELETE     = &amp;quot;@DELETE&amp;quot;;&lt;br /&gt;
string  COMMAND_CLEAR      = &amp;quot;@CLEAR&amp;quot;;&lt;br /&gt;
string  COMMAND_REPLY      = &amp;quot;@REPLY&amp;quot;;&lt;br /&gt;
string  COMMAND_NEXT       = &amp;quot;@NEXT&amp;quot;;&lt;br /&gt;
string  COMMAND_PREV       = &amp;quot;@PREV&amp;quot;;&lt;br /&gt;
string  COMMAND_FIRST      = &amp;quot;@FIRST&amp;quot;;&lt;br /&gt;
string  COMMAND_LAST       = &amp;quot;@LAST&amp;quot;;&lt;br /&gt;
string  COMMAND_LIST       = &amp;quot;@LIST&amp;quot;;&lt;br /&gt;
string  COMMAND_SELECT     = &amp;quot;@SELECT&amp;quot;;&lt;br /&gt;
string  COMMAND_HELP       = &amp;quot;@HELP&amp;quot;;&lt;br /&gt;
string  COMMAND_INFO       = &amp;quot;@INFO&amp;quot;;&lt;br /&gt;
string  COMMAND_RESET      = &amp;quot;@RESET&amp;quot;;&lt;br /&gt;
string  COMMAND_SHOW       = &amp;quot;@SHOW&amp;quot;;&lt;br /&gt;
string  COMMAND_ON         = &amp;quot;@ON&amp;quot;;&lt;br /&gt;
string  COMMAND_OFF        = &amp;quot;@OFF&amp;quot;;&lt;br /&gt;
string  COMMAND_HOME       = &amp;quot;@HOME&amp;quot;;&lt;br /&gt;
string  COMMAND_LOAD       = &amp;quot;@LOAD&amp;quot;;&lt;br /&gt;
string  COMMAND_ADDRESS    = &amp;quot;@ADDRESS&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Recording&lt;br /&gt;
&lt;br /&gt;
integer Recording = FALSE;&lt;br /&gt;
&lt;br /&gt;
list    ChatRecording=[];&lt;br /&gt;
integer NumLines=0;&lt;br /&gt;
integer Length=0;&lt;br /&gt;
&lt;br /&gt;
list     TimeList=[];&lt;br /&gt;
list     AddressList=[];&lt;br /&gt;
list     SubjectList=[];&lt;br /&gt;
list     BodyList=[];&lt;br /&gt;
integer  NumMessages=0;&lt;br /&gt;
integer  CurrentMessage=-1;&lt;br /&gt;
&lt;br /&gt;
float    MAIL_FETCH_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
// Link Messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP                        = 10000;&lt;br /&gt;
integer MSG_STATUS_ONLINE               = 30000;&lt;br /&gt;
integer MSG_STATUS_OFFLINE              = 30100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED          = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR           = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Unix Time conversion //////////////////&lt;br /&gt;
&lt;br /&gt;
integer DAYS_PER_YEAR        = 365;                // Non leap year&lt;br /&gt;
integer SECONDS_PER_YEAR     = 31536000;          // Non leap year&lt;br /&gt;
integer SECONDS_PER_DAY      = 86400;&lt;br /&gt;
integer SECONDS_PER_HOUR     = 3600;&lt;br /&gt;
integer SECONDS_PER_MINUTE   = 60;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// LeapYear() /////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer LeapYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (year % 4 == 0)&lt;br /&gt;
    {&lt;br /&gt;
        if (year % 100 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (year % 400 == 0)&lt;br /&gt;
            {&lt;br /&gt;
                return 1;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// DaysPerMonth() ///////////////////////////////////////&lt;br /&gt;
                &lt;br /&gt;
integer DaysPerMonth(integer year,integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;lt; 8)&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (month == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if (LeapYear(year))&lt;br /&gt;
                {&lt;br /&gt;
                    return 29;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    return 28;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 30;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 30;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////// DaysPerYear() ////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DaysPerYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (LeapYear(year))&lt;br /&gt;
        return DAYS_PER_YEAR + 1;&lt;br /&gt;
    else&lt;br /&gt;
        return DAYS_PER_YEAR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Unix2DataTime() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list Unix2DateTime(integer unixtime)&lt;br /&gt;
{&lt;br /&gt;
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;&lt;br /&gt;
    integer day = days_since_1_1_1970 + 1;&lt;br /&gt;
    integer year  = 1970;&lt;br /&gt;
    integer days_per_year = DaysPerYear(year);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_year)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_year;&lt;br /&gt;
        ++year;&lt;br /&gt;
        days_per_year = DaysPerYear(year);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer month = 1;&lt;br /&gt;
    integer days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_month)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_month;&lt;br /&gt;
        &lt;br /&gt;
        if (++month &amp;gt; 12)&lt;br /&gt;
        {    &lt;br /&gt;
            ++year;&lt;br /&gt;
            month = 1;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;&lt;br /&gt;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;&lt;br /&gt;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;&lt;br /&gt;
    integer minute      = second / SECONDS_PER_MINUTE;&lt;br /&gt;
    second               = second % SECONDS_PER_MINUTE;&lt;br /&gt;
    &lt;br /&gt;
    return [ year, month, day, hour, minute, second ];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// MonthName() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list MonthNameList = [     &amp;quot;JAN&amp;quot;, &amp;quot;FEB&amp;quot;, &amp;quot;MAR&amp;quot;, &amp;quot;APR&amp;quot;, &amp;quot;MAY&amp;quot;, &amp;quot;JUN&amp;quot;, &lt;br /&gt;
                        &amp;quot;JUL&amp;quot;, &amp;quot;AUG&amp;quot;, &amp;quot;SEP&amp;quot;, &amp;quot;OCT&amp;quot; , &amp;quot;NOV&amp;quot;, &amp;quot;DEC&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
string MonthName(integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;gt;= 0 &amp;amp;&amp;amp; month &amp;lt; 12)&lt;br /&gt;
        return llList2String(MonthNameList, month);&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// DateString() ///////////////////////////&lt;br /&gt;
&lt;br /&gt;
string DateString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer year       = llList2Integer(timelist,0);&lt;br /&gt;
    integer month      = llList2Integer(timelist,1);&lt;br /&gt;
    integer day        = llList2Integer(timelist,2);&lt;br /&gt;
    &lt;br /&gt;
    return (string)day + &amp;quot;-&amp;quot; + MonthName(month - 1) + &amp;quot;-&amp;quot; + (string)year;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// TimeString() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string TimeString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer hour          = llList2Integer(timelist,3);&lt;br /&gt;
    integer minute         = llList2Integer(timelist,4);&lt;br /&gt;
    integer second         = llList2Integer(timelist,5);&lt;br /&gt;
    string  hourstr     = (string)hour;&lt;br /&gt;
    string  minutestr   = (string)minute;&lt;br /&gt;
    string  secondstr   = (string)second;&lt;br /&gt;
    &lt;br /&gt;
    if (hour &amp;lt; 10)         hourstr     = &amp;quot;0&amp;quot; + hourstr;&lt;br /&gt;
    if (minute &amp;lt; 10)     minutestr     = &amp;quot;0&amp;quot; + minutestr;&lt;br /&gt;
    if (second &amp;lt; 10)    secondstr    = &amp;quot;0&amp;quot; + secondstr;&lt;br /&gt;
    return hourstr + &amp;quot;:&amp;quot; + minutestr + &amp;quot;:&amp;quot; + secondstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() /////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string body)&lt;br /&gt;
{&lt;br /&gt;
    // llOwnerSay(&amp;quot;Sending message to &#039;&amp;quot; + address + &amp;quot;&#039; with subject &#039;&amp;quot; + subject +&amp;quot;&#039;.&amp;quot;);&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND, body, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// SendHome() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendHome(string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SENDHOME, body, (key)subject);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Show() ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Show()&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;Current chat recording is:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; NumLines; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(ChatRecording,i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;Lines is &amp;quot; + (string)NumLines);&lt;br /&gt;
    llOwnerSay(&amp;quot;Message length is &amp;quot; + (string)Length);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Read() /////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Read()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;Reading message &amp;quot; + (string)CurrentMessage + &amp;quot; from mail buffer.&amp;quot;);&lt;br /&gt;
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);&lt;br /&gt;
    list timelist=Unix2DateTime(time);&lt;br /&gt;
    string Address = llList2String(AddressList,CurrentMessage);&lt;br /&gt;
    string Subject = llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
    string Body    = llList2String(BodyList,CurrentMessage);&lt;br /&gt;
    llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Address: &amp;quot; + Address);&lt;br /&gt;
    llOwnerSay(&amp;quot;Subject: &amp;quot; + Subject);&lt;br /&gt;
    llOwnerSay(&amp;quot;Begin of message body:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    list bodylist=llParseStringKeepNulls(Body, [ &amp;quot;\n&amp;quot; ], []);&lt;br /&gt;
    integer num=llGetListLength(bodylist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(bodylist,i));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;End of message body.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////// List ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
List()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;The mail buffer contains the following messages:\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; NumMessages; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer time=llList2Integer(TimeList,i);&lt;br /&gt;
        list timelist=Unix2DateTime(time);&lt;br /&gt;
        if (i &amp;gt; 0) llOwnerSay(&amp;quot;+-+-+-+-+-+-+-+-+-+-+-+-&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Message: &amp;quot; + (string)i);&lt;br /&gt;
        llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;From:    &amp;quot; + llList2String(AddressList,i));&lt;br /&gt;
        llOwnerSay(&amp;quot;Subject: &amp;quot; + llList2String(SubjectList,i));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////// NotifyNewMail() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
NotifyNewMail(string time, string address, string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    list timelist=Unix2DateTime((integer)time);&lt;br /&gt;
&lt;br /&gt;
    if (StatusOnline)&lt;br /&gt;
    {&lt;br /&gt;
        llInstantMessage(llGetOwner(), &amp;quot;You received a new mail message on &amp;quot; &lt;br /&gt;
                                    + DateString(timelist) + &amp;quot; at &amp;quot; + TimeString(timelist)&lt;br /&gt;
                                    + &amp;quot; from &amp;quot; + address &lt;br /&gt;
                                    + &amp;quot; with the subject &amp;quot; + subject);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        SendHome(&amp;quot;FW: &amp;quot; + subject, &amp;quot;Received at: &amp;quot; + DateString(timelist) + &amp;quot; &amp;quot; + TimeString(timelist) + &amp;quot;\nFrom: &amp;quot; +  address &lt;br /&gt;
                    + &amp;quot;\nBegin message body:\n-------------------\n&amp;quot; + body + &amp;quot;\n-------------------\nEnd message body.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ResetOtherScripts() //////////////////////&lt;br /&gt;
&lt;br /&gt;
ResetOtherScripts()&lt;br /&gt;
{&lt;br /&gt;
    string     name;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(ScriptList);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        name = llList2String(ScriptList,i);&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(name) == INVENTORY_SCRIPT)&lt;br /&gt;
        {&lt;br /&gt;
            llResetOtherScript(name);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Error - script &#039;&amp;quot; + name + &amp;quot;&#039; not found.&amp;quot;);&lt;br /&gt;
            ErrorFlag = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
// default &lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ////////////////////// state_entry() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Welcome to SL Mail, released under GNU software licence.&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Version &amp;quot; + SL_MAIL_VERSION + &amp;quot; &amp;quot; + SL_MAIL_DATE);&lt;br /&gt;
        llOwnerSay(&amp;quot;Produced by Logic Scripted Products &amp;amp; Product Services&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Free memory: &amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
        ResetOtherScripts();&lt;br /&gt;
        &lt;br /&gt;
        if (ErrorFlag)&lt;br /&gt;
            state Error;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// on_rez() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// changed() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_LOADED)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_ERROR)&lt;br /&gt;
        {&lt;br /&gt;
            state Error;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() //////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(MAIL_FETCH_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //////////////////////// on_rez() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// listen() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string trimmessage=llStringTrim(message,STRING_TRIM);&lt;br /&gt;
        list   parse = llParseStringKeepNulls(trimmessage, [ &amp;quot; &amp;quot;], []);&lt;br /&gt;
        string command = llToUpper(llList2String(parse,0));&lt;br /&gt;
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        integer nargs  = llGetListLength(parse);&lt;br /&gt;
        string argstr=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (nargs &amp;gt; 1) argstr=llGetSubString(message, llSubStringIndex(message, &amp;quot; &amp;quot;) + 1, -1);&lt;br /&gt;
            &lt;br /&gt;
        if (Recording)&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Recording stopped. Type @SHOW to see the message you have entered,&amp;quot;&lt;br /&gt;
                            + &amp;quot; or @SEND to send it.&amp;quot;);&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                &lt;br /&gt;
                SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];&lt;br /&gt;
                ++NumLines;&lt;br /&gt;
                Length += llStringLength(message) + 2;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_RECORD)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Start recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                ChatRecording = [];&lt;br /&gt;
                NumLines=0;&lt;br /&gt;
                Length=0;&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CONTINUE)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Continue recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_REPLY)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    string address=llList2String(AddressList,CurrentMessage);&lt;br /&gt;
                    string subject=&amp;quot;Re: &amp;quot; + llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, address, NULL_KEY);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, subject, NULL_KEY);&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines=0;&lt;br /&gt;
                    Length=0;&lt;br /&gt;
                    Recording = TRUE;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_MAIL)&lt;br /&gt;
            {&lt;br /&gt;
                string mailaddress=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailaddress != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, mailaddress, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETADDRESS, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SUBJECT)&lt;br /&gt;
            {&lt;br /&gt;
                string mailsubject=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailsubject != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, mailsubject, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETSUBJECT, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Not recording.&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    if (NumLines == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND_NOTECARD, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_IGNORE)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines = 0;&lt;br /&gt;
                    Length = 0;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Show();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_READ)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumMessages == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Read();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        ++CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        --CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_FIRST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = 0;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LAST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LIST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    List();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SELECT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;Need to supply a message number.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    integer msgnum = (integer)arg;&lt;br /&gt;
                     &lt;br /&gt;
                    if (msgnum &amp;lt; 0 || msgnum &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Message number &amp;quot; + arg + &amp;quot; not in mail buffer.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = msgnum;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_DELETE)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    --NumMessages;&lt;br /&gt;
                     &lt;br /&gt;
                    if (NumMessages == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = -1;&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (CurrentMessage &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CLEAR)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList=[];&lt;br /&gt;
                    AddressList=[];&lt;br /&gt;
                    SubjectList=[];&lt;br /&gt;
                    BodyList=[];&lt;br /&gt;
                    NumMessages=0;&lt;br /&gt;
                    CurrentMessage=-1;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_HELP, arg, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_INFO)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                Show();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_RESET)&lt;br /&gt;
            {&lt;br /&gt;
                llResetScript();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                state not_running;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HOME)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs==1)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETHOME, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETHOME, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// email() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    email(string time, string address, string subject, string body, integer queued)&lt;br /&gt;
    {&lt;br /&gt;
        NotifyNewMail(time, address, subject, body);&lt;br /&gt;
        TimeList = (TimeList=[]) + TimeList + [time];&lt;br /&gt;
        AddressList = (AddressList=[]) + AddressList + [address];&lt;br /&gt;
        SubjectList = (SubjectList=[]) + SubjectList + [subject];&lt;br /&gt;
        BodyList = (BodyList=[]) + BodyList + [body];&lt;br /&gt;
        ++NumMessages;&lt;br /&gt;
        &lt;br /&gt;
        if (CurrentMessage == -1)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = NumMessages - 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_REPLY)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state not_running&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state not_running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;SL Mailbox switched OFF. Say @ON to switch it back on.&amp;quot;);&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// on_rez() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// listen() ////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer chan, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string command=llToUpper(message);&lt;br /&gt;
        &lt;br /&gt;
        if (command == COMMAND_ON)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state Error&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state Error&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Error in SL Mail: not all component scripts found.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// End SL Mail V1.2.lsl&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Address Book V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Read and interpret the contents of the Address Book.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail AddressBook V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// &lt;br /&gt;
//  Read the Address Book from a notecard named &amp;quot;Address Book&amp;quot;.&lt;br /&gt;
//&lt;br /&gt;
//  The Address Book has the following format:&lt;br /&gt;
//  &lt;br /&gt;
//  [ADDRESS BOOK]&lt;br /&gt;
//  Name1=username@yourdomain.com&lt;br /&gt;
//  Name2=otheruser@otherdomain.com&lt;br /&gt;
//  ...&lt;br /&gt;
//  [GROUP]&lt;br /&gt;
//  group1=Name1, Name2&lt;br /&gt;
//  ...&lt;br /&gt;
//&lt;br /&gt;
//  Notes:&lt;br /&gt;
//  1. Group and Name share the same namespace, and must be unique.&lt;br /&gt;
//  2. It is allowed to have a name in the addressbook with multiple addresses, seperated by comma&#039;s.&lt;br /&gt;
// &lt;br /&gt;
/////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string  CurrentMailAddress = &amp;quot;&amp;quot;;&lt;br /&gt;
string  CurrentMailSubject = &amp;quot;&amp;quot;;&lt;br /&gt;
integer StatusOnline = FALSE;&lt;br /&gt;
&lt;br /&gt;
// Fetch or Send notecard&lt;br /&gt;
&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Names&lt;br /&gt;
&lt;br /&gt;
list    AddressBookList=[];&lt;br /&gt;
list    MailAddressList=[];&lt;br /&gt;
&lt;br /&gt;
string  STRING_HOME=&amp;quot;HOME&amp;quot;;&lt;br /&gt;
string  STRING_SELF=&amp;quot;SELF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Groups&lt;br /&gt;
&lt;br /&gt;
list   GroupList=[];&lt;br /&gt;
list   GroupNameList=[];&lt;br /&gt;
&lt;br /&gt;
string LSL_DOMAIN = &amp;quot;lsl.secondlife.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Read Address Book notecard&lt;br /&gt;
&lt;br /&gt;
string  ADDRESSBOOK_NOTECARD=&amp;quot;Address Book&amp;quot;;&lt;br /&gt;
integer Line=0;&lt;br /&gt;
key     reqAddressBook=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
integer Section=0;&lt;br /&gt;
integer SECTION_ADDRESS_BOOK=1;&lt;br /&gt;
integer SECTION_GROUP=2;&lt;br /&gt;
string  STRING_ADDRESS_BOOK=&amp;quot;ADDRESS BOOK&amp;quot;;&lt;br /&gt;
string  STRING_GROUP=&amp;quot;GROUP&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Links messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
integer MSG_MESSAGE_NOTIFY              = 90900;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED            = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR            = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// GetSelfAddress() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
string GetSelfAddress()&lt;br /&gt;
{&lt;br /&gt;
    return (string)llGetKey() + &amp;quot;@&amp;quot; + LSL_DOMAIN;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Info() /////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Info()&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;The mail address for this object is: &amp;quot; &lt;br /&gt;
                    + GetSelfAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// IsValidKeyFormat() //////////////////////&lt;br /&gt;
&lt;br /&gt;
integer IsValidKeyFormat(string str)&lt;br /&gt;
{&lt;br /&gt;
    string keychars = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    if (llStringLength(str) != 36)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    if( (llGetSubString( str, 8, 8 )   != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 13, 13 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 18, 18 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 23, 23 )  != &amp;quot;-&amp;quot; ) )&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 9; i &amp;lt; 13; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 14; i &amp;lt; 18; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 19; i &amp;lt; 23; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 24; i &amp;lt; 36; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// ValidMailAddress() ////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer ValidMailAddress(string arg)&lt;br /&gt;
{&lt;br /&gt;
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));&lt;br /&gt;
    &lt;br /&gt;
    if (adress == &amp;quot;&amp;quot;)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    list parse = llParseStringKeepNulls(adress, [ &amp;quot;@&amp;quot; ], []);&lt;br /&gt;
    string account = llList2String(parse,0);&lt;br /&gt;
    string domain  = llList2String(parse,1);&lt;br /&gt;
    &lt;br /&gt;
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    &lt;br /&gt;
    if (domain == LSL_DOMAIN)&lt;br /&gt;
    {&lt;br /&gt;
        return IsValidKeyFormat(account);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list parsedomain = llParseString2List(domain, [ &amp;quot;.&amp;quot; ], []);&lt;br /&gt;
    &lt;br /&gt;
        if (llGetListLength(parsedomain) &amp;lt; 2)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        &lt;br /&gt;
        integer num = llGetListLength(parsedomain);&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llStringLength(llList2String(parsedomain,i)) &amp;lt; 2)&lt;br /&gt;
            {&lt;br /&gt;
                return FALSE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetAddressStr() ///////////////////&lt;br /&gt;
&lt;br /&gt;
string GetAndCheckAddressStr(string address)&lt;br /&gt;
{&lt;br /&gt;
    list addresslist = llCSV2List(address);&lt;br /&gt;
    integer num=llGetListLength(addresslist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    string addressstr=&amp;quot;&amp;quot;;&lt;br /&gt;
    string curaddress=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        curaddress=llList2String(addresslist,i);&lt;br /&gt;
        &lt;br /&gt;
        if (ValidMailAddress(curaddress))&lt;br /&gt;
        {&lt;br /&gt;
            addressstr = (addressstr=&amp;quot;&amp;quot;) + addressstr + curaddress + &amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address string: &#039;&amp;quot; &lt;br /&gt;
                            + curaddress + &amp;quot;&#039;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return llGetSubString(addressstr, 0, -2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ProcessLine() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
ProcessLine(string rawline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(rawline,STRING_TRIM);&lt;br /&gt;
    string first=llGetSubString(line,0,0);&lt;br /&gt;
    string last=llGetSubString(line,-1,-1);&lt;br /&gt;
    &lt;br /&gt;
    // Ignore a blank line or comment line&lt;br /&gt;
    if (line == &amp;quot;&amp;quot; || first == &amp;quot;#&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // Check for the right section&lt;br /&gt;
    &lt;br /&gt;
    if (first == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; last == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        string sectionstr=llToUpper(llStringTrim(llGetSubString(line,1,-2),STRING_TRIM));&lt;br /&gt;
        &lt;br /&gt;
        if (sectionstr == STRING_ADDRESS_BOOK)&lt;br /&gt;
        {&lt;br /&gt;
            Section = SECTION_ADDRESS_BOOK;&lt;br /&gt;
        }&lt;br /&gt;
        else if (sectionstr == STRING_GROUP)&lt;br /&gt;
        {&lt;br /&gt;
            if (Section == 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                        + &amp;quot;. Group section defined before Address Book section.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Section = SECTION_GROUP;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid section header &#039;&amp;quot; + sectionstr &lt;br /&gt;
                        + &amp;quot;&#039; in &amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Must be in a section&lt;br /&gt;
    &lt;br /&gt;
    if (Section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;. No section header.&amp;quot;, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    list     parse=llParseString2List(line, [ &amp;quot;=&amp;quot; ], []);&lt;br /&gt;
    integer  num=llGetListLength(parse);&lt;br /&gt;
    &lt;br /&gt;
    // Format must be correct&lt;br /&gt;
    &lt;br /&gt;
    if (num != 2)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; +  (string)(Line+1) + &amp;quot;:\n&amp;quot; + rawline, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (Section == SECTION_ADDRESS_BOOK)&lt;br /&gt;
    {&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(name) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + name &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ name ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            string address=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
            string addressstr=GetAndCheckAddressStr(address);&lt;br /&gt;
            &lt;br /&gt;
            if (addressstr != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                AddressBookList     = (AddressBookList=[])     + AddressBookList     + [ name ];&lt;br /&gt;
                MailAddressList     = (MailAddressList=[])     + MailAddressList     + [ addressstr ];&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;No valid mail address for &#039;&amp;quot; + name &lt;br /&gt;
                    + &amp;quot;&#039;. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                    + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name &lt;br /&gt;
                + &amp;quot;&#039; already defined. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // Group&lt;br /&gt;
    {&lt;br /&gt;
        string group=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(group) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + group &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ group ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(GroupList, [ group ]) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                string names=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
                list   namelist=llCSV2List(names);&lt;br /&gt;
                integer num=llGetListLength(namelist);&lt;br /&gt;
                integer i;&lt;br /&gt;
                integer index;&lt;br /&gt;
                string  name;&lt;br /&gt;
                string  namestr=&amp;quot;&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
                for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                    name=llList2String(namelist,i);&lt;br /&gt;
                    index=llListFindList(AddressBookList, [ name ]);&lt;br /&gt;
            &lt;br /&gt;
                    if (index == -1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name + &amp;quot;&#039; defined in Group &#039;&amp;quot; &lt;br /&gt;
                                + group + &amp;quot;&#039; not found in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY); &lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        namestr = (namestr=&amp;quot;&amp;quot;) + namestr + name + &amp;quot;,&amp;quot;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (namestr != &amp;quot;&amp;quot;)&lt;br /&gt;
                {    &lt;br /&gt;
                    namestr=llGetSubString(namestr,0,-2);&lt;br /&gt;
                    GroupList         = (GroupList=[])         + GroupList     + [ group ];&lt;br /&gt;
                    GroupNameList     = (GroupNameList=[])    + GroupNameList + [ namestr ];&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                        + &amp;quot;&#039; has no valid names. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                        + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                    + &amp;quot;&#039; already defined in Group. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                    + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group&lt;br /&gt;
                + &amp;quot;&#039; already defined in Address Book. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// GetGroupAddressList ///////////////&lt;br /&gt;
&lt;br /&gt;
string GetGroupAddressList(string group)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(GroupList, [ group ]);&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(GroupList);&lt;br /&gt;
    string  grouplist=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        for (i = index; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2String(GroupList,i) == group)&lt;br /&gt;
            {&lt;br /&gt;
                grouplist = (grouplist=&amp;quot;&amp;quot;) + grouplist + llList2String(GroupNameList,i) + &amp;quot;,&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (grouplist != &amp;quot;&amp;quot;) grouplist=llGetSubString(grouplist,0,-2);   // remove last &amp;quot;,&amp;quot;&lt;br /&gt;
        return grouplist;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// SetMailAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetMailAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ address ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        index=llListFindList(GroupList, [ address ]);&lt;br /&gt;
        &lt;br /&gt;
        if (index == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llToUpper(address) == STRING_SELF)&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = GetSelfAddress();&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if(ValidMailAddress(address))&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = address;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Mail adress &amp;quot; + address &lt;br /&gt;
                            + &amp;quot; : not found in adress book or invalid format.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailAddress = GetGroupAddressList(address);&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        CurrentMailAddress = llList2String(MailAddressList,index);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                        + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string message)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No mail address defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No subject defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list mailaddresslist=llCSV2List(CurrentMailAddress);&lt;br /&gt;
        integer num=llGetListLength(mailaddresslist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(mailaddresslist,i);&lt;br /&gt;
            llEmail(address, CurrentMailSubject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMailHome() ////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMailHome(string message, string subject)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, STRING_HOME &lt;br /&gt;
                + &amp;quot; not set. Set your home adress with @HOME &amp;lt;address&amp;gt;.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        string homeaddress=llList2String(AddressBookList,index);&lt;br /&gt;
        list   homelist=llCSV2List(homeaddress);&lt;br /&gt;
        integer num=llGetListLength(homelist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(homelist,i);&lt;br /&gt;
            llEmail(address, subject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
string GetHomeAddress()&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;not set&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2String(MailAddressList,index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetHomeAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        AddressBookList     = (AddressBookList=[]) + [ STRING_HOME ] + AddressBookList;&lt;br /&gt;
        MailAddressList     = (MailAddressList=[]) + [ GetAndCheckAddressStr(address) ]  + MailAddressList;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MailAddressList = llListReplaceList(MailAddressList, [ GetAndCheckAddressStr(address) ], index, index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        Line=0;&lt;br /&gt;
        Section=0;&lt;br /&gt;
        llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// dataserver() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqAddressBook)&lt;br /&gt;
        {&lt;br /&gt;
            reqAddressBook = NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                ProcessLine(data);&lt;br /&gt;
                reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Address Book loaded.&amp;quot;, NULL_KEY);&lt;br /&gt;
                state running;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// timer() ///////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_ERROR, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Could not read Address Book: &amp;quot; &lt;br /&gt;
                            + ADDRESSBOOK_NOTECARD + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// link_message() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_MESSAGE_GETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is empty.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailSubject = message;&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is empty.&amp;quot;, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            SetMailAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Body of message to send is empty. &amp;quot; &lt;br /&gt;
                                +  &amp;quot;No mail is send.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SENDHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SendMailHome(message, (string)id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetInventoryType(message) == INVENTORY_NOTECARD)&lt;br /&gt;
            {&lt;br /&gt;
                Notecard2Fetch = message;                &lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_READ, message, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + message + &amp;quot; not found.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_NOTECARD_FETCHED)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + Notecard2Fetch &lt;br /&gt;
                            + &amp;quot; was empty or could not be read.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Home address is: &amp;quot; + GetHomeAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SetHomeAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_INFO)&lt;br /&gt;
        {&lt;br /&gt;
            Info();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
// End SL Mail AddressBook V1.2.lsl&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail FetchNotecard V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch the contents of a notecard and return it via link message as a string.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Notecard&lt;br /&gt;
&lt;br /&gt;
integer Line=0;&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
key     reqNotecard=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=10.0;&lt;br /&gt;
integer Fetched=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Lines&lt;br /&gt;
&lt;br /&gt;
list LineList=[];&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    /////////////////////// dataserver() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqNotecard)&lt;br /&gt;
        {&lt;br /&gt;
            reqNotecard=NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                LineList = (LineList=[]) + LineList + [ data ];&lt;br /&gt;
                reqNotecard = llGetNotecardLine(Notecard2Fetch, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Fetched=TRUE;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, llDumpList2String(LineList, &amp;quot;\n&amp;quot;), NULL_KEY);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /////////////////////// timer() ///////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        if (!Fetched)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            llSetTimerEvent(0.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer send, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_NOTECARD_READ)&lt;br /&gt;
        {&lt;br /&gt;
            Line=0;&lt;br /&gt;
            Notecard2Fetch=message;&lt;br /&gt;
            LineList=[];&lt;br /&gt;
            Fetched=FALSE;&lt;br /&gt;
            reqNotecard=llGetNotecardLine(Notecard2Fetch, Line);&lt;br /&gt;
            llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL OnlineStatus V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch online status of owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Online status&lt;br /&gt;
&lt;br /&gt;
key     reqOnlineStatus=NULL_KEY;&lt;br /&gt;
float   STATUS_INTERVAL=2.0;&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_STATUS_ONLINE       = 30000;&lt;br /&gt;
integer MS_STATUS_OFFLINE       = 30100;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus=llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
        llSetTimerEvent(STATUS_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// dataserver() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqOnlineStatus)&lt;br /&gt;
        {&lt;br /&gt;
            reqOnlineStatus = NULL_KEY;&lt;br /&gt;
        &lt;br /&gt;
            if (data==&amp;quot;1&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_STATUS_ONLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if (data==&amp;quot;0&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MS_STATUS_OFFLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus = llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Help V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Display help information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail Help V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP    = 10000;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Help() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Help()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;HELP for SL Mail V1.2.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;COMMANDS:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HELP               - displays help info.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@INFO               - display mailaddress of this object.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RECORD             - start recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CONTINUE           - continue recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@STOP               - stop recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@IGNORE             - ignore the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SHOW               - show what your recorded.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SEND               - send the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@MAIL &amp;lt;mailadress&amp;gt;  - set the mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SUBJECT subject    - set the mail subject.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LIST               - list messages in mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SELECT &amp;lt;message&amp;gt;   - select message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@READ               - read current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@NEXT               - read next message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@PREV               - read previous message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@FIRST              - read first message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LAST               - read last message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@DELETE             - delete current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CLEAR              - clear the mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@REPLY              - reply to current message.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RESET              - reset the script.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HOME               - set the home mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@OFF                - switch mailbox OFF.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@ON                 - switch mailbox ON.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_HELP)&lt;br /&gt;
        {&lt;br /&gt;
            Help();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail Help V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}&lt;/div&gt;</description>
			<pubDate>Sun, 07 Oct 2007 10:49:21 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:SL_Mail_V1.2</comments>
		</item>
		<item>
			<title>SL Mail V1.2</title>
			<link>https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34587</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34587</guid>
			<description>&lt;p&gt;Flennan Roffo: /* &amp;#039;&amp;#039;&amp;#039;PRODUCTION &amp;amp; MAINTANENCE&amp;#039;&amp;#039;&amp;#039; */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}} __NOTOC__&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=&#039;&#039;&#039;Second Life mail client&#039;&#039;&#039;=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Send and receive email from within Second Life from and to any address.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implemented with Address Book function (in a notecard named &#039;Address Book&#039;) to stores addresses by name  and to compile groups of named addresses. Current version is stand-alone (no server functionality) and uses chat commands only.&lt;br /&gt;
&lt;br /&gt;
[[Image:BannerSLMail.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=Release Notes V1.2=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 Release notes (edition 2, 4 sept 2007)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LICENCE INFO&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is released under GNU free software licence&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;PRODUCTION &amp;amp; MAINTANENCE&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
by Logic Scripted Products and Script Services&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicbanner1.jpg|http://www.logicscripts.org]]&lt;br /&gt;
&lt;br /&gt;
SLurl:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Contact: [[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
&lt;br /&gt;
Email: &#039;&#039;&#039;info@slmail.info&#039;&#039;&#039; or &#039;&#039;&#039;Flennan.Roffo@slmail.info&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;DESCRIPTION&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is a simple tool to send and receive mail from within SL.&lt;br /&gt;
You can either compose a message yourself using chat recording, or choose a notecard from inventory to send. The Address Book functionality allows you to use short names for mail recipients stored in a notecard. The current version does not have a persisent mail address. Watch out for the upcoming next release (V1.3) which will facilitate persisent in-world mail addresses and will be enhanced with many new features (See: Requests For Change (RFC).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;COMMANDS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Help&#039;&#039;&#039;&lt;br /&gt;
||Show Help about available commands&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Record&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording (for owner only).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Stop&#039;&#039;&#039;&lt;br /&gt;
||Stops the chat recording without sending&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Continue&#039;&#039;&#039;&lt;br /&gt;
||Continues a previously stopped chat recording. Lines will be appended to you recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Show&#039;&#039;&#039;&lt;br /&gt;
||Shows the content of the recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send&#039;&#039;&#039;&lt;br /&gt;
||If recording, stops the recording, and sends the mail (need to supply mail address and subject first!)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send &amp;lt;notecard&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Sends the content of the notecard, instead of the chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Ignore&#039;&#039;&#039;&lt;br /&gt;
||Ignores your current chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject &amp;lt;subject&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the subject of the mail.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail subject.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Set the HOME address of the owner (mail will be forwarder to this address when offline).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home&#039;&#039;&#039;&lt;br /&gt;
||Show the HOME address.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Info&#039;&#039;&#039;&lt;br /&gt;
||Shows the mail address the object this script is running in uses (e.g. &amp;lt;object-key&amp;gt;@lsl.secondlife.com).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Read&#039;&#039;&#039;&lt;br /&gt;
||Reads the current message from the mail buffer (the mail buffer gets filled with mail you receive)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Select &amp;lt;msg&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Select a message number from the availabe messages in the mail buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Next&#039;&#039;&#039;&lt;br /&gt;
||Make next message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Prev&#039;&#039;&#039;&lt;br /&gt;
||Make previous message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@First&#039;&#039;&#039;&lt;br /&gt;
||Make the first message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Last&#039;&#039;&#039;&lt;br /&gt;
||Make the last message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Clear&#039;&#039;&#039;&lt;br /&gt;
||Clear the mail buffer&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Delete&#039;&#039;&#039;&lt;br /&gt;
||Deletes only the current message&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Reply&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording to reply to the current message. Mail adress and subject are filled in automatically.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* Commands are case insensitive (&amp;quot;@read&amp;quot; == &amp;quot;@READ&amp;quot;). Arguments might not be case insensitive.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;ADDRESS BOOK FORMAT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
A notecard of the name &#039;Address Book&#039; is read during initialization which may contain Address Book items and Groups.&lt;br /&gt;
The notecard is split in two sections, which need to be defined in that particular order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[ADDRESS BOOK]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Defines the section in which you can put names for mail addresses,  like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name1=account@thisdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name2=user@otherdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[GROUP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define groups of previously defined names under a new name, like for instance:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyGroup=Name1, Name2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note that names of groups and individual mail adresses share the same namespace and must be unique.&lt;br /&gt;
&lt;br /&gt;
So when you filled in your mail adresses in the Address Book, you can now use:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail Name1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to  &amp;lt;account@thisdomain.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail MyGroup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to &amp;lt;account@thisdomain.com&amp;gt; and &amp;lt;user@otherdomain.com&amp;gt;&lt;br /&gt;
Mails will be sent one after another.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* Names for Addreses and Groups are case insensitive (e.g. &amp;quot;mary&amp;quot;  == &amp;quot;MARY&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* The special address &#039;Self&#039; can be used in commands where otherwise an address specification can be used. &#039;Self&#039; is case insensitive (e.g. &amp;quot;self&amp;quot; == &amp;quot;SELF&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LIMITATIONS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
The current version is limited by the following:&lt;br /&gt;
&lt;br /&gt;
* Chat recording lines are limited by the 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Output of lines from the mail buffer are also limited by this 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Incoming mail is limited to a 1000 (1024?) byte limit&lt;br /&gt;
&lt;br /&gt;
* Outgoing mai is limited by a 4096 byte limit, which includes the standard mail header (region/location info on the first two lines)&lt;br /&gt;
&lt;br /&gt;
We are making adjustments to this release to help overcome these limitations. At least the line lenght limit can be overcome by introducing a line continuation character (for example a hyphen &#039;-&#039;) that when used at the end of a line appends the next line, so lines longer then 255 bytes are possible then.&lt;br /&gt;
&lt;br /&gt;
To overcome the outgoing mail length limit, the mail can be broken textualy into parts, and each part can be send seperatedely, with an indication in the subject or in an introduced primary line of the mail body to indicate that the mail was split into parts.&lt;br /&gt;
For incoming mail and at least to receive mail from other SL Mail programs, a protocol will be introduced to receive mail in parts that are joined together after receiving them to form a single mail.&lt;br /&gt;
&lt;br /&gt;
These enhancements will be made available in the next release (V1.3) of SL Mail &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;BUGS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Report any bugs you find in this release to Logic (IM: Flennan Roffo).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;REQUEST FOR CHANGE (RFC)&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Do you have additional wishes for enhancement of this product?&lt;br /&gt;
Contact Flennan Roffo and we will see if they can be implemented in the next release.&lt;br /&gt;
&lt;br /&gt;
Existing RFC&#039;s are:&lt;br /&gt;
&lt;br /&gt;
* Menu support for commands.&lt;br /&gt;
&lt;br /&gt;
* Lines on incoming/outgoing mail longer than 255 bytes.&lt;br /&gt;
&lt;br /&gt;
* Send messages longer than 4096 (minus SL mail header) bytes.&lt;br /&gt;
&lt;br /&gt;
* Receive messages longer than 1024 bytes.&lt;br /&gt;
&lt;br /&gt;
* Permanent mail addresses for the SL Mail client (like: &amp;lt;Flennan.Roffo@somedomain.sl&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Add your RFC!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In-world join the group &amp;quot;SL Mail&amp;quot; for bug reports, feature requests, the latest SL Mail release, and notices about development issues.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scripts=&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==Script: SL Mail v1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail core module which scans for incoming mail messages and executes commands used by the owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail V1.2.lsl&lt;br /&gt;
// (c) 2007 Logic Scripted Products and Script Services&lt;br /&gt;
// Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
// VERSION&lt;br /&gt;
// Version: 1.2&lt;br /&gt;
&lt;br /&gt;
// HISTORY&lt;br /&gt;
// Date         Version     Author              Comment&lt;br /&gt;
// --------------------------------------------------------------------------------------&lt;br /&gt;
// 28 aug 2007  V 1.0       Flennan Roffo       Created&lt;br /&gt;
//&lt;br /&gt;
//  1 sep 2007  V 1.1       Flennan Roffo       @Reply empties the recording buffer.&lt;br /&gt;
//                                                @Send while recording ends recording&lt;br /&gt;
//                                                and sends the mail if a mail address&lt;br /&gt;
//                                                and subject are supplied.&lt;br /&gt;
//                                                Fixed incorrect date in Unix2DateTime.&lt;br /&gt;
//  3 sep 2007  V 1.2       Flennan Roffo       Notification options:&lt;br /&gt;
//                                              - When online, send an IM when mail is received.&lt;br /&gt;
//                                              - When offline, send to HOME mail adress.&lt;br /&gt;
//                                              Adressbook&lt;br /&gt;
//                                              - Read adress book from config notecard.&lt;br /&gt;
&lt;br /&gt;
// LICENCE&lt;br /&gt;
// This program is free software; you can redistribute it and/or&lt;br /&gt;
// modify it under the terms of the GNU General Public License&lt;br /&gt;
// as published by the Free Software Foundation; either version 2&lt;br /&gt;
// of the License, or (at your option) any later version.&lt;br /&gt;
// &lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
// &lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program; if not, write to the Free Software&lt;br /&gt;
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
// (Also available at http://www.gnu.org/copyleft/gpl.html) &lt;br /&gt;
&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// Let&#039;s you record a message and sent to email and get messages and reply to messages.&lt;br /&gt;
// Must supply a valid mail adress and non-empty subject using chat commands.&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
// 1) Check for the maximum length of an email message (including newline and header).&lt;br /&gt;
// 2) Read adress book from notecard.                                    *DONE*&lt;br /&gt;
// 3) Send incoming mail to personal mail adress when offline.            *DONE*&lt;br /&gt;
// 4) Alert with an IM when online upon receiving new mail.                *DONE*&lt;br /&gt;
&lt;br /&gt;
string   SL_MAIL_VERSION = &amp;quot;V 1.2&amp;quot;;&lt;br /&gt;
string   SL_MAIL_DATE    = &amp;quot; 2 sep 2007&amp;quot;;&lt;br /&gt;
integer  ErrorFlag         = FALSE;&lt;br /&gt;
list     ScriptList        = [ &amp;quot;SL Mail Help V1.2&amp;quot;, &amp;quot;SL Mail AddressBook V1.2&amp;quot;, &lt;br /&gt;
                                &amp;quot;SL Mail OnlineStatus V1.2&amp;quot;, &amp;quot;SL Mail FetchNotecard V1.2&amp;quot; ];    &lt;br /&gt;
string   LSL_DOMAIN=&amp;quot;lsl.secondlife.com&amp;quot;; &lt;br /&gt;
integer  StatusOnline=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Commands&lt;br /&gt;
&lt;br /&gt;
string  COMMAND_RECORD     = &amp;quot;@RECORD&amp;quot;;&lt;br /&gt;
string  COMMAND_CONTINUE   = &amp;quot;@CONTINUE&amp;quot;;&lt;br /&gt;
string  COMMAND_STOP       = &amp;quot;@STOP&amp;quot;;&lt;br /&gt;
string  COMMAND_MAIL       = &amp;quot;@MAIL&amp;quot;;&lt;br /&gt;
string  COMMAND_SUBJECT    = &amp;quot;@SUBJECT&amp;quot;;&lt;br /&gt;
string  COMMAND_SEND       = &amp;quot;@SEND&amp;quot;;&lt;br /&gt;
string  COMMAND_SEE        = &amp;quot;@SEE&amp;quot;;&lt;br /&gt;
string  COMMAND_IGNORE     = &amp;quot;@IGNORE&amp;quot;;&lt;br /&gt;
string  COMMAND_READ       = &amp;quot;@READ&amp;quot;;&lt;br /&gt;
string  COMMAND_DELETE     = &amp;quot;@DELETE&amp;quot;;&lt;br /&gt;
string  COMMAND_CLEAR      = &amp;quot;@CLEAR&amp;quot;;&lt;br /&gt;
string  COMMAND_REPLY      = &amp;quot;@REPLY&amp;quot;;&lt;br /&gt;
string  COMMAND_NEXT       = &amp;quot;@NEXT&amp;quot;;&lt;br /&gt;
string  COMMAND_PREV       = &amp;quot;@PREV&amp;quot;;&lt;br /&gt;
string  COMMAND_FIRST      = &amp;quot;@FIRST&amp;quot;;&lt;br /&gt;
string  COMMAND_LAST       = &amp;quot;@LAST&amp;quot;;&lt;br /&gt;
string  COMMAND_LIST       = &amp;quot;@LIST&amp;quot;;&lt;br /&gt;
string  COMMAND_SELECT     = &amp;quot;@SELECT&amp;quot;;&lt;br /&gt;
string  COMMAND_HELP       = &amp;quot;@HELP&amp;quot;;&lt;br /&gt;
string  COMMAND_INFO       = &amp;quot;@INFO&amp;quot;;&lt;br /&gt;
string  COMMAND_RESET      = &amp;quot;@RESET&amp;quot;;&lt;br /&gt;
string  COMMAND_SHOW       = &amp;quot;@SHOW&amp;quot;;&lt;br /&gt;
string  COMMAND_ON         = &amp;quot;@ON&amp;quot;;&lt;br /&gt;
string  COMMAND_OFF        = &amp;quot;@OFF&amp;quot;;&lt;br /&gt;
string  COMMAND_HOME       = &amp;quot;@HOME&amp;quot;;&lt;br /&gt;
string  COMMAND_LOAD       = &amp;quot;@LOAD&amp;quot;;&lt;br /&gt;
string  COMMAND_ADDRESS    = &amp;quot;@ADDRESS&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Recording&lt;br /&gt;
&lt;br /&gt;
integer Recording = FALSE;&lt;br /&gt;
&lt;br /&gt;
list    ChatRecording=[];&lt;br /&gt;
integer NumLines=0;&lt;br /&gt;
integer Length=0;&lt;br /&gt;
&lt;br /&gt;
list     TimeList=[];&lt;br /&gt;
list     AddressList=[];&lt;br /&gt;
list     SubjectList=[];&lt;br /&gt;
list     BodyList=[];&lt;br /&gt;
integer  NumMessages=0;&lt;br /&gt;
integer  CurrentMessage=-1;&lt;br /&gt;
&lt;br /&gt;
float    MAIL_FETCH_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
// Link Messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP                        = 10000;&lt;br /&gt;
integer MSG_STATUS_ONLINE               = 30000;&lt;br /&gt;
integer MSG_STATUS_OFFLINE              = 30100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED          = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR           = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Unix Time conversion //////////////////&lt;br /&gt;
&lt;br /&gt;
integer DAYS_PER_YEAR        = 365;                // Non leap year&lt;br /&gt;
integer SECONDS_PER_YEAR     = 31536000;          // Non leap year&lt;br /&gt;
integer SECONDS_PER_DAY      = 86400;&lt;br /&gt;
integer SECONDS_PER_HOUR     = 3600;&lt;br /&gt;
integer SECONDS_PER_MINUTE   = 60;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// LeapYear() /////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer LeapYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (year % 4 == 0)&lt;br /&gt;
    {&lt;br /&gt;
        if (year % 100 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (year % 400 == 0)&lt;br /&gt;
            {&lt;br /&gt;
                return 1;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// DaysPerMonth() ///////////////////////////////////////&lt;br /&gt;
                &lt;br /&gt;
integer DaysPerMonth(integer year,integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;lt; 8)&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (month == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if (LeapYear(year))&lt;br /&gt;
                {&lt;br /&gt;
                    return 29;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    return 28;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 30;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 30;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////// DaysPerYear() ////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DaysPerYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (LeapYear(year))&lt;br /&gt;
        return DAYS_PER_YEAR + 1;&lt;br /&gt;
    else&lt;br /&gt;
        return DAYS_PER_YEAR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Unix2DataTime() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list Unix2DateTime(integer unixtime)&lt;br /&gt;
{&lt;br /&gt;
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;&lt;br /&gt;
    integer day = days_since_1_1_1970 + 1;&lt;br /&gt;
    integer year  = 1970;&lt;br /&gt;
    integer days_per_year = DaysPerYear(year);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_year)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_year;&lt;br /&gt;
        ++year;&lt;br /&gt;
        days_per_year = DaysPerYear(year);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer month = 1;&lt;br /&gt;
    integer days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_month)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_month;&lt;br /&gt;
        &lt;br /&gt;
        if (++month &amp;gt; 12)&lt;br /&gt;
        {    &lt;br /&gt;
            ++year;&lt;br /&gt;
            month = 1;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;&lt;br /&gt;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;&lt;br /&gt;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;&lt;br /&gt;
    integer minute      = second / SECONDS_PER_MINUTE;&lt;br /&gt;
    second               = second % SECONDS_PER_MINUTE;&lt;br /&gt;
    &lt;br /&gt;
    return [ year, month, day, hour, minute, second ];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// MonthName() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list MonthNameList = [     &amp;quot;JAN&amp;quot;, &amp;quot;FEB&amp;quot;, &amp;quot;MAR&amp;quot;, &amp;quot;APR&amp;quot;, &amp;quot;MAY&amp;quot;, &amp;quot;JUN&amp;quot;, &lt;br /&gt;
                        &amp;quot;JUL&amp;quot;, &amp;quot;AUG&amp;quot;, &amp;quot;SEP&amp;quot;, &amp;quot;OCT&amp;quot; , &amp;quot;NOV&amp;quot;, &amp;quot;DEC&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
string MonthName(integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;gt;= 0 &amp;amp;&amp;amp; month &amp;lt; 12)&lt;br /&gt;
        return llList2String(MonthNameList, month);&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// DateString() ///////////////////////////&lt;br /&gt;
&lt;br /&gt;
string DateString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer year       = llList2Integer(timelist,0);&lt;br /&gt;
    integer month      = llList2Integer(timelist,1);&lt;br /&gt;
    integer day        = llList2Integer(timelist,2);&lt;br /&gt;
    &lt;br /&gt;
    return (string)day + &amp;quot;-&amp;quot; + MonthName(month - 1) + &amp;quot;-&amp;quot; + (string)year;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// TimeString() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string TimeString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer hour          = llList2Integer(timelist,3);&lt;br /&gt;
    integer minute         = llList2Integer(timelist,4);&lt;br /&gt;
    integer second         = llList2Integer(timelist,5);&lt;br /&gt;
    string  hourstr     = (string)hour;&lt;br /&gt;
    string  minutestr   = (string)minute;&lt;br /&gt;
    string  secondstr   = (string)second;&lt;br /&gt;
    &lt;br /&gt;
    if (hour &amp;lt; 10)         hourstr     = &amp;quot;0&amp;quot; + hourstr;&lt;br /&gt;
    if (minute &amp;lt; 10)     minutestr     = &amp;quot;0&amp;quot; + minutestr;&lt;br /&gt;
    if (second &amp;lt; 10)    secondstr    = &amp;quot;0&amp;quot; + secondstr;&lt;br /&gt;
    return hourstr + &amp;quot;:&amp;quot; + minutestr + &amp;quot;:&amp;quot; + secondstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() /////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string body)&lt;br /&gt;
{&lt;br /&gt;
    // llOwnerSay(&amp;quot;Sending message to &#039;&amp;quot; + address + &amp;quot;&#039; with subject &#039;&amp;quot; + subject +&amp;quot;&#039;.&amp;quot;);&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND, body, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// SendHome() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendHome(string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SENDHOME, body, (key)subject);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Show() ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Show()&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;Current chat recording is:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; NumLines; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(ChatRecording,i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;Lines is &amp;quot; + (string)NumLines);&lt;br /&gt;
    llOwnerSay(&amp;quot;Message length is &amp;quot; + (string)Length);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Read() /////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Read()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;Reading message &amp;quot; + (string)CurrentMessage + &amp;quot; from mail buffer.&amp;quot;);&lt;br /&gt;
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);&lt;br /&gt;
    list timelist=Unix2DateTime(time);&lt;br /&gt;
    string Address = llList2String(AddressList,CurrentMessage);&lt;br /&gt;
    string Subject = llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
    string Body    = llList2String(BodyList,CurrentMessage);&lt;br /&gt;
    llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Address: &amp;quot; + Address);&lt;br /&gt;
    llOwnerSay(&amp;quot;Subject: &amp;quot; + Subject);&lt;br /&gt;
    llOwnerSay(&amp;quot;Begin of message body:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    list bodylist=llParseStringKeepNulls(Body, [ &amp;quot;\n&amp;quot; ], []);&lt;br /&gt;
    integer num=llGetListLength(bodylist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(bodylist,i));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;End of message body.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////// List ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
List()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;The mail buffer contains the following messages:\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; NumMessages; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer time=llList2Integer(TimeList,i);&lt;br /&gt;
        list timelist=Unix2DateTime(time);&lt;br /&gt;
        if (i &amp;gt; 0) llOwnerSay(&amp;quot;+-+-+-+-+-+-+-+-+-+-+-+-&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Message: &amp;quot; + (string)i);&lt;br /&gt;
        llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;From:    &amp;quot; + llList2String(AddressList,i));&lt;br /&gt;
        llOwnerSay(&amp;quot;Subject: &amp;quot; + llList2String(SubjectList,i));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////// NotifyNewMail() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
NotifyNewMail(string time, string address, string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    list timelist=Unix2DateTime((integer)time);&lt;br /&gt;
&lt;br /&gt;
    if (StatusOnline)&lt;br /&gt;
    {&lt;br /&gt;
        llInstantMessage(llGetOwner(), &amp;quot;You received a new mail message on &amp;quot; &lt;br /&gt;
                                    + DateString(timelist) + &amp;quot; at &amp;quot; + TimeString(timelist)&lt;br /&gt;
                                    + &amp;quot; from &amp;quot; + address &lt;br /&gt;
                                    + &amp;quot; with the subject &amp;quot; + subject);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        SendHome(&amp;quot;FW: &amp;quot; + subject, &amp;quot;Received at: &amp;quot; + DateString(timelist) + &amp;quot; &amp;quot; + TimeString(timelist) + &amp;quot;\nFrom: &amp;quot; +  address &lt;br /&gt;
                    + &amp;quot;\nBegin message body:\n-------------------\n&amp;quot; + body + &amp;quot;\n-------------------\nEnd message body.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ResetOtherScripts() //////////////////////&lt;br /&gt;
&lt;br /&gt;
ResetOtherScripts()&lt;br /&gt;
{&lt;br /&gt;
    string     name;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(ScriptList);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        name = llList2String(ScriptList,i);&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(name) == INVENTORY_SCRIPT)&lt;br /&gt;
        {&lt;br /&gt;
            llResetOtherScript(name);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Error - script &#039;&amp;quot; + name + &amp;quot;&#039; not found.&amp;quot;);&lt;br /&gt;
            ErrorFlag = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
// default &lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ////////////////////// state_entry() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Welcome to SL Mail, released under GNU software licence.&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Version &amp;quot; + SL_MAIL_VERSION + &amp;quot; &amp;quot; + SL_MAIL_DATE);&lt;br /&gt;
        llOwnerSay(&amp;quot;Produced by Logic Scripted Products &amp;amp; Product Services&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Free memory: &amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
        ResetOtherScripts();&lt;br /&gt;
        &lt;br /&gt;
        if (ErrorFlag)&lt;br /&gt;
            state Error;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// on_rez() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// changed() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_LOADED)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_ERROR)&lt;br /&gt;
        {&lt;br /&gt;
            state Error;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() //////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(MAIL_FETCH_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //////////////////////// on_rez() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// listen() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string trimmessage=llStringTrim(message,STRING_TRIM);&lt;br /&gt;
        list   parse = llParseStringKeepNulls(trimmessage, [ &amp;quot; &amp;quot;], []);&lt;br /&gt;
        string command = llToUpper(llList2String(parse,0));&lt;br /&gt;
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        integer nargs  = llGetListLength(parse);&lt;br /&gt;
        string argstr=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (nargs &amp;gt; 1) argstr=llGetSubString(message, llSubStringIndex(message, &amp;quot; &amp;quot;) + 1, -1);&lt;br /&gt;
            &lt;br /&gt;
        if (Recording)&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Recording stopped. Type @SHOW to see the message you have entered,&amp;quot;&lt;br /&gt;
                            + &amp;quot; or @SEND to send it.&amp;quot;);&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                &lt;br /&gt;
                SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];&lt;br /&gt;
                ++NumLines;&lt;br /&gt;
                Length += llStringLength(message) + 2;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_RECORD)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Start recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                ChatRecording = [];&lt;br /&gt;
                NumLines=0;&lt;br /&gt;
                Length=0;&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CONTINUE)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Continue recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_REPLY)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    string address=llList2String(AddressList,CurrentMessage);&lt;br /&gt;
                    string subject=&amp;quot;Re: &amp;quot; + llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, address, NULL_KEY);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, subject, NULL_KEY);&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines=0;&lt;br /&gt;
                    Length=0;&lt;br /&gt;
                    Recording = TRUE;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_MAIL)&lt;br /&gt;
            {&lt;br /&gt;
                string mailaddress=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailaddress != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, mailaddress, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETADDRESS, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SUBJECT)&lt;br /&gt;
            {&lt;br /&gt;
                string mailsubject=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailsubject != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, mailsubject, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETSUBJECT, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Not recording.&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    if (NumLines == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND_NOTECARD, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_IGNORE)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines = 0;&lt;br /&gt;
                    Length = 0;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Show();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_READ)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumMessages == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Read();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        ++CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        --CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_FIRST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = 0;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LAST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LIST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    List();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SELECT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;Need to supply a message number.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    integer msgnum = (integer)arg;&lt;br /&gt;
                     &lt;br /&gt;
                    if (msgnum &amp;lt; 0 || msgnum &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Message number &amp;quot; + arg + &amp;quot; not in mail buffer.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = msgnum;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_DELETE)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    --NumMessages;&lt;br /&gt;
                     &lt;br /&gt;
                    if (NumMessages == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = -1;&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (CurrentMessage &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CLEAR)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList=[];&lt;br /&gt;
                    AddressList=[];&lt;br /&gt;
                    SubjectList=[];&lt;br /&gt;
                    BodyList=[];&lt;br /&gt;
                    NumMessages=0;&lt;br /&gt;
                    CurrentMessage=-1;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_HELP, arg, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_INFO)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                Show();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_RESET)&lt;br /&gt;
            {&lt;br /&gt;
                llResetScript();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                state not_running;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HOME)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs==1)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETHOME, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETHOME, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// email() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    email(string time, string address, string subject, string body, integer queued)&lt;br /&gt;
    {&lt;br /&gt;
        NotifyNewMail(time, address, subject, body);&lt;br /&gt;
        TimeList = (TimeList=[]) + TimeList + [time];&lt;br /&gt;
        AddressList = (AddressList=[]) + AddressList + [address];&lt;br /&gt;
        SubjectList = (SubjectList=[]) + SubjectList + [subject];&lt;br /&gt;
        BodyList = (BodyList=[]) + BodyList + [body];&lt;br /&gt;
        ++NumMessages;&lt;br /&gt;
        &lt;br /&gt;
        if (CurrentMessage == -1)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = NumMessages - 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_REPLY)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state not_running&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state not_running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;SL Mailbox switched OFF. Say @ON to switch it back on.&amp;quot;);&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// on_rez() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// listen() ////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer chan, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string command=llToUpper(message);&lt;br /&gt;
        &lt;br /&gt;
        if (command == COMMAND_ON)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state Error&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state Error&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Error in SL Mail: not all component scripts found.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// End SL Mail V1.2.lsl&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Address Book V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Read and interpret the contents of the Address Book.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail AddressBook V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// &lt;br /&gt;
//  Read the Address Book from a notecard named &amp;quot;Address Book&amp;quot;.&lt;br /&gt;
//&lt;br /&gt;
//  The Address Book has the following format:&lt;br /&gt;
//  &lt;br /&gt;
//  [ADDRESS BOOK]&lt;br /&gt;
//  Name1=username@yourdomain.com&lt;br /&gt;
//  Name2=otheruser@otherdomain.com&lt;br /&gt;
//  ...&lt;br /&gt;
//  [GROUP]&lt;br /&gt;
//  group1=Name1, Name2&lt;br /&gt;
//  ...&lt;br /&gt;
//&lt;br /&gt;
//  Notes:&lt;br /&gt;
//  1. Group and Name share the same namespace, and must be unique.&lt;br /&gt;
//  2. It is allowed to have a name in the addressbook with multiple addresses, seperated by comma&#039;s.&lt;br /&gt;
// &lt;br /&gt;
/////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string  CurrentMailAddress = &amp;quot;&amp;quot;;&lt;br /&gt;
string  CurrentMailSubject = &amp;quot;&amp;quot;;&lt;br /&gt;
integer StatusOnline = FALSE;&lt;br /&gt;
&lt;br /&gt;
// Fetch or Send notecard&lt;br /&gt;
&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Names&lt;br /&gt;
&lt;br /&gt;
list    AddressBookList=[];&lt;br /&gt;
list    MailAddressList=[];&lt;br /&gt;
&lt;br /&gt;
string  STRING_HOME=&amp;quot;HOME&amp;quot;;&lt;br /&gt;
string  STRING_SELF=&amp;quot;SELF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Groups&lt;br /&gt;
&lt;br /&gt;
list   GroupList=[];&lt;br /&gt;
list   GroupNameList=[];&lt;br /&gt;
&lt;br /&gt;
string LSL_DOMAIN = &amp;quot;lsl.secondlife.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Read Address Book notecard&lt;br /&gt;
&lt;br /&gt;
string  ADDRESSBOOK_NOTECARD=&amp;quot;Address Book&amp;quot;;&lt;br /&gt;
integer Line=0;&lt;br /&gt;
key     reqAddressBook=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
integer Section=0;&lt;br /&gt;
integer SECTION_ADDRESS_BOOK=1;&lt;br /&gt;
integer SECTION_GROUP=2;&lt;br /&gt;
string  STRING_ADDRESS_BOOK=&amp;quot;ADDRESS BOOK&amp;quot;;&lt;br /&gt;
string  STRING_GROUP=&amp;quot;GROUP&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Links messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
integer MSG_MESSAGE_NOTIFY              = 90900;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED            = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR            = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// GetSelfAddress() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
string GetSelfAddress()&lt;br /&gt;
{&lt;br /&gt;
    return (string)llGetKey() + &amp;quot;@&amp;quot; + LSL_DOMAIN;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Info() /////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Info()&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;The mail address for this object is: &amp;quot; &lt;br /&gt;
                    + GetSelfAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// IsValidKeyFormat() //////////////////////&lt;br /&gt;
&lt;br /&gt;
integer IsValidKeyFormat(string str)&lt;br /&gt;
{&lt;br /&gt;
    string keychars = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    if (llStringLength(str) != 36)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    if( (llGetSubString( str, 8, 8 )   != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 13, 13 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 18, 18 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 23, 23 )  != &amp;quot;-&amp;quot; ) )&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 9; i &amp;lt; 13; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 14; i &amp;lt; 18; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 19; i &amp;lt; 23; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 24; i &amp;lt; 36; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// ValidMailAddress() ////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer ValidMailAddress(string arg)&lt;br /&gt;
{&lt;br /&gt;
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));&lt;br /&gt;
    &lt;br /&gt;
    if (adress == &amp;quot;&amp;quot;)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    list parse = llParseStringKeepNulls(adress, [ &amp;quot;@&amp;quot; ], []);&lt;br /&gt;
    string account = llList2String(parse,0);&lt;br /&gt;
    string domain  = llList2String(parse,1);&lt;br /&gt;
    &lt;br /&gt;
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    &lt;br /&gt;
    if (domain == LSL_DOMAIN)&lt;br /&gt;
    {&lt;br /&gt;
        return IsValidKeyFormat(account);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list parsedomain = llParseString2List(domain, [ &amp;quot;.&amp;quot; ], []);&lt;br /&gt;
    &lt;br /&gt;
        if (llGetListLength(parsedomain) &amp;lt; 2)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        &lt;br /&gt;
        integer num = llGetListLength(parsedomain);&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llStringLength(llList2String(parsedomain,i)) &amp;lt; 2)&lt;br /&gt;
            {&lt;br /&gt;
                return FALSE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetAddressStr() ///////////////////&lt;br /&gt;
&lt;br /&gt;
string GetAndCheckAddressStr(string address)&lt;br /&gt;
{&lt;br /&gt;
    list addresslist = llCSV2List(address);&lt;br /&gt;
    integer num=llGetListLength(addresslist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    string addressstr=&amp;quot;&amp;quot;;&lt;br /&gt;
    string curaddress=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        curaddress=llList2String(addresslist,i);&lt;br /&gt;
        &lt;br /&gt;
        if (ValidMailAddress(curaddress))&lt;br /&gt;
        {&lt;br /&gt;
            addressstr = (addressstr=&amp;quot;&amp;quot;) + addressstr + curaddress + &amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address string: &#039;&amp;quot; &lt;br /&gt;
                            + curaddress + &amp;quot;&#039;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return llGetSubString(addressstr, 0, -2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ProcessLine() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
ProcessLine(string rawline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(rawline,STRING_TRIM);&lt;br /&gt;
    string first=llGetSubString(line,0,0);&lt;br /&gt;
    string last=llGetSubString(line,-1,-1);&lt;br /&gt;
    &lt;br /&gt;
    // Ignore a blank line or comment line&lt;br /&gt;
    if (line == &amp;quot;&amp;quot; || first == &amp;quot;#&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // Check for the right section&lt;br /&gt;
    &lt;br /&gt;
    if (first == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; last == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        string sectionstr=llToUpper(llStringTrim(llGetSubString(line,1,-2),STRING_TRIM));&lt;br /&gt;
        &lt;br /&gt;
        if (sectionstr == STRING_ADDRESS_BOOK)&lt;br /&gt;
        {&lt;br /&gt;
            Section = SECTION_ADDRESS_BOOK;&lt;br /&gt;
        }&lt;br /&gt;
        else if (sectionstr == STRING_GROUP)&lt;br /&gt;
        {&lt;br /&gt;
            if (Section == 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                        + &amp;quot;. Group section defined before Address Book section.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Section = SECTION_GROUP;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid section header &#039;&amp;quot; + sectionstr &lt;br /&gt;
                        + &amp;quot;&#039; in &amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Must be in a section&lt;br /&gt;
    &lt;br /&gt;
    if (Section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;. No section header.&amp;quot;, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    list     parse=llParseString2List(line, [ &amp;quot;=&amp;quot; ], []);&lt;br /&gt;
    integer  num=llGetListLength(parse);&lt;br /&gt;
    &lt;br /&gt;
    // Format must be correct&lt;br /&gt;
    &lt;br /&gt;
    if (num != 2)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; +  (string)(Line+1) + &amp;quot;:\n&amp;quot; + rawline, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (Section == SECTION_ADDRESS_BOOK)&lt;br /&gt;
    {&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(name) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + name &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ name ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            string address=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
            string addressstr=GetAndCheckAddressStr(address);&lt;br /&gt;
            &lt;br /&gt;
            if (addressstr != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                AddressBookList     = (AddressBookList=[])     + AddressBookList     + [ name ];&lt;br /&gt;
                MailAddressList     = (MailAddressList=[])     + MailAddressList     + [ addressstr ];&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;No valid mail address for &#039;&amp;quot; + name &lt;br /&gt;
                    + &amp;quot;&#039;. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                    + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name &lt;br /&gt;
                + &amp;quot;&#039; already defined. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // Group&lt;br /&gt;
    {&lt;br /&gt;
        string group=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(group) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + group &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ group ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(GroupList, [ group ]) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                string names=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
                list   namelist=llCSV2List(names);&lt;br /&gt;
                integer num=llGetListLength(namelist);&lt;br /&gt;
                integer i;&lt;br /&gt;
                integer index;&lt;br /&gt;
                string  name;&lt;br /&gt;
                string  namestr=&amp;quot;&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
                for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                    name=llList2String(namelist,i);&lt;br /&gt;
                    index=llListFindList(AddressBookList, [ name ]);&lt;br /&gt;
            &lt;br /&gt;
                    if (index == -1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name + &amp;quot;&#039; defined in Group &#039;&amp;quot; &lt;br /&gt;
                                + group + &amp;quot;&#039; not found in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY); &lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        namestr = (namestr=&amp;quot;&amp;quot;) + namestr + name + &amp;quot;,&amp;quot;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (namestr != &amp;quot;&amp;quot;)&lt;br /&gt;
                {    &lt;br /&gt;
                    namestr=llGetSubString(namestr,0,-2);&lt;br /&gt;
                    GroupList         = (GroupList=[])         + GroupList     + [ group ];&lt;br /&gt;
                    GroupNameList     = (GroupNameList=[])    + GroupNameList + [ namestr ];&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                        + &amp;quot;&#039; has no valid names. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                        + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                    + &amp;quot;&#039; already defined in Group. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                    + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group&lt;br /&gt;
                + &amp;quot;&#039; already defined in Address Book. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// GetGroupAddressList ///////////////&lt;br /&gt;
&lt;br /&gt;
string GetGroupAddressList(string group)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(GroupList, [ group ]);&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(GroupList);&lt;br /&gt;
    string  grouplist=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        for (i = index; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2String(GroupList,i) == group)&lt;br /&gt;
            {&lt;br /&gt;
                grouplist = (grouplist=&amp;quot;&amp;quot;) + grouplist + llList2String(GroupNameList,i) + &amp;quot;,&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (grouplist != &amp;quot;&amp;quot;) grouplist=llGetSubString(grouplist,0,-2);   // remove last &amp;quot;,&amp;quot;&lt;br /&gt;
        return grouplist;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// SetMailAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetMailAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ address ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        index=llListFindList(GroupList, [ address ]);&lt;br /&gt;
        &lt;br /&gt;
        if (index == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llToUpper(address) == STRING_SELF)&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = GetSelfAddress();&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if(ValidMailAddress(address))&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = address;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Mail adress &amp;quot; + address &lt;br /&gt;
                            + &amp;quot; : not found in adress book or invalid format.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailAddress = GetGroupAddressList(address);&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        CurrentMailAddress = llList2String(MailAddressList,index);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                        + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string message)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No mail address defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No subject defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list mailaddresslist=llCSV2List(CurrentMailAddress);&lt;br /&gt;
        integer num=llGetListLength(mailaddresslist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(mailaddresslist,i);&lt;br /&gt;
            llEmail(address, CurrentMailSubject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMailHome() ////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMailHome(string message, string subject)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, STRING_HOME &lt;br /&gt;
                + &amp;quot; not set. Set your home adress with @HOME &amp;lt;address&amp;gt;.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        string homeaddress=llList2String(AddressBookList,index);&lt;br /&gt;
        list   homelist=llCSV2List(homeaddress);&lt;br /&gt;
        integer num=llGetListLength(homelist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(homelist,i);&lt;br /&gt;
            llEmail(address, subject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
string GetHomeAddress()&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;not set&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2String(MailAddressList,index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetHomeAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        AddressBookList     = (AddressBookList=[]) + [ STRING_HOME ] + AddressBookList;&lt;br /&gt;
        MailAddressList     = (MailAddressList=[]) + [ GetAndCheckAddressStr(address) ]  + MailAddressList;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MailAddressList = llListReplaceList(MailAddressList, [ GetAndCheckAddressStr(address) ], index, index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        Line=0;&lt;br /&gt;
        Section=0;&lt;br /&gt;
        llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// dataserver() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqAddressBook)&lt;br /&gt;
        {&lt;br /&gt;
            reqAddressBook = NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                ProcessLine(data);&lt;br /&gt;
                reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Address Book loaded.&amp;quot;, NULL_KEY);&lt;br /&gt;
                state running;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// timer() ///////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_ERROR, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Could not read Address Book: &amp;quot; &lt;br /&gt;
                            + ADDRESSBOOK_NOTECARD + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// link_message() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_MESSAGE_GETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is empty.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailSubject = message;&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is empty.&amp;quot;, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            SetMailAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Body of message to send is empty. &amp;quot; &lt;br /&gt;
                                +  &amp;quot;No mail is send.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SENDHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SendMailHome(message, (string)id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetInventoryType(message) == INVENTORY_NOTECARD)&lt;br /&gt;
            {&lt;br /&gt;
                Notecard2Fetch = message;                &lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_READ, message, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + message + &amp;quot; not found.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_NOTECARD_FETCHED)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + Notecard2Fetch &lt;br /&gt;
                            + &amp;quot; was empty or could not be read.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Home address is: &amp;quot; + GetHomeAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SetHomeAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_INFO)&lt;br /&gt;
        {&lt;br /&gt;
            Info();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
// End SL Mail AddressBook V1.2.lsl&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail FetchNotecard V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch the contents of a notecard and return it via link message as a string.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Notecard&lt;br /&gt;
&lt;br /&gt;
integer Line=0;&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
key     reqNotecard=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=10.0;&lt;br /&gt;
integer Fetched=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Lines&lt;br /&gt;
&lt;br /&gt;
list LineList=[];&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    /////////////////////// dataserver() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqNotecard)&lt;br /&gt;
        {&lt;br /&gt;
            reqNotecard=NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                LineList = (LineList=[]) + LineList + [ data ];&lt;br /&gt;
                reqNotecard = llGetNotecardLine(Notecard2Fetch, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Fetched=TRUE;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, llDumpList2String(LineList, &amp;quot;\n&amp;quot;), NULL_KEY);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /////////////////////// timer() ///////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        if (!Fetched)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            llSetTimerEvent(0.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer send, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_NOTECARD_READ)&lt;br /&gt;
        {&lt;br /&gt;
            Line=0;&lt;br /&gt;
            Notecard2Fetch=message;&lt;br /&gt;
            LineList=[];&lt;br /&gt;
            Fetched=FALSE;&lt;br /&gt;
            reqNotecard=llGetNotecardLine(Notecard2Fetch, Line);&lt;br /&gt;
            llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL OnlineStatus V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch online status of owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Online status&lt;br /&gt;
&lt;br /&gt;
key     reqOnlineStatus=NULL_KEY;&lt;br /&gt;
float   STATUS_INTERVAL=2.0;&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_STATUS_ONLINE       = 30000;&lt;br /&gt;
integer MS_STATUS_OFFLINE       = 30100;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus=llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
        llSetTimerEvent(STATUS_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// dataserver() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqOnlineStatus)&lt;br /&gt;
        {&lt;br /&gt;
            reqOnlineStatus = NULL_KEY;&lt;br /&gt;
        &lt;br /&gt;
            if (data==&amp;quot;1&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_STATUS_ONLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if (data==&amp;quot;0&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MS_STATUS_OFFLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus = llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Help V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Display help information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail Help V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP    = 10000;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Help() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Help()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;HELP for SL Mail V1.2.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;COMMANDS:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HELP               - displays help info.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@INFO               - display mailaddress of this object.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RECORD             - start recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CONTINUE           - continue recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@STOP               - stop recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@IGNORE             - ignore the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SHOW               - show what your recorded.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SEND               - send the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@MAIL &amp;lt;mailadress&amp;gt;  - set the mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SUBJECT subject    - set the mail subject.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LIST               - list messages in mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SELECT &amp;lt;message&amp;gt;   - select message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@READ               - read current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@NEXT               - read next message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@PREV               - read previous message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@FIRST              - read first message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LAST               - read last message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@DELETE             - delete current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CLEAR              - clear the mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@REPLY              - reply to current message.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RESET              - reset the script.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HOME               - set the home mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@OFF                - switch mailbox OFF.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@ON                 - switch mailbox ON.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_HELP)&lt;br /&gt;
        {&lt;br /&gt;
            Help();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail Help V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}&lt;/div&gt;</description>
			<pubDate>Sun, 07 Oct 2007 10:49:02 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:SL_Mail_V1.2</comments>
		</item>
		<item>
			<title>SL Mail V1.2</title>
			<link>https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34586</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34586</guid>
			<description>&lt;p&gt;Flennan Roffo: /* &amp;#039;&amp;#039;&amp;#039;PRODUCTION &amp;amp; MAINTANENCE&amp;#039;&amp;#039;&amp;#039; */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}} __NOTOC__&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=&#039;&#039;&#039;Second Life mail client&#039;&#039;&#039;=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Send and receive email from within Second Life from and to any address.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implemented with Address Book function (in a notecard named &#039;Address Book&#039;) to stores addresses by name  and to compile groups of named addresses. Current version is stand-alone (no server functionality) and uses chat commands only.&lt;br /&gt;
&lt;br /&gt;
[[Image:BannerSLMail.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=Release Notes V1.2=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 Release notes (edition 2, 4 sept 2007)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LICENCE INFO&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is released under GNU free software licence&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;PRODUCTION &amp;amp; MAINTANENCE&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
by Logic Scripted Products and Script Services&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
SLurl:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Contact: [[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
&lt;br /&gt;
Email: &#039;&#039;&#039;info@slmail.info&#039;&#039;&#039; or &#039;&#039;&#039;Flennan.Roffo@slmail.info&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;DESCRIPTION&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is a simple tool to send and receive mail from within SL.&lt;br /&gt;
You can either compose a message yourself using chat recording, or choose a notecard from inventory to send. The Address Book functionality allows you to use short names for mail recipients stored in a notecard. The current version does not have a persisent mail address. Watch out for the upcoming next release (V1.3) which will facilitate persisent in-world mail addresses and will be enhanced with many new features (See: Requests For Change (RFC).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;COMMANDS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Help&#039;&#039;&#039;&lt;br /&gt;
||Show Help about available commands&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Record&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording (for owner only).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Stop&#039;&#039;&#039;&lt;br /&gt;
||Stops the chat recording without sending&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Continue&#039;&#039;&#039;&lt;br /&gt;
||Continues a previously stopped chat recording. Lines will be appended to you recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Show&#039;&#039;&#039;&lt;br /&gt;
||Shows the content of the recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send&#039;&#039;&#039;&lt;br /&gt;
||If recording, stops the recording, and sends the mail (need to supply mail address and subject first!)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send &amp;lt;notecard&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Sends the content of the notecard, instead of the chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Ignore&#039;&#039;&#039;&lt;br /&gt;
||Ignores your current chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject &amp;lt;subject&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the subject of the mail.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail subject.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Set the HOME address of the owner (mail will be forwarder to this address when offline).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home&#039;&#039;&#039;&lt;br /&gt;
||Show the HOME address.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Info&#039;&#039;&#039;&lt;br /&gt;
||Shows the mail address the object this script is running in uses (e.g. &amp;lt;object-key&amp;gt;@lsl.secondlife.com).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Read&#039;&#039;&#039;&lt;br /&gt;
||Reads the current message from the mail buffer (the mail buffer gets filled with mail you receive)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Select &amp;lt;msg&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Select a message number from the availabe messages in the mail buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Next&#039;&#039;&#039;&lt;br /&gt;
||Make next message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Prev&#039;&#039;&#039;&lt;br /&gt;
||Make previous message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@First&#039;&#039;&#039;&lt;br /&gt;
||Make the first message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Last&#039;&#039;&#039;&lt;br /&gt;
||Make the last message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Clear&#039;&#039;&#039;&lt;br /&gt;
||Clear the mail buffer&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Delete&#039;&#039;&#039;&lt;br /&gt;
||Deletes only the current message&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Reply&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording to reply to the current message. Mail adress and subject are filled in automatically.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* Commands are case insensitive (&amp;quot;@read&amp;quot; == &amp;quot;@READ&amp;quot;). Arguments might not be case insensitive.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;ADDRESS BOOK FORMAT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
A notecard of the name &#039;Address Book&#039; is read during initialization which may contain Address Book items and Groups.&lt;br /&gt;
The notecard is split in two sections, which need to be defined in that particular order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[ADDRESS BOOK]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Defines the section in which you can put names for mail addresses,  like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name1=account@thisdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name2=user@otherdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[GROUP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define groups of previously defined names under a new name, like for instance:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyGroup=Name1, Name2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note that names of groups and individual mail adresses share the same namespace and must be unique.&lt;br /&gt;
&lt;br /&gt;
So when you filled in your mail adresses in the Address Book, you can now use:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail Name1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to  &amp;lt;account@thisdomain.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail MyGroup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to &amp;lt;account@thisdomain.com&amp;gt; and &amp;lt;user@otherdomain.com&amp;gt;&lt;br /&gt;
Mails will be sent one after another.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* Names for Addreses and Groups are case insensitive (e.g. &amp;quot;mary&amp;quot;  == &amp;quot;MARY&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* The special address &#039;Self&#039; can be used in commands where otherwise an address specification can be used. &#039;Self&#039; is case insensitive (e.g. &amp;quot;self&amp;quot; == &amp;quot;SELF&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LIMITATIONS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
The current version is limited by the following:&lt;br /&gt;
&lt;br /&gt;
* Chat recording lines are limited by the 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Output of lines from the mail buffer are also limited by this 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Incoming mail is limited to a 1000 (1024?) byte limit&lt;br /&gt;
&lt;br /&gt;
* Outgoing mai is limited by a 4096 byte limit, which includes the standard mail header (region/location info on the first two lines)&lt;br /&gt;
&lt;br /&gt;
We are making adjustments to this release to help overcome these limitations. At least the line lenght limit can be overcome by introducing a line continuation character (for example a hyphen &#039;-&#039;) that when used at the end of a line appends the next line, so lines longer then 255 bytes are possible then.&lt;br /&gt;
&lt;br /&gt;
To overcome the outgoing mail length limit, the mail can be broken textualy into parts, and each part can be send seperatedely, with an indication in the subject or in an introduced primary line of the mail body to indicate that the mail was split into parts.&lt;br /&gt;
For incoming mail and at least to receive mail from other SL Mail programs, a protocol will be introduced to receive mail in parts that are joined together after receiving them to form a single mail.&lt;br /&gt;
&lt;br /&gt;
These enhancements will be made available in the next release (V1.3) of SL Mail &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;BUGS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Report any bugs you find in this release to Logic (IM: Flennan Roffo).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;REQUEST FOR CHANGE (RFC)&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Do you have additional wishes for enhancement of this product?&lt;br /&gt;
Contact Flennan Roffo and we will see if they can be implemented in the next release.&lt;br /&gt;
&lt;br /&gt;
Existing RFC&#039;s are:&lt;br /&gt;
&lt;br /&gt;
* Menu support for commands.&lt;br /&gt;
&lt;br /&gt;
* Lines on incoming/outgoing mail longer than 255 bytes.&lt;br /&gt;
&lt;br /&gt;
* Send messages longer than 4096 (minus SL mail header) bytes.&lt;br /&gt;
&lt;br /&gt;
* Receive messages longer than 1024 bytes.&lt;br /&gt;
&lt;br /&gt;
* Permanent mail addresses for the SL Mail client (like: &amp;lt;Flennan.Roffo@somedomain.sl&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Add your RFC!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In-world join the group &amp;quot;SL Mail&amp;quot; for bug reports, feature requests, the latest SL Mail release, and notices about development issues.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scripts=&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==Script: SL Mail v1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail core module which scans for incoming mail messages and executes commands used by the owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail V1.2.lsl&lt;br /&gt;
// (c) 2007 Logic Scripted Products and Script Services&lt;br /&gt;
// Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
// VERSION&lt;br /&gt;
// Version: 1.2&lt;br /&gt;
&lt;br /&gt;
// HISTORY&lt;br /&gt;
// Date         Version     Author              Comment&lt;br /&gt;
// --------------------------------------------------------------------------------------&lt;br /&gt;
// 28 aug 2007  V 1.0       Flennan Roffo       Created&lt;br /&gt;
//&lt;br /&gt;
//  1 sep 2007  V 1.1       Flennan Roffo       @Reply empties the recording buffer.&lt;br /&gt;
//                                                @Send while recording ends recording&lt;br /&gt;
//                                                and sends the mail if a mail address&lt;br /&gt;
//                                                and subject are supplied.&lt;br /&gt;
//                                                Fixed incorrect date in Unix2DateTime.&lt;br /&gt;
//  3 sep 2007  V 1.2       Flennan Roffo       Notification options:&lt;br /&gt;
//                                              - When online, send an IM when mail is received.&lt;br /&gt;
//                                              - When offline, send to HOME mail adress.&lt;br /&gt;
//                                              Adressbook&lt;br /&gt;
//                                              - Read adress book from config notecard.&lt;br /&gt;
&lt;br /&gt;
// LICENCE&lt;br /&gt;
// This program is free software; you can redistribute it and/or&lt;br /&gt;
// modify it under the terms of the GNU General Public License&lt;br /&gt;
// as published by the Free Software Foundation; either version 2&lt;br /&gt;
// of the License, or (at your option) any later version.&lt;br /&gt;
// &lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
// &lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program; if not, write to the Free Software&lt;br /&gt;
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
// (Also available at http://www.gnu.org/copyleft/gpl.html) &lt;br /&gt;
&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// Let&#039;s you record a message and sent to email and get messages and reply to messages.&lt;br /&gt;
// Must supply a valid mail adress and non-empty subject using chat commands.&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
// 1) Check for the maximum length of an email message (including newline and header).&lt;br /&gt;
// 2) Read adress book from notecard.                                    *DONE*&lt;br /&gt;
// 3) Send incoming mail to personal mail adress when offline.            *DONE*&lt;br /&gt;
// 4) Alert with an IM when online upon receiving new mail.                *DONE*&lt;br /&gt;
&lt;br /&gt;
string   SL_MAIL_VERSION = &amp;quot;V 1.2&amp;quot;;&lt;br /&gt;
string   SL_MAIL_DATE    = &amp;quot; 2 sep 2007&amp;quot;;&lt;br /&gt;
integer  ErrorFlag         = FALSE;&lt;br /&gt;
list     ScriptList        = [ &amp;quot;SL Mail Help V1.2&amp;quot;, &amp;quot;SL Mail AddressBook V1.2&amp;quot;, &lt;br /&gt;
                                &amp;quot;SL Mail OnlineStatus V1.2&amp;quot;, &amp;quot;SL Mail FetchNotecard V1.2&amp;quot; ];    &lt;br /&gt;
string   LSL_DOMAIN=&amp;quot;lsl.secondlife.com&amp;quot;; &lt;br /&gt;
integer  StatusOnline=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Commands&lt;br /&gt;
&lt;br /&gt;
string  COMMAND_RECORD     = &amp;quot;@RECORD&amp;quot;;&lt;br /&gt;
string  COMMAND_CONTINUE   = &amp;quot;@CONTINUE&amp;quot;;&lt;br /&gt;
string  COMMAND_STOP       = &amp;quot;@STOP&amp;quot;;&lt;br /&gt;
string  COMMAND_MAIL       = &amp;quot;@MAIL&amp;quot;;&lt;br /&gt;
string  COMMAND_SUBJECT    = &amp;quot;@SUBJECT&amp;quot;;&lt;br /&gt;
string  COMMAND_SEND       = &amp;quot;@SEND&amp;quot;;&lt;br /&gt;
string  COMMAND_SEE        = &amp;quot;@SEE&amp;quot;;&lt;br /&gt;
string  COMMAND_IGNORE     = &amp;quot;@IGNORE&amp;quot;;&lt;br /&gt;
string  COMMAND_READ       = &amp;quot;@READ&amp;quot;;&lt;br /&gt;
string  COMMAND_DELETE     = &amp;quot;@DELETE&amp;quot;;&lt;br /&gt;
string  COMMAND_CLEAR      = &amp;quot;@CLEAR&amp;quot;;&lt;br /&gt;
string  COMMAND_REPLY      = &amp;quot;@REPLY&amp;quot;;&lt;br /&gt;
string  COMMAND_NEXT       = &amp;quot;@NEXT&amp;quot;;&lt;br /&gt;
string  COMMAND_PREV       = &amp;quot;@PREV&amp;quot;;&lt;br /&gt;
string  COMMAND_FIRST      = &amp;quot;@FIRST&amp;quot;;&lt;br /&gt;
string  COMMAND_LAST       = &amp;quot;@LAST&amp;quot;;&lt;br /&gt;
string  COMMAND_LIST       = &amp;quot;@LIST&amp;quot;;&lt;br /&gt;
string  COMMAND_SELECT     = &amp;quot;@SELECT&amp;quot;;&lt;br /&gt;
string  COMMAND_HELP       = &amp;quot;@HELP&amp;quot;;&lt;br /&gt;
string  COMMAND_INFO       = &amp;quot;@INFO&amp;quot;;&lt;br /&gt;
string  COMMAND_RESET      = &amp;quot;@RESET&amp;quot;;&lt;br /&gt;
string  COMMAND_SHOW       = &amp;quot;@SHOW&amp;quot;;&lt;br /&gt;
string  COMMAND_ON         = &amp;quot;@ON&amp;quot;;&lt;br /&gt;
string  COMMAND_OFF        = &amp;quot;@OFF&amp;quot;;&lt;br /&gt;
string  COMMAND_HOME       = &amp;quot;@HOME&amp;quot;;&lt;br /&gt;
string  COMMAND_LOAD       = &amp;quot;@LOAD&amp;quot;;&lt;br /&gt;
string  COMMAND_ADDRESS    = &amp;quot;@ADDRESS&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Recording&lt;br /&gt;
&lt;br /&gt;
integer Recording = FALSE;&lt;br /&gt;
&lt;br /&gt;
list    ChatRecording=[];&lt;br /&gt;
integer NumLines=0;&lt;br /&gt;
integer Length=0;&lt;br /&gt;
&lt;br /&gt;
list     TimeList=[];&lt;br /&gt;
list     AddressList=[];&lt;br /&gt;
list     SubjectList=[];&lt;br /&gt;
list     BodyList=[];&lt;br /&gt;
integer  NumMessages=0;&lt;br /&gt;
integer  CurrentMessage=-1;&lt;br /&gt;
&lt;br /&gt;
float    MAIL_FETCH_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
// Link Messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP                        = 10000;&lt;br /&gt;
integer MSG_STATUS_ONLINE               = 30000;&lt;br /&gt;
integer MSG_STATUS_OFFLINE              = 30100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED          = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR           = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Unix Time conversion //////////////////&lt;br /&gt;
&lt;br /&gt;
integer DAYS_PER_YEAR        = 365;                // Non leap year&lt;br /&gt;
integer SECONDS_PER_YEAR     = 31536000;          // Non leap year&lt;br /&gt;
integer SECONDS_PER_DAY      = 86400;&lt;br /&gt;
integer SECONDS_PER_HOUR     = 3600;&lt;br /&gt;
integer SECONDS_PER_MINUTE   = 60;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// LeapYear() /////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer LeapYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (year % 4 == 0)&lt;br /&gt;
    {&lt;br /&gt;
        if (year % 100 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (year % 400 == 0)&lt;br /&gt;
            {&lt;br /&gt;
                return 1;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// DaysPerMonth() ///////////////////////////////////////&lt;br /&gt;
                &lt;br /&gt;
integer DaysPerMonth(integer year,integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;lt; 8)&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (month == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if (LeapYear(year))&lt;br /&gt;
                {&lt;br /&gt;
                    return 29;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    return 28;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 30;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 30;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////// DaysPerYear() ////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DaysPerYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (LeapYear(year))&lt;br /&gt;
        return DAYS_PER_YEAR + 1;&lt;br /&gt;
    else&lt;br /&gt;
        return DAYS_PER_YEAR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Unix2DataTime() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list Unix2DateTime(integer unixtime)&lt;br /&gt;
{&lt;br /&gt;
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;&lt;br /&gt;
    integer day = days_since_1_1_1970 + 1;&lt;br /&gt;
    integer year  = 1970;&lt;br /&gt;
    integer days_per_year = DaysPerYear(year);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_year)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_year;&lt;br /&gt;
        ++year;&lt;br /&gt;
        days_per_year = DaysPerYear(year);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer month = 1;&lt;br /&gt;
    integer days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_month)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_month;&lt;br /&gt;
        &lt;br /&gt;
        if (++month &amp;gt; 12)&lt;br /&gt;
        {    &lt;br /&gt;
            ++year;&lt;br /&gt;
            month = 1;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;&lt;br /&gt;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;&lt;br /&gt;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;&lt;br /&gt;
    integer minute      = second / SECONDS_PER_MINUTE;&lt;br /&gt;
    second               = second % SECONDS_PER_MINUTE;&lt;br /&gt;
    &lt;br /&gt;
    return [ year, month, day, hour, minute, second ];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// MonthName() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list MonthNameList = [     &amp;quot;JAN&amp;quot;, &amp;quot;FEB&amp;quot;, &amp;quot;MAR&amp;quot;, &amp;quot;APR&amp;quot;, &amp;quot;MAY&amp;quot;, &amp;quot;JUN&amp;quot;, &lt;br /&gt;
                        &amp;quot;JUL&amp;quot;, &amp;quot;AUG&amp;quot;, &amp;quot;SEP&amp;quot;, &amp;quot;OCT&amp;quot; , &amp;quot;NOV&amp;quot;, &amp;quot;DEC&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
string MonthName(integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;gt;= 0 &amp;amp;&amp;amp; month &amp;lt; 12)&lt;br /&gt;
        return llList2String(MonthNameList, month);&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// DateString() ///////////////////////////&lt;br /&gt;
&lt;br /&gt;
string DateString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer year       = llList2Integer(timelist,0);&lt;br /&gt;
    integer month      = llList2Integer(timelist,1);&lt;br /&gt;
    integer day        = llList2Integer(timelist,2);&lt;br /&gt;
    &lt;br /&gt;
    return (string)day + &amp;quot;-&amp;quot; + MonthName(month - 1) + &amp;quot;-&amp;quot; + (string)year;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// TimeString() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string TimeString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer hour          = llList2Integer(timelist,3);&lt;br /&gt;
    integer minute         = llList2Integer(timelist,4);&lt;br /&gt;
    integer second         = llList2Integer(timelist,5);&lt;br /&gt;
    string  hourstr     = (string)hour;&lt;br /&gt;
    string  minutestr   = (string)minute;&lt;br /&gt;
    string  secondstr   = (string)second;&lt;br /&gt;
    &lt;br /&gt;
    if (hour &amp;lt; 10)         hourstr     = &amp;quot;0&amp;quot; + hourstr;&lt;br /&gt;
    if (minute &amp;lt; 10)     minutestr     = &amp;quot;0&amp;quot; + minutestr;&lt;br /&gt;
    if (second &amp;lt; 10)    secondstr    = &amp;quot;0&amp;quot; + secondstr;&lt;br /&gt;
    return hourstr + &amp;quot;:&amp;quot; + minutestr + &amp;quot;:&amp;quot; + secondstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() /////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string body)&lt;br /&gt;
{&lt;br /&gt;
    // llOwnerSay(&amp;quot;Sending message to &#039;&amp;quot; + address + &amp;quot;&#039; with subject &#039;&amp;quot; + subject +&amp;quot;&#039;.&amp;quot;);&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND, body, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// SendHome() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendHome(string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SENDHOME, body, (key)subject);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Show() ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Show()&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;Current chat recording is:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; NumLines; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(ChatRecording,i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;Lines is &amp;quot; + (string)NumLines);&lt;br /&gt;
    llOwnerSay(&amp;quot;Message length is &amp;quot; + (string)Length);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Read() /////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Read()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;Reading message &amp;quot; + (string)CurrentMessage + &amp;quot; from mail buffer.&amp;quot;);&lt;br /&gt;
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);&lt;br /&gt;
    list timelist=Unix2DateTime(time);&lt;br /&gt;
    string Address = llList2String(AddressList,CurrentMessage);&lt;br /&gt;
    string Subject = llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
    string Body    = llList2String(BodyList,CurrentMessage);&lt;br /&gt;
    llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Address: &amp;quot; + Address);&lt;br /&gt;
    llOwnerSay(&amp;quot;Subject: &amp;quot; + Subject);&lt;br /&gt;
    llOwnerSay(&amp;quot;Begin of message body:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    list bodylist=llParseStringKeepNulls(Body, [ &amp;quot;\n&amp;quot; ], []);&lt;br /&gt;
    integer num=llGetListLength(bodylist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(bodylist,i));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;End of message body.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////// List ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
List()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;The mail buffer contains the following messages:\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; NumMessages; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer time=llList2Integer(TimeList,i);&lt;br /&gt;
        list timelist=Unix2DateTime(time);&lt;br /&gt;
        if (i &amp;gt; 0) llOwnerSay(&amp;quot;+-+-+-+-+-+-+-+-+-+-+-+-&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Message: &amp;quot; + (string)i);&lt;br /&gt;
        llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;From:    &amp;quot; + llList2String(AddressList,i));&lt;br /&gt;
        llOwnerSay(&amp;quot;Subject: &amp;quot; + llList2String(SubjectList,i));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////// NotifyNewMail() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
NotifyNewMail(string time, string address, string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    list timelist=Unix2DateTime((integer)time);&lt;br /&gt;
&lt;br /&gt;
    if (StatusOnline)&lt;br /&gt;
    {&lt;br /&gt;
        llInstantMessage(llGetOwner(), &amp;quot;You received a new mail message on &amp;quot; &lt;br /&gt;
                                    + DateString(timelist) + &amp;quot; at &amp;quot; + TimeString(timelist)&lt;br /&gt;
                                    + &amp;quot; from &amp;quot; + address &lt;br /&gt;
                                    + &amp;quot; with the subject &amp;quot; + subject);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        SendHome(&amp;quot;FW: &amp;quot; + subject, &amp;quot;Received at: &amp;quot; + DateString(timelist) + &amp;quot; &amp;quot; + TimeString(timelist) + &amp;quot;\nFrom: &amp;quot; +  address &lt;br /&gt;
                    + &amp;quot;\nBegin message body:\n-------------------\n&amp;quot; + body + &amp;quot;\n-------------------\nEnd message body.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ResetOtherScripts() //////////////////////&lt;br /&gt;
&lt;br /&gt;
ResetOtherScripts()&lt;br /&gt;
{&lt;br /&gt;
    string     name;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(ScriptList);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        name = llList2String(ScriptList,i);&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(name) == INVENTORY_SCRIPT)&lt;br /&gt;
        {&lt;br /&gt;
            llResetOtherScript(name);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Error - script &#039;&amp;quot; + name + &amp;quot;&#039; not found.&amp;quot;);&lt;br /&gt;
            ErrorFlag = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
// default &lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ////////////////////// state_entry() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Welcome to SL Mail, released under GNU software licence.&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Version &amp;quot; + SL_MAIL_VERSION + &amp;quot; &amp;quot; + SL_MAIL_DATE);&lt;br /&gt;
        llOwnerSay(&amp;quot;Produced by Logic Scripted Products &amp;amp; Product Services&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Free memory: &amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
        ResetOtherScripts();&lt;br /&gt;
        &lt;br /&gt;
        if (ErrorFlag)&lt;br /&gt;
            state Error;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// on_rez() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// changed() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_LOADED)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_ERROR)&lt;br /&gt;
        {&lt;br /&gt;
            state Error;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() //////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(MAIL_FETCH_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //////////////////////// on_rez() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// listen() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string trimmessage=llStringTrim(message,STRING_TRIM);&lt;br /&gt;
        list   parse = llParseStringKeepNulls(trimmessage, [ &amp;quot; &amp;quot;], []);&lt;br /&gt;
        string command = llToUpper(llList2String(parse,0));&lt;br /&gt;
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        integer nargs  = llGetListLength(parse);&lt;br /&gt;
        string argstr=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (nargs &amp;gt; 1) argstr=llGetSubString(message, llSubStringIndex(message, &amp;quot; &amp;quot;) + 1, -1);&lt;br /&gt;
            &lt;br /&gt;
        if (Recording)&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Recording stopped. Type @SHOW to see the message you have entered,&amp;quot;&lt;br /&gt;
                            + &amp;quot; or @SEND to send it.&amp;quot;);&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                &lt;br /&gt;
                SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];&lt;br /&gt;
                ++NumLines;&lt;br /&gt;
                Length += llStringLength(message) + 2;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_RECORD)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Start recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                ChatRecording = [];&lt;br /&gt;
                NumLines=0;&lt;br /&gt;
                Length=0;&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CONTINUE)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Continue recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_REPLY)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    string address=llList2String(AddressList,CurrentMessage);&lt;br /&gt;
                    string subject=&amp;quot;Re: &amp;quot; + llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, address, NULL_KEY);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, subject, NULL_KEY);&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines=0;&lt;br /&gt;
                    Length=0;&lt;br /&gt;
                    Recording = TRUE;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_MAIL)&lt;br /&gt;
            {&lt;br /&gt;
                string mailaddress=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailaddress != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, mailaddress, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETADDRESS, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SUBJECT)&lt;br /&gt;
            {&lt;br /&gt;
                string mailsubject=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailsubject != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, mailsubject, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETSUBJECT, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Not recording.&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    if (NumLines == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND_NOTECARD, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_IGNORE)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines = 0;&lt;br /&gt;
                    Length = 0;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Show();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_READ)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumMessages == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Read();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        ++CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        --CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_FIRST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = 0;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LAST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LIST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    List();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SELECT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;Need to supply a message number.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    integer msgnum = (integer)arg;&lt;br /&gt;
                     &lt;br /&gt;
                    if (msgnum &amp;lt; 0 || msgnum &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Message number &amp;quot; + arg + &amp;quot; not in mail buffer.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = msgnum;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_DELETE)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    --NumMessages;&lt;br /&gt;
                     &lt;br /&gt;
                    if (NumMessages == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = -1;&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (CurrentMessage &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CLEAR)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList=[];&lt;br /&gt;
                    AddressList=[];&lt;br /&gt;
                    SubjectList=[];&lt;br /&gt;
                    BodyList=[];&lt;br /&gt;
                    NumMessages=0;&lt;br /&gt;
                    CurrentMessage=-1;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_HELP, arg, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_INFO)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                Show();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_RESET)&lt;br /&gt;
            {&lt;br /&gt;
                llResetScript();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                state not_running;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HOME)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs==1)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETHOME, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETHOME, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// email() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    email(string time, string address, string subject, string body, integer queued)&lt;br /&gt;
    {&lt;br /&gt;
        NotifyNewMail(time, address, subject, body);&lt;br /&gt;
        TimeList = (TimeList=[]) + TimeList + [time];&lt;br /&gt;
        AddressList = (AddressList=[]) + AddressList + [address];&lt;br /&gt;
        SubjectList = (SubjectList=[]) + SubjectList + [subject];&lt;br /&gt;
        BodyList = (BodyList=[]) + BodyList + [body];&lt;br /&gt;
        ++NumMessages;&lt;br /&gt;
        &lt;br /&gt;
        if (CurrentMessage == -1)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = NumMessages - 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_REPLY)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state not_running&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state not_running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;SL Mailbox switched OFF. Say @ON to switch it back on.&amp;quot;);&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// on_rez() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// listen() ////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer chan, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string command=llToUpper(message);&lt;br /&gt;
        &lt;br /&gt;
        if (command == COMMAND_ON)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state Error&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state Error&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Error in SL Mail: not all component scripts found.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// End SL Mail V1.2.lsl&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Address Book V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Read and interpret the contents of the Address Book.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail AddressBook V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// &lt;br /&gt;
//  Read the Address Book from a notecard named &amp;quot;Address Book&amp;quot;.&lt;br /&gt;
//&lt;br /&gt;
//  The Address Book has the following format:&lt;br /&gt;
//  &lt;br /&gt;
//  [ADDRESS BOOK]&lt;br /&gt;
//  Name1=username@yourdomain.com&lt;br /&gt;
//  Name2=otheruser@otherdomain.com&lt;br /&gt;
//  ...&lt;br /&gt;
//  [GROUP]&lt;br /&gt;
//  group1=Name1, Name2&lt;br /&gt;
//  ...&lt;br /&gt;
//&lt;br /&gt;
//  Notes:&lt;br /&gt;
//  1. Group and Name share the same namespace, and must be unique.&lt;br /&gt;
//  2. It is allowed to have a name in the addressbook with multiple addresses, seperated by comma&#039;s.&lt;br /&gt;
// &lt;br /&gt;
/////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string  CurrentMailAddress = &amp;quot;&amp;quot;;&lt;br /&gt;
string  CurrentMailSubject = &amp;quot;&amp;quot;;&lt;br /&gt;
integer StatusOnline = FALSE;&lt;br /&gt;
&lt;br /&gt;
// Fetch or Send notecard&lt;br /&gt;
&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Names&lt;br /&gt;
&lt;br /&gt;
list    AddressBookList=[];&lt;br /&gt;
list    MailAddressList=[];&lt;br /&gt;
&lt;br /&gt;
string  STRING_HOME=&amp;quot;HOME&amp;quot;;&lt;br /&gt;
string  STRING_SELF=&amp;quot;SELF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Groups&lt;br /&gt;
&lt;br /&gt;
list   GroupList=[];&lt;br /&gt;
list   GroupNameList=[];&lt;br /&gt;
&lt;br /&gt;
string LSL_DOMAIN = &amp;quot;lsl.secondlife.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Read Address Book notecard&lt;br /&gt;
&lt;br /&gt;
string  ADDRESSBOOK_NOTECARD=&amp;quot;Address Book&amp;quot;;&lt;br /&gt;
integer Line=0;&lt;br /&gt;
key     reqAddressBook=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
integer Section=0;&lt;br /&gt;
integer SECTION_ADDRESS_BOOK=1;&lt;br /&gt;
integer SECTION_GROUP=2;&lt;br /&gt;
string  STRING_ADDRESS_BOOK=&amp;quot;ADDRESS BOOK&amp;quot;;&lt;br /&gt;
string  STRING_GROUP=&amp;quot;GROUP&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Links messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
integer MSG_MESSAGE_NOTIFY              = 90900;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED            = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR            = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// GetSelfAddress() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
string GetSelfAddress()&lt;br /&gt;
{&lt;br /&gt;
    return (string)llGetKey() + &amp;quot;@&amp;quot; + LSL_DOMAIN;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Info() /////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Info()&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;The mail address for this object is: &amp;quot; &lt;br /&gt;
                    + GetSelfAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// IsValidKeyFormat() //////////////////////&lt;br /&gt;
&lt;br /&gt;
integer IsValidKeyFormat(string str)&lt;br /&gt;
{&lt;br /&gt;
    string keychars = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    if (llStringLength(str) != 36)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    if( (llGetSubString( str, 8, 8 )   != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 13, 13 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 18, 18 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 23, 23 )  != &amp;quot;-&amp;quot; ) )&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 9; i &amp;lt; 13; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 14; i &amp;lt; 18; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 19; i &amp;lt; 23; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 24; i &amp;lt; 36; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// ValidMailAddress() ////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer ValidMailAddress(string arg)&lt;br /&gt;
{&lt;br /&gt;
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));&lt;br /&gt;
    &lt;br /&gt;
    if (adress == &amp;quot;&amp;quot;)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    list parse = llParseStringKeepNulls(adress, [ &amp;quot;@&amp;quot; ], []);&lt;br /&gt;
    string account = llList2String(parse,0);&lt;br /&gt;
    string domain  = llList2String(parse,1);&lt;br /&gt;
    &lt;br /&gt;
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    &lt;br /&gt;
    if (domain == LSL_DOMAIN)&lt;br /&gt;
    {&lt;br /&gt;
        return IsValidKeyFormat(account);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list parsedomain = llParseString2List(domain, [ &amp;quot;.&amp;quot; ], []);&lt;br /&gt;
    &lt;br /&gt;
        if (llGetListLength(parsedomain) &amp;lt; 2)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        &lt;br /&gt;
        integer num = llGetListLength(parsedomain);&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llStringLength(llList2String(parsedomain,i)) &amp;lt; 2)&lt;br /&gt;
            {&lt;br /&gt;
                return FALSE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetAddressStr() ///////////////////&lt;br /&gt;
&lt;br /&gt;
string GetAndCheckAddressStr(string address)&lt;br /&gt;
{&lt;br /&gt;
    list addresslist = llCSV2List(address);&lt;br /&gt;
    integer num=llGetListLength(addresslist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    string addressstr=&amp;quot;&amp;quot;;&lt;br /&gt;
    string curaddress=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        curaddress=llList2String(addresslist,i);&lt;br /&gt;
        &lt;br /&gt;
        if (ValidMailAddress(curaddress))&lt;br /&gt;
        {&lt;br /&gt;
            addressstr = (addressstr=&amp;quot;&amp;quot;) + addressstr + curaddress + &amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address string: &#039;&amp;quot; &lt;br /&gt;
                            + curaddress + &amp;quot;&#039;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return llGetSubString(addressstr, 0, -2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ProcessLine() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
ProcessLine(string rawline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(rawline,STRING_TRIM);&lt;br /&gt;
    string first=llGetSubString(line,0,0);&lt;br /&gt;
    string last=llGetSubString(line,-1,-1);&lt;br /&gt;
    &lt;br /&gt;
    // Ignore a blank line or comment line&lt;br /&gt;
    if (line == &amp;quot;&amp;quot; || first == &amp;quot;#&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // Check for the right section&lt;br /&gt;
    &lt;br /&gt;
    if (first == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; last == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        string sectionstr=llToUpper(llStringTrim(llGetSubString(line,1,-2),STRING_TRIM));&lt;br /&gt;
        &lt;br /&gt;
        if (sectionstr == STRING_ADDRESS_BOOK)&lt;br /&gt;
        {&lt;br /&gt;
            Section = SECTION_ADDRESS_BOOK;&lt;br /&gt;
        }&lt;br /&gt;
        else if (sectionstr == STRING_GROUP)&lt;br /&gt;
        {&lt;br /&gt;
            if (Section == 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                        + &amp;quot;. Group section defined before Address Book section.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Section = SECTION_GROUP;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid section header &#039;&amp;quot; + sectionstr &lt;br /&gt;
                        + &amp;quot;&#039; in &amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Must be in a section&lt;br /&gt;
    &lt;br /&gt;
    if (Section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;. No section header.&amp;quot;, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    list     parse=llParseString2List(line, [ &amp;quot;=&amp;quot; ], []);&lt;br /&gt;
    integer  num=llGetListLength(parse);&lt;br /&gt;
    &lt;br /&gt;
    // Format must be correct&lt;br /&gt;
    &lt;br /&gt;
    if (num != 2)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; +  (string)(Line+1) + &amp;quot;:\n&amp;quot; + rawline, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (Section == SECTION_ADDRESS_BOOK)&lt;br /&gt;
    {&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(name) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + name &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ name ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            string address=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
            string addressstr=GetAndCheckAddressStr(address);&lt;br /&gt;
            &lt;br /&gt;
            if (addressstr != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                AddressBookList     = (AddressBookList=[])     + AddressBookList     + [ name ];&lt;br /&gt;
                MailAddressList     = (MailAddressList=[])     + MailAddressList     + [ addressstr ];&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;No valid mail address for &#039;&amp;quot; + name &lt;br /&gt;
                    + &amp;quot;&#039;. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                    + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name &lt;br /&gt;
                + &amp;quot;&#039; already defined. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // Group&lt;br /&gt;
    {&lt;br /&gt;
        string group=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(group) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + group &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ group ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(GroupList, [ group ]) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                string names=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
                list   namelist=llCSV2List(names);&lt;br /&gt;
                integer num=llGetListLength(namelist);&lt;br /&gt;
                integer i;&lt;br /&gt;
                integer index;&lt;br /&gt;
                string  name;&lt;br /&gt;
                string  namestr=&amp;quot;&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
                for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                    name=llList2String(namelist,i);&lt;br /&gt;
                    index=llListFindList(AddressBookList, [ name ]);&lt;br /&gt;
            &lt;br /&gt;
                    if (index == -1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name + &amp;quot;&#039; defined in Group &#039;&amp;quot; &lt;br /&gt;
                                + group + &amp;quot;&#039; not found in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY); &lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        namestr = (namestr=&amp;quot;&amp;quot;) + namestr + name + &amp;quot;,&amp;quot;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (namestr != &amp;quot;&amp;quot;)&lt;br /&gt;
                {    &lt;br /&gt;
                    namestr=llGetSubString(namestr,0,-2);&lt;br /&gt;
                    GroupList         = (GroupList=[])         + GroupList     + [ group ];&lt;br /&gt;
                    GroupNameList     = (GroupNameList=[])    + GroupNameList + [ namestr ];&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                        + &amp;quot;&#039; has no valid names. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                        + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                    + &amp;quot;&#039; already defined in Group. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                    + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group&lt;br /&gt;
                + &amp;quot;&#039; already defined in Address Book. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// GetGroupAddressList ///////////////&lt;br /&gt;
&lt;br /&gt;
string GetGroupAddressList(string group)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(GroupList, [ group ]);&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(GroupList);&lt;br /&gt;
    string  grouplist=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        for (i = index; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2String(GroupList,i) == group)&lt;br /&gt;
            {&lt;br /&gt;
                grouplist = (grouplist=&amp;quot;&amp;quot;) + grouplist + llList2String(GroupNameList,i) + &amp;quot;,&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (grouplist != &amp;quot;&amp;quot;) grouplist=llGetSubString(grouplist,0,-2);   // remove last &amp;quot;,&amp;quot;&lt;br /&gt;
        return grouplist;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// SetMailAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetMailAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ address ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        index=llListFindList(GroupList, [ address ]);&lt;br /&gt;
        &lt;br /&gt;
        if (index == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llToUpper(address) == STRING_SELF)&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = GetSelfAddress();&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if(ValidMailAddress(address))&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = address;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Mail adress &amp;quot; + address &lt;br /&gt;
                            + &amp;quot; : not found in adress book or invalid format.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailAddress = GetGroupAddressList(address);&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        CurrentMailAddress = llList2String(MailAddressList,index);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                        + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string message)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No mail address defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No subject defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list mailaddresslist=llCSV2List(CurrentMailAddress);&lt;br /&gt;
        integer num=llGetListLength(mailaddresslist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(mailaddresslist,i);&lt;br /&gt;
            llEmail(address, CurrentMailSubject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMailHome() ////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMailHome(string message, string subject)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, STRING_HOME &lt;br /&gt;
                + &amp;quot; not set. Set your home adress with @HOME &amp;lt;address&amp;gt;.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        string homeaddress=llList2String(AddressBookList,index);&lt;br /&gt;
        list   homelist=llCSV2List(homeaddress);&lt;br /&gt;
        integer num=llGetListLength(homelist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(homelist,i);&lt;br /&gt;
            llEmail(address, subject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
string GetHomeAddress()&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;not set&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2String(MailAddressList,index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetHomeAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        AddressBookList     = (AddressBookList=[]) + [ STRING_HOME ] + AddressBookList;&lt;br /&gt;
        MailAddressList     = (MailAddressList=[]) + [ GetAndCheckAddressStr(address) ]  + MailAddressList;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MailAddressList = llListReplaceList(MailAddressList, [ GetAndCheckAddressStr(address) ], index, index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        Line=0;&lt;br /&gt;
        Section=0;&lt;br /&gt;
        llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// dataserver() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqAddressBook)&lt;br /&gt;
        {&lt;br /&gt;
            reqAddressBook = NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                ProcessLine(data);&lt;br /&gt;
                reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Address Book loaded.&amp;quot;, NULL_KEY);&lt;br /&gt;
                state running;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// timer() ///////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_ERROR, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Could not read Address Book: &amp;quot; &lt;br /&gt;
                            + ADDRESSBOOK_NOTECARD + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// link_message() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_MESSAGE_GETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is empty.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailSubject = message;&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is empty.&amp;quot;, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            SetMailAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Body of message to send is empty. &amp;quot; &lt;br /&gt;
                                +  &amp;quot;No mail is send.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SENDHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SendMailHome(message, (string)id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetInventoryType(message) == INVENTORY_NOTECARD)&lt;br /&gt;
            {&lt;br /&gt;
                Notecard2Fetch = message;                &lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_READ, message, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + message + &amp;quot; not found.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_NOTECARD_FETCHED)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + Notecard2Fetch &lt;br /&gt;
                            + &amp;quot; was empty or could not be read.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Home address is: &amp;quot; + GetHomeAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SetHomeAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_INFO)&lt;br /&gt;
        {&lt;br /&gt;
            Info();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
// End SL Mail AddressBook V1.2.lsl&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail FetchNotecard V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch the contents of a notecard and return it via link message as a string.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Notecard&lt;br /&gt;
&lt;br /&gt;
integer Line=0;&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
key     reqNotecard=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=10.0;&lt;br /&gt;
integer Fetched=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Lines&lt;br /&gt;
&lt;br /&gt;
list LineList=[];&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    /////////////////////// dataserver() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqNotecard)&lt;br /&gt;
        {&lt;br /&gt;
            reqNotecard=NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                LineList = (LineList=[]) + LineList + [ data ];&lt;br /&gt;
                reqNotecard = llGetNotecardLine(Notecard2Fetch, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Fetched=TRUE;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, llDumpList2String(LineList, &amp;quot;\n&amp;quot;), NULL_KEY);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /////////////////////// timer() ///////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        if (!Fetched)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            llSetTimerEvent(0.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer send, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_NOTECARD_READ)&lt;br /&gt;
        {&lt;br /&gt;
            Line=0;&lt;br /&gt;
            Notecard2Fetch=message;&lt;br /&gt;
            LineList=[];&lt;br /&gt;
            Fetched=FALSE;&lt;br /&gt;
            reqNotecard=llGetNotecardLine(Notecard2Fetch, Line);&lt;br /&gt;
            llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL OnlineStatus V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch online status of owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Online status&lt;br /&gt;
&lt;br /&gt;
key     reqOnlineStatus=NULL_KEY;&lt;br /&gt;
float   STATUS_INTERVAL=2.0;&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_STATUS_ONLINE       = 30000;&lt;br /&gt;
integer MS_STATUS_OFFLINE       = 30100;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus=llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
        llSetTimerEvent(STATUS_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// dataserver() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqOnlineStatus)&lt;br /&gt;
        {&lt;br /&gt;
            reqOnlineStatus = NULL_KEY;&lt;br /&gt;
        &lt;br /&gt;
            if (data==&amp;quot;1&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_STATUS_ONLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if (data==&amp;quot;0&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MS_STATUS_OFFLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus = llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Help V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Display help information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail Help V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP    = 10000;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Help() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Help()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;HELP for SL Mail V1.2.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;COMMANDS:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HELP               - displays help info.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@INFO               - display mailaddress of this object.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RECORD             - start recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CONTINUE           - continue recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@STOP               - stop recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@IGNORE             - ignore the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SHOW               - show what your recorded.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SEND               - send the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@MAIL &amp;lt;mailadress&amp;gt;  - set the mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SUBJECT subject    - set the mail subject.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LIST               - list messages in mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SELECT &amp;lt;message&amp;gt;   - select message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@READ               - read current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@NEXT               - read next message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@PREV               - read previous message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@FIRST              - read first message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LAST               - read last message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@DELETE             - delete current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CLEAR              - clear the mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@REPLY              - reply to current message.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RESET              - reset the script.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HOME               - set the home mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@OFF                - switch mailbox OFF.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@ON                 - switch mailbox ON.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_HELP)&lt;br /&gt;
        {&lt;br /&gt;
            Help();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail Help V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}&lt;/div&gt;</description>
			<pubDate>Sun, 07 Oct 2007 10:21:46 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:SL_Mail_V1.2</comments>
		</item>
		<item>
			<title>SL Mail V1.2</title>
			<link>https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34585</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34585</guid>
			<description>&lt;p&gt;Flennan Roffo: /* &amp;#039;&amp;#039;&amp;#039;PRODUCTION &amp;amp; MAINTANENCE&amp;#039;&amp;#039;&amp;#039; */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}} __NOTOC__&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=&#039;&#039;&#039;Second Life mail client&#039;&#039;&#039;=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Send and receive email from within Second Life from and to any address.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implemented with Address Book function (in a notecard named &#039;Address Book&#039;) to stores addresses by name  and to compile groups of named addresses. Current version is stand-alone (no server functionality) and uses chat commands only.&lt;br /&gt;
&lt;br /&gt;
[[Image:BannerSLMail.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=Release Notes V1.2=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 Release notes (edition 2, 4 sept 2007)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LICENCE INFO&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is released under GNU free software licence&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;PRODUCTION &amp;amp; MAINTANENCE&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
by Logic Scripted Products and Script Services&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
SLurl:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Contact: [[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
&lt;br /&gt;
Email: info@slmail.info or Flennan.Roffo@slmail.info&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;DESCRIPTION&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is a simple tool to send and receive mail from within SL.&lt;br /&gt;
You can either compose a message yourself using chat recording, or choose a notecard from inventory to send. The Address Book functionality allows you to use short names for mail recipients stored in a notecard. The current version does not have a persisent mail address. Watch out for the upcoming next release (V1.3) which will facilitate persisent in-world mail addresses and will be enhanced with many new features (See: Requests For Change (RFC).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;COMMANDS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Help&#039;&#039;&#039;&lt;br /&gt;
||Show Help about available commands&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Record&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording (for owner only).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Stop&#039;&#039;&#039;&lt;br /&gt;
||Stops the chat recording without sending&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Continue&#039;&#039;&#039;&lt;br /&gt;
||Continues a previously stopped chat recording. Lines will be appended to you recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Show&#039;&#039;&#039;&lt;br /&gt;
||Shows the content of the recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send&#039;&#039;&#039;&lt;br /&gt;
||If recording, stops the recording, and sends the mail (need to supply mail address and subject first!)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send &amp;lt;notecard&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Sends the content of the notecard, instead of the chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Ignore&#039;&#039;&#039;&lt;br /&gt;
||Ignores your current chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject &amp;lt;subject&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the subject of the mail.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail subject.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Set the HOME address of the owner (mail will be forwarder to this address when offline).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home&#039;&#039;&#039;&lt;br /&gt;
||Show the HOME address.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Info&#039;&#039;&#039;&lt;br /&gt;
||Shows the mail address the object this script is running in uses (e.g. &amp;lt;object-key&amp;gt;@lsl.secondlife.com).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Read&#039;&#039;&#039;&lt;br /&gt;
||Reads the current message from the mail buffer (the mail buffer gets filled with mail you receive)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Select &amp;lt;msg&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Select a message number from the availabe messages in the mail buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Next&#039;&#039;&#039;&lt;br /&gt;
||Make next message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Prev&#039;&#039;&#039;&lt;br /&gt;
||Make previous message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@First&#039;&#039;&#039;&lt;br /&gt;
||Make the first message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Last&#039;&#039;&#039;&lt;br /&gt;
||Make the last message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Clear&#039;&#039;&#039;&lt;br /&gt;
||Clear the mail buffer&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Delete&#039;&#039;&#039;&lt;br /&gt;
||Deletes only the current message&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Reply&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording to reply to the current message. Mail adress and subject are filled in automatically.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* Commands are case insensitive (&amp;quot;@read&amp;quot; == &amp;quot;@READ&amp;quot;). Arguments might not be case insensitive.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;ADDRESS BOOK FORMAT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
A notecard of the name &#039;Address Book&#039; is read during initialization which may contain Address Book items and Groups.&lt;br /&gt;
The notecard is split in two sections, which need to be defined in that particular order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[ADDRESS BOOK]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Defines the section in which you can put names for mail addresses,  like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name1=account@thisdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name2=user@otherdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[GROUP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define groups of previously defined names under a new name, like for instance:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyGroup=Name1, Name2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note that names of groups and individual mail adresses share the same namespace and must be unique.&lt;br /&gt;
&lt;br /&gt;
So when you filled in your mail adresses in the Address Book, you can now use:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail Name1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to  &amp;lt;account@thisdomain.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail MyGroup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to &amp;lt;account@thisdomain.com&amp;gt; and &amp;lt;user@otherdomain.com&amp;gt;&lt;br /&gt;
Mails will be sent one after another.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* Names for Addreses and Groups are case insensitive (e.g. &amp;quot;mary&amp;quot;  == &amp;quot;MARY&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* The special address &#039;Self&#039; can be used in commands where otherwise an address specification can be used. &#039;Self&#039; is case insensitive (e.g. &amp;quot;self&amp;quot; == &amp;quot;SELF&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LIMITATIONS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
The current version is limited by the following:&lt;br /&gt;
&lt;br /&gt;
* Chat recording lines are limited by the 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Output of lines from the mail buffer are also limited by this 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Incoming mail is limited to a 1000 (1024?) byte limit&lt;br /&gt;
&lt;br /&gt;
* Outgoing mai is limited by a 4096 byte limit, which includes the standard mail header (region/location info on the first two lines)&lt;br /&gt;
&lt;br /&gt;
We are making adjustments to this release to help overcome these limitations. At least the line lenght limit can be overcome by introducing a line continuation character (for example a hyphen &#039;-&#039;) that when used at the end of a line appends the next line, so lines longer then 255 bytes are possible then.&lt;br /&gt;
&lt;br /&gt;
To overcome the outgoing mail length limit, the mail can be broken textualy into parts, and each part can be send seperatedely, with an indication in the subject or in an introduced primary line of the mail body to indicate that the mail was split into parts.&lt;br /&gt;
For incoming mail and at least to receive mail from other SL Mail programs, a protocol will be introduced to receive mail in parts that are joined together after receiving them to form a single mail.&lt;br /&gt;
&lt;br /&gt;
These enhancements will be made available in the next release (V1.3) of SL Mail &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;BUGS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Report any bugs you find in this release to Logic (IM: Flennan Roffo).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;REQUEST FOR CHANGE (RFC)&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Do you have additional wishes for enhancement of this product?&lt;br /&gt;
Contact Flennan Roffo and we will see if they can be implemented in the next release.&lt;br /&gt;
&lt;br /&gt;
Existing RFC&#039;s are:&lt;br /&gt;
&lt;br /&gt;
* Menu support for commands.&lt;br /&gt;
&lt;br /&gt;
* Lines on incoming/outgoing mail longer than 255 bytes.&lt;br /&gt;
&lt;br /&gt;
* Send messages longer than 4096 (minus SL mail header) bytes.&lt;br /&gt;
&lt;br /&gt;
* Receive messages longer than 1024 bytes.&lt;br /&gt;
&lt;br /&gt;
* Permanent mail addresses for the SL Mail client (like: &amp;lt;Flennan.Roffo@somedomain.sl&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Add your RFC!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In-world join the group &amp;quot;SL Mail&amp;quot; for bug reports, feature requests, the latest SL Mail release, and notices about development issues.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scripts=&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==Script: SL Mail v1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail core module which scans for incoming mail messages and executes commands used by the owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail V1.2.lsl&lt;br /&gt;
// (c) 2007 Logic Scripted Products and Script Services&lt;br /&gt;
// Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
// VERSION&lt;br /&gt;
// Version: 1.2&lt;br /&gt;
&lt;br /&gt;
// HISTORY&lt;br /&gt;
// Date         Version     Author              Comment&lt;br /&gt;
// --------------------------------------------------------------------------------------&lt;br /&gt;
// 28 aug 2007  V 1.0       Flennan Roffo       Created&lt;br /&gt;
//&lt;br /&gt;
//  1 sep 2007  V 1.1       Flennan Roffo       @Reply empties the recording buffer.&lt;br /&gt;
//                                                @Send while recording ends recording&lt;br /&gt;
//                                                and sends the mail if a mail address&lt;br /&gt;
//                                                and subject are supplied.&lt;br /&gt;
//                                                Fixed incorrect date in Unix2DateTime.&lt;br /&gt;
//  3 sep 2007  V 1.2       Flennan Roffo       Notification options:&lt;br /&gt;
//                                              - When online, send an IM when mail is received.&lt;br /&gt;
//                                              - When offline, send to HOME mail adress.&lt;br /&gt;
//                                              Adressbook&lt;br /&gt;
//                                              - Read adress book from config notecard.&lt;br /&gt;
&lt;br /&gt;
// LICENCE&lt;br /&gt;
// This program is free software; you can redistribute it and/or&lt;br /&gt;
// modify it under the terms of the GNU General Public License&lt;br /&gt;
// as published by the Free Software Foundation; either version 2&lt;br /&gt;
// of the License, or (at your option) any later version.&lt;br /&gt;
// &lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
// &lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program; if not, write to the Free Software&lt;br /&gt;
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
// (Also available at http://www.gnu.org/copyleft/gpl.html) &lt;br /&gt;
&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// Let&#039;s you record a message and sent to email and get messages and reply to messages.&lt;br /&gt;
// Must supply a valid mail adress and non-empty subject using chat commands.&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
// 1) Check for the maximum length of an email message (including newline and header).&lt;br /&gt;
// 2) Read adress book from notecard.                                    *DONE*&lt;br /&gt;
// 3) Send incoming mail to personal mail adress when offline.            *DONE*&lt;br /&gt;
// 4) Alert with an IM when online upon receiving new mail.                *DONE*&lt;br /&gt;
&lt;br /&gt;
string   SL_MAIL_VERSION = &amp;quot;V 1.2&amp;quot;;&lt;br /&gt;
string   SL_MAIL_DATE    = &amp;quot; 2 sep 2007&amp;quot;;&lt;br /&gt;
integer  ErrorFlag         = FALSE;&lt;br /&gt;
list     ScriptList        = [ &amp;quot;SL Mail Help V1.2&amp;quot;, &amp;quot;SL Mail AddressBook V1.2&amp;quot;, &lt;br /&gt;
                                &amp;quot;SL Mail OnlineStatus V1.2&amp;quot;, &amp;quot;SL Mail FetchNotecard V1.2&amp;quot; ];    &lt;br /&gt;
string   LSL_DOMAIN=&amp;quot;lsl.secondlife.com&amp;quot;; &lt;br /&gt;
integer  StatusOnline=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Commands&lt;br /&gt;
&lt;br /&gt;
string  COMMAND_RECORD     = &amp;quot;@RECORD&amp;quot;;&lt;br /&gt;
string  COMMAND_CONTINUE   = &amp;quot;@CONTINUE&amp;quot;;&lt;br /&gt;
string  COMMAND_STOP       = &amp;quot;@STOP&amp;quot;;&lt;br /&gt;
string  COMMAND_MAIL       = &amp;quot;@MAIL&amp;quot;;&lt;br /&gt;
string  COMMAND_SUBJECT    = &amp;quot;@SUBJECT&amp;quot;;&lt;br /&gt;
string  COMMAND_SEND       = &amp;quot;@SEND&amp;quot;;&lt;br /&gt;
string  COMMAND_SEE        = &amp;quot;@SEE&amp;quot;;&lt;br /&gt;
string  COMMAND_IGNORE     = &amp;quot;@IGNORE&amp;quot;;&lt;br /&gt;
string  COMMAND_READ       = &amp;quot;@READ&amp;quot;;&lt;br /&gt;
string  COMMAND_DELETE     = &amp;quot;@DELETE&amp;quot;;&lt;br /&gt;
string  COMMAND_CLEAR      = &amp;quot;@CLEAR&amp;quot;;&lt;br /&gt;
string  COMMAND_REPLY      = &amp;quot;@REPLY&amp;quot;;&lt;br /&gt;
string  COMMAND_NEXT       = &amp;quot;@NEXT&amp;quot;;&lt;br /&gt;
string  COMMAND_PREV       = &amp;quot;@PREV&amp;quot;;&lt;br /&gt;
string  COMMAND_FIRST      = &amp;quot;@FIRST&amp;quot;;&lt;br /&gt;
string  COMMAND_LAST       = &amp;quot;@LAST&amp;quot;;&lt;br /&gt;
string  COMMAND_LIST       = &amp;quot;@LIST&amp;quot;;&lt;br /&gt;
string  COMMAND_SELECT     = &amp;quot;@SELECT&amp;quot;;&lt;br /&gt;
string  COMMAND_HELP       = &amp;quot;@HELP&amp;quot;;&lt;br /&gt;
string  COMMAND_INFO       = &amp;quot;@INFO&amp;quot;;&lt;br /&gt;
string  COMMAND_RESET      = &amp;quot;@RESET&amp;quot;;&lt;br /&gt;
string  COMMAND_SHOW       = &amp;quot;@SHOW&amp;quot;;&lt;br /&gt;
string  COMMAND_ON         = &amp;quot;@ON&amp;quot;;&lt;br /&gt;
string  COMMAND_OFF        = &amp;quot;@OFF&amp;quot;;&lt;br /&gt;
string  COMMAND_HOME       = &amp;quot;@HOME&amp;quot;;&lt;br /&gt;
string  COMMAND_LOAD       = &amp;quot;@LOAD&amp;quot;;&lt;br /&gt;
string  COMMAND_ADDRESS    = &amp;quot;@ADDRESS&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Recording&lt;br /&gt;
&lt;br /&gt;
integer Recording = FALSE;&lt;br /&gt;
&lt;br /&gt;
list    ChatRecording=[];&lt;br /&gt;
integer NumLines=0;&lt;br /&gt;
integer Length=0;&lt;br /&gt;
&lt;br /&gt;
list     TimeList=[];&lt;br /&gt;
list     AddressList=[];&lt;br /&gt;
list     SubjectList=[];&lt;br /&gt;
list     BodyList=[];&lt;br /&gt;
integer  NumMessages=0;&lt;br /&gt;
integer  CurrentMessage=-1;&lt;br /&gt;
&lt;br /&gt;
float    MAIL_FETCH_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
// Link Messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP                        = 10000;&lt;br /&gt;
integer MSG_STATUS_ONLINE               = 30000;&lt;br /&gt;
integer MSG_STATUS_OFFLINE              = 30100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED          = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR           = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Unix Time conversion //////////////////&lt;br /&gt;
&lt;br /&gt;
integer DAYS_PER_YEAR        = 365;                // Non leap year&lt;br /&gt;
integer SECONDS_PER_YEAR     = 31536000;          // Non leap year&lt;br /&gt;
integer SECONDS_PER_DAY      = 86400;&lt;br /&gt;
integer SECONDS_PER_HOUR     = 3600;&lt;br /&gt;
integer SECONDS_PER_MINUTE   = 60;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// LeapYear() /////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer LeapYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (year % 4 == 0)&lt;br /&gt;
    {&lt;br /&gt;
        if (year % 100 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (year % 400 == 0)&lt;br /&gt;
            {&lt;br /&gt;
                return 1;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// DaysPerMonth() ///////////////////////////////////////&lt;br /&gt;
                &lt;br /&gt;
integer DaysPerMonth(integer year,integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;lt; 8)&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (month == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if (LeapYear(year))&lt;br /&gt;
                {&lt;br /&gt;
                    return 29;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    return 28;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 30;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 30;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////// DaysPerYear() ////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DaysPerYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (LeapYear(year))&lt;br /&gt;
        return DAYS_PER_YEAR + 1;&lt;br /&gt;
    else&lt;br /&gt;
        return DAYS_PER_YEAR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Unix2DataTime() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list Unix2DateTime(integer unixtime)&lt;br /&gt;
{&lt;br /&gt;
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;&lt;br /&gt;
    integer day = days_since_1_1_1970 + 1;&lt;br /&gt;
    integer year  = 1970;&lt;br /&gt;
    integer days_per_year = DaysPerYear(year);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_year)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_year;&lt;br /&gt;
        ++year;&lt;br /&gt;
        days_per_year = DaysPerYear(year);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer month = 1;&lt;br /&gt;
    integer days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_month)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_month;&lt;br /&gt;
        &lt;br /&gt;
        if (++month &amp;gt; 12)&lt;br /&gt;
        {    &lt;br /&gt;
            ++year;&lt;br /&gt;
            month = 1;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;&lt;br /&gt;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;&lt;br /&gt;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;&lt;br /&gt;
    integer minute      = second / SECONDS_PER_MINUTE;&lt;br /&gt;
    second               = second % SECONDS_PER_MINUTE;&lt;br /&gt;
    &lt;br /&gt;
    return [ year, month, day, hour, minute, second ];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// MonthName() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list MonthNameList = [     &amp;quot;JAN&amp;quot;, &amp;quot;FEB&amp;quot;, &amp;quot;MAR&amp;quot;, &amp;quot;APR&amp;quot;, &amp;quot;MAY&amp;quot;, &amp;quot;JUN&amp;quot;, &lt;br /&gt;
                        &amp;quot;JUL&amp;quot;, &amp;quot;AUG&amp;quot;, &amp;quot;SEP&amp;quot;, &amp;quot;OCT&amp;quot; , &amp;quot;NOV&amp;quot;, &amp;quot;DEC&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
string MonthName(integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;gt;= 0 &amp;amp;&amp;amp; month &amp;lt; 12)&lt;br /&gt;
        return llList2String(MonthNameList, month);&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// DateString() ///////////////////////////&lt;br /&gt;
&lt;br /&gt;
string DateString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer year       = llList2Integer(timelist,0);&lt;br /&gt;
    integer month      = llList2Integer(timelist,1);&lt;br /&gt;
    integer day        = llList2Integer(timelist,2);&lt;br /&gt;
    &lt;br /&gt;
    return (string)day + &amp;quot;-&amp;quot; + MonthName(month - 1) + &amp;quot;-&amp;quot; + (string)year;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// TimeString() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string TimeString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer hour          = llList2Integer(timelist,3);&lt;br /&gt;
    integer minute         = llList2Integer(timelist,4);&lt;br /&gt;
    integer second         = llList2Integer(timelist,5);&lt;br /&gt;
    string  hourstr     = (string)hour;&lt;br /&gt;
    string  minutestr   = (string)minute;&lt;br /&gt;
    string  secondstr   = (string)second;&lt;br /&gt;
    &lt;br /&gt;
    if (hour &amp;lt; 10)         hourstr     = &amp;quot;0&amp;quot; + hourstr;&lt;br /&gt;
    if (minute &amp;lt; 10)     minutestr     = &amp;quot;0&amp;quot; + minutestr;&lt;br /&gt;
    if (second &amp;lt; 10)    secondstr    = &amp;quot;0&amp;quot; + secondstr;&lt;br /&gt;
    return hourstr + &amp;quot;:&amp;quot; + minutestr + &amp;quot;:&amp;quot; + secondstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() /////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string body)&lt;br /&gt;
{&lt;br /&gt;
    // llOwnerSay(&amp;quot;Sending message to &#039;&amp;quot; + address + &amp;quot;&#039; with subject &#039;&amp;quot; + subject +&amp;quot;&#039;.&amp;quot;);&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND, body, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// SendHome() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendHome(string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SENDHOME, body, (key)subject);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Show() ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Show()&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;Current chat recording is:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; NumLines; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(ChatRecording,i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;Lines is &amp;quot; + (string)NumLines);&lt;br /&gt;
    llOwnerSay(&amp;quot;Message length is &amp;quot; + (string)Length);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Read() /////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Read()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;Reading message &amp;quot; + (string)CurrentMessage + &amp;quot; from mail buffer.&amp;quot;);&lt;br /&gt;
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);&lt;br /&gt;
    list timelist=Unix2DateTime(time);&lt;br /&gt;
    string Address = llList2String(AddressList,CurrentMessage);&lt;br /&gt;
    string Subject = llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
    string Body    = llList2String(BodyList,CurrentMessage);&lt;br /&gt;
    llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Address: &amp;quot; + Address);&lt;br /&gt;
    llOwnerSay(&amp;quot;Subject: &amp;quot; + Subject);&lt;br /&gt;
    llOwnerSay(&amp;quot;Begin of message body:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    list bodylist=llParseStringKeepNulls(Body, [ &amp;quot;\n&amp;quot; ], []);&lt;br /&gt;
    integer num=llGetListLength(bodylist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(bodylist,i));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;End of message body.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////// List ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
List()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;The mail buffer contains the following messages:\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; NumMessages; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer time=llList2Integer(TimeList,i);&lt;br /&gt;
        list timelist=Unix2DateTime(time);&lt;br /&gt;
        if (i &amp;gt; 0) llOwnerSay(&amp;quot;+-+-+-+-+-+-+-+-+-+-+-+-&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Message: &amp;quot; + (string)i);&lt;br /&gt;
        llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;From:    &amp;quot; + llList2String(AddressList,i));&lt;br /&gt;
        llOwnerSay(&amp;quot;Subject: &amp;quot; + llList2String(SubjectList,i));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////// NotifyNewMail() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
NotifyNewMail(string time, string address, string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    list timelist=Unix2DateTime((integer)time);&lt;br /&gt;
&lt;br /&gt;
    if (StatusOnline)&lt;br /&gt;
    {&lt;br /&gt;
        llInstantMessage(llGetOwner(), &amp;quot;You received a new mail message on &amp;quot; &lt;br /&gt;
                                    + DateString(timelist) + &amp;quot; at &amp;quot; + TimeString(timelist)&lt;br /&gt;
                                    + &amp;quot; from &amp;quot; + address &lt;br /&gt;
                                    + &amp;quot; with the subject &amp;quot; + subject);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        SendHome(&amp;quot;FW: &amp;quot; + subject, &amp;quot;Received at: &amp;quot; + DateString(timelist) + &amp;quot; &amp;quot; + TimeString(timelist) + &amp;quot;\nFrom: &amp;quot; +  address &lt;br /&gt;
                    + &amp;quot;\nBegin message body:\n-------------------\n&amp;quot; + body + &amp;quot;\n-------------------\nEnd message body.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ResetOtherScripts() //////////////////////&lt;br /&gt;
&lt;br /&gt;
ResetOtherScripts()&lt;br /&gt;
{&lt;br /&gt;
    string     name;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(ScriptList);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        name = llList2String(ScriptList,i);&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(name) == INVENTORY_SCRIPT)&lt;br /&gt;
        {&lt;br /&gt;
            llResetOtherScript(name);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Error - script &#039;&amp;quot; + name + &amp;quot;&#039; not found.&amp;quot;);&lt;br /&gt;
            ErrorFlag = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
// default &lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ////////////////////// state_entry() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Welcome to SL Mail, released under GNU software licence.&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Version &amp;quot; + SL_MAIL_VERSION + &amp;quot; &amp;quot; + SL_MAIL_DATE);&lt;br /&gt;
        llOwnerSay(&amp;quot;Produced by Logic Scripted Products &amp;amp; Product Services&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Free memory: &amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
        ResetOtherScripts();&lt;br /&gt;
        &lt;br /&gt;
        if (ErrorFlag)&lt;br /&gt;
            state Error;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// on_rez() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// changed() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_LOADED)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_ERROR)&lt;br /&gt;
        {&lt;br /&gt;
            state Error;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() //////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(MAIL_FETCH_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //////////////////////// on_rez() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// listen() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string trimmessage=llStringTrim(message,STRING_TRIM);&lt;br /&gt;
        list   parse = llParseStringKeepNulls(trimmessage, [ &amp;quot; &amp;quot;], []);&lt;br /&gt;
        string command = llToUpper(llList2String(parse,0));&lt;br /&gt;
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        integer nargs  = llGetListLength(parse);&lt;br /&gt;
        string argstr=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (nargs &amp;gt; 1) argstr=llGetSubString(message, llSubStringIndex(message, &amp;quot; &amp;quot;) + 1, -1);&lt;br /&gt;
            &lt;br /&gt;
        if (Recording)&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Recording stopped. Type @SHOW to see the message you have entered,&amp;quot;&lt;br /&gt;
                            + &amp;quot; or @SEND to send it.&amp;quot;);&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                &lt;br /&gt;
                SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];&lt;br /&gt;
                ++NumLines;&lt;br /&gt;
                Length += llStringLength(message) + 2;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_RECORD)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Start recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                ChatRecording = [];&lt;br /&gt;
                NumLines=0;&lt;br /&gt;
                Length=0;&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CONTINUE)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Continue recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_REPLY)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    string address=llList2String(AddressList,CurrentMessage);&lt;br /&gt;
                    string subject=&amp;quot;Re: &amp;quot; + llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, address, NULL_KEY);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, subject, NULL_KEY);&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines=0;&lt;br /&gt;
                    Length=0;&lt;br /&gt;
                    Recording = TRUE;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_MAIL)&lt;br /&gt;
            {&lt;br /&gt;
                string mailaddress=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailaddress != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, mailaddress, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETADDRESS, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SUBJECT)&lt;br /&gt;
            {&lt;br /&gt;
                string mailsubject=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailsubject != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, mailsubject, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETSUBJECT, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Not recording.&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    if (NumLines == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND_NOTECARD, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_IGNORE)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines = 0;&lt;br /&gt;
                    Length = 0;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Show();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_READ)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumMessages == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Read();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        ++CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        --CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_FIRST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = 0;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LAST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LIST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    List();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SELECT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;Need to supply a message number.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    integer msgnum = (integer)arg;&lt;br /&gt;
                     &lt;br /&gt;
                    if (msgnum &amp;lt; 0 || msgnum &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Message number &amp;quot; + arg + &amp;quot; not in mail buffer.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = msgnum;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_DELETE)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    --NumMessages;&lt;br /&gt;
                     &lt;br /&gt;
                    if (NumMessages == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = -1;&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (CurrentMessage &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CLEAR)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList=[];&lt;br /&gt;
                    AddressList=[];&lt;br /&gt;
                    SubjectList=[];&lt;br /&gt;
                    BodyList=[];&lt;br /&gt;
                    NumMessages=0;&lt;br /&gt;
                    CurrentMessage=-1;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_HELP, arg, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_INFO)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                Show();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_RESET)&lt;br /&gt;
            {&lt;br /&gt;
                llResetScript();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                state not_running;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HOME)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs==1)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETHOME, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETHOME, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// email() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    email(string time, string address, string subject, string body, integer queued)&lt;br /&gt;
    {&lt;br /&gt;
        NotifyNewMail(time, address, subject, body);&lt;br /&gt;
        TimeList = (TimeList=[]) + TimeList + [time];&lt;br /&gt;
        AddressList = (AddressList=[]) + AddressList + [address];&lt;br /&gt;
        SubjectList = (SubjectList=[]) + SubjectList + [subject];&lt;br /&gt;
        BodyList = (BodyList=[]) + BodyList + [body];&lt;br /&gt;
        ++NumMessages;&lt;br /&gt;
        &lt;br /&gt;
        if (CurrentMessage == -1)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = NumMessages - 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_REPLY)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state not_running&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state not_running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;SL Mailbox switched OFF. Say @ON to switch it back on.&amp;quot;);&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// on_rez() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// listen() ////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer chan, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string command=llToUpper(message);&lt;br /&gt;
        &lt;br /&gt;
        if (command == COMMAND_ON)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state Error&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state Error&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Error in SL Mail: not all component scripts found.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// End SL Mail V1.2.lsl&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Address Book V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Read and interpret the contents of the Address Book.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail AddressBook V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// &lt;br /&gt;
//  Read the Address Book from a notecard named &amp;quot;Address Book&amp;quot;.&lt;br /&gt;
//&lt;br /&gt;
//  The Address Book has the following format:&lt;br /&gt;
//  &lt;br /&gt;
//  [ADDRESS BOOK]&lt;br /&gt;
//  Name1=username@yourdomain.com&lt;br /&gt;
//  Name2=otheruser@otherdomain.com&lt;br /&gt;
//  ...&lt;br /&gt;
//  [GROUP]&lt;br /&gt;
//  group1=Name1, Name2&lt;br /&gt;
//  ...&lt;br /&gt;
//&lt;br /&gt;
//  Notes:&lt;br /&gt;
//  1. Group and Name share the same namespace, and must be unique.&lt;br /&gt;
//  2. It is allowed to have a name in the addressbook with multiple addresses, seperated by comma&#039;s.&lt;br /&gt;
// &lt;br /&gt;
/////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string  CurrentMailAddress = &amp;quot;&amp;quot;;&lt;br /&gt;
string  CurrentMailSubject = &amp;quot;&amp;quot;;&lt;br /&gt;
integer StatusOnline = FALSE;&lt;br /&gt;
&lt;br /&gt;
// Fetch or Send notecard&lt;br /&gt;
&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Names&lt;br /&gt;
&lt;br /&gt;
list    AddressBookList=[];&lt;br /&gt;
list    MailAddressList=[];&lt;br /&gt;
&lt;br /&gt;
string  STRING_HOME=&amp;quot;HOME&amp;quot;;&lt;br /&gt;
string  STRING_SELF=&amp;quot;SELF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Groups&lt;br /&gt;
&lt;br /&gt;
list   GroupList=[];&lt;br /&gt;
list   GroupNameList=[];&lt;br /&gt;
&lt;br /&gt;
string LSL_DOMAIN = &amp;quot;lsl.secondlife.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Read Address Book notecard&lt;br /&gt;
&lt;br /&gt;
string  ADDRESSBOOK_NOTECARD=&amp;quot;Address Book&amp;quot;;&lt;br /&gt;
integer Line=0;&lt;br /&gt;
key     reqAddressBook=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
integer Section=0;&lt;br /&gt;
integer SECTION_ADDRESS_BOOK=1;&lt;br /&gt;
integer SECTION_GROUP=2;&lt;br /&gt;
string  STRING_ADDRESS_BOOK=&amp;quot;ADDRESS BOOK&amp;quot;;&lt;br /&gt;
string  STRING_GROUP=&amp;quot;GROUP&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Links messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
integer MSG_MESSAGE_NOTIFY              = 90900;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED            = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR            = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// GetSelfAddress() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
string GetSelfAddress()&lt;br /&gt;
{&lt;br /&gt;
    return (string)llGetKey() + &amp;quot;@&amp;quot; + LSL_DOMAIN;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Info() /////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Info()&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;The mail address for this object is: &amp;quot; &lt;br /&gt;
                    + GetSelfAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// IsValidKeyFormat() //////////////////////&lt;br /&gt;
&lt;br /&gt;
integer IsValidKeyFormat(string str)&lt;br /&gt;
{&lt;br /&gt;
    string keychars = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    if (llStringLength(str) != 36)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    if( (llGetSubString( str, 8, 8 )   != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 13, 13 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 18, 18 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 23, 23 )  != &amp;quot;-&amp;quot; ) )&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 9; i &amp;lt; 13; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 14; i &amp;lt; 18; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 19; i &amp;lt; 23; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 24; i &amp;lt; 36; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// ValidMailAddress() ////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer ValidMailAddress(string arg)&lt;br /&gt;
{&lt;br /&gt;
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));&lt;br /&gt;
    &lt;br /&gt;
    if (adress == &amp;quot;&amp;quot;)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    list parse = llParseStringKeepNulls(adress, [ &amp;quot;@&amp;quot; ], []);&lt;br /&gt;
    string account = llList2String(parse,0);&lt;br /&gt;
    string domain  = llList2String(parse,1);&lt;br /&gt;
    &lt;br /&gt;
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    &lt;br /&gt;
    if (domain == LSL_DOMAIN)&lt;br /&gt;
    {&lt;br /&gt;
        return IsValidKeyFormat(account);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list parsedomain = llParseString2List(domain, [ &amp;quot;.&amp;quot; ], []);&lt;br /&gt;
    &lt;br /&gt;
        if (llGetListLength(parsedomain) &amp;lt; 2)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        &lt;br /&gt;
        integer num = llGetListLength(parsedomain);&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llStringLength(llList2String(parsedomain,i)) &amp;lt; 2)&lt;br /&gt;
            {&lt;br /&gt;
                return FALSE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetAddressStr() ///////////////////&lt;br /&gt;
&lt;br /&gt;
string GetAndCheckAddressStr(string address)&lt;br /&gt;
{&lt;br /&gt;
    list addresslist = llCSV2List(address);&lt;br /&gt;
    integer num=llGetListLength(addresslist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    string addressstr=&amp;quot;&amp;quot;;&lt;br /&gt;
    string curaddress=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        curaddress=llList2String(addresslist,i);&lt;br /&gt;
        &lt;br /&gt;
        if (ValidMailAddress(curaddress))&lt;br /&gt;
        {&lt;br /&gt;
            addressstr = (addressstr=&amp;quot;&amp;quot;) + addressstr + curaddress + &amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address string: &#039;&amp;quot; &lt;br /&gt;
                            + curaddress + &amp;quot;&#039;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return llGetSubString(addressstr, 0, -2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ProcessLine() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
ProcessLine(string rawline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(rawline,STRING_TRIM);&lt;br /&gt;
    string first=llGetSubString(line,0,0);&lt;br /&gt;
    string last=llGetSubString(line,-1,-1);&lt;br /&gt;
    &lt;br /&gt;
    // Ignore a blank line or comment line&lt;br /&gt;
    if (line == &amp;quot;&amp;quot; || first == &amp;quot;#&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // Check for the right section&lt;br /&gt;
    &lt;br /&gt;
    if (first == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; last == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        string sectionstr=llToUpper(llStringTrim(llGetSubString(line,1,-2),STRING_TRIM));&lt;br /&gt;
        &lt;br /&gt;
        if (sectionstr == STRING_ADDRESS_BOOK)&lt;br /&gt;
        {&lt;br /&gt;
            Section = SECTION_ADDRESS_BOOK;&lt;br /&gt;
        }&lt;br /&gt;
        else if (sectionstr == STRING_GROUP)&lt;br /&gt;
        {&lt;br /&gt;
            if (Section == 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                        + &amp;quot;. Group section defined before Address Book section.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Section = SECTION_GROUP;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid section header &#039;&amp;quot; + sectionstr &lt;br /&gt;
                        + &amp;quot;&#039; in &amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Must be in a section&lt;br /&gt;
    &lt;br /&gt;
    if (Section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;. No section header.&amp;quot;, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    list     parse=llParseString2List(line, [ &amp;quot;=&amp;quot; ], []);&lt;br /&gt;
    integer  num=llGetListLength(parse);&lt;br /&gt;
    &lt;br /&gt;
    // Format must be correct&lt;br /&gt;
    &lt;br /&gt;
    if (num != 2)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; +  (string)(Line+1) + &amp;quot;:\n&amp;quot; + rawline, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (Section == SECTION_ADDRESS_BOOK)&lt;br /&gt;
    {&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(name) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + name &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ name ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            string address=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
            string addressstr=GetAndCheckAddressStr(address);&lt;br /&gt;
            &lt;br /&gt;
            if (addressstr != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                AddressBookList     = (AddressBookList=[])     + AddressBookList     + [ name ];&lt;br /&gt;
                MailAddressList     = (MailAddressList=[])     + MailAddressList     + [ addressstr ];&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;No valid mail address for &#039;&amp;quot; + name &lt;br /&gt;
                    + &amp;quot;&#039;. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                    + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name &lt;br /&gt;
                + &amp;quot;&#039; already defined. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // Group&lt;br /&gt;
    {&lt;br /&gt;
        string group=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(group) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + group &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ group ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(GroupList, [ group ]) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                string names=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
                list   namelist=llCSV2List(names);&lt;br /&gt;
                integer num=llGetListLength(namelist);&lt;br /&gt;
                integer i;&lt;br /&gt;
                integer index;&lt;br /&gt;
                string  name;&lt;br /&gt;
                string  namestr=&amp;quot;&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
                for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                    name=llList2String(namelist,i);&lt;br /&gt;
                    index=llListFindList(AddressBookList, [ name ]);&lt;br /&gt;
            &lt;br /&gt;
                    if (index == -1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name + &amp;quot;&#039; defined in Group &#039;&amp;quot; &lt;br /&gt;
                                + group + &amp;quot;&#039; not found in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY); &lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        namestr = (namestr=&amp;quot;&amp;quot;) + namestr + name + &amp;quot;,&amp;quot;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (namestr != &amp;quot;&amp;quot;)&lt;br /&gt;
                {    &lt;br /&gt;
                    namestr=llGetSubString(namestr,0,-2);&lt;br /&gt;
                    GroupList         = (GroupList=[])         + GroupList     + [ group ];&lt;br /&gt;
                    GroupNameList     = (GroupNameList=[])    + GroupNameList + [ namestr ];&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                        + &amp;quot;&#039; has no valid names. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                        + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                    + &amp;quot;&#039; already defined in Group. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                    + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group&lt;br /&gt;
                + &amp;quot;&#039; already defined in Address Book. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// GetGroupAddressList ///////////////&lt;br /&gt;
&lt;br /&gt;
string GetGroupAddressList(string group)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(GroupList, [ group ]);&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(GroupList);&lt;br /&gt;
    string  grouplist=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        for (i = index; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2String(GroupList,i) == group)&lt;br /&gt;
            {&lt;br /&gt;
                grouplist = (grouplist=&amp;quot;&amp;quot;) + grouplist + llList2String(GroupNameList,i) + &amp;quot;,&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (grouplist != &amp;quot;&amp;quot;) grouplist=llGetSubString(grouplist,0,-2);   // remove last &amp;quot;,&amp;quot;&lt;br /&gt;
        return grouplist;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// SetMailAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetMailAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ address ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        index=llListFindList(GroupList, [ address ]);&lt;br /&gt;
        &lt;br /&gt;
        if (index == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llToUpper(address) == STRING_SELF)&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = GetSelfAddress();&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if(ValidMailAddress(address))&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = address;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Mail adress &amp;quot; + address &lt;br /&gt;
                            + &amp;quot; : not found in adress book or invalid format.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailAddress = GetGroupAddressList(address);&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        CurrentMailAddress = llList2String(MailAddressList,index);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                        + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string message)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No mail address defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No subject defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list mailaddresslist=llCSV2List(CurrentMailAddress);&lt;br /&gt;
        integer num=llGetListLength(mailaddresslist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(mailaddresslist,i);&lt;br /&gt;
            llEmail(address, CurrentMailSubject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMailHome() ////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMailHome(string message, string subject)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, STRING_HOME &lt;br /&gt;
                + &amp;quot; not set. Set your home adress with @HOME &amp;lt;address&amp;gt;.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        string homeaddress=llList2String(AddressBookList,index);&lt;br /&gt;
        list   homelist=llCSV2List(homeaddress);&lt;br /&gt;
        integer num=llGetListLength(homelist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(homelist,i);&lt;br /&gt;
            llEmail(address, subject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
string GetHomeAddress()&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;not set&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2String(MailAddressList,index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetHomeAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        AddressBookList     = (AddressBookList=[]) + [ STRING_HOME ] + AddressBookList;&lt;br /&gt;
        MailAddressList     = (MailAddressList=[]) + [ GetAndCheckAddressStr(address) ]  + MailAddressList;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MailAddressList = llListReplaceList(MailAddressList, [ GetAndCheckAddressStr(address) ], index, index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        Line=0;&lt;br /&gt;
        Section=0;&lt;br /&gt;
        llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// dataserver() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqAddressBook)&lt;br /&gt;
        {&lt;br /&gt;
            reqAddressBook = NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                ProcessLine(data);&lt;br /&gt;
                reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Address Book loaded.&amp;quot;, NULL_KEY);&lt;br /&gt;
                state running;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// timer() ///////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_ERROR, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Could not read Address Book: &amp;quot; &lt;br /&gt;
                            + ADDRESSBOOK_NOTECARD + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// link_message() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_MESSAGE_GETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is empty.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailSubject = message;&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is empty.&amp;quot;, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            SetMailAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Body of message to send is empty. &amp;quot; &lt;br /&gt;
                                +  &amp;quot;No mail is send.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SENDHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SendMailHome(message, (string)id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetInventoryType(message) == INVENTORY_NOTECARD)&lt;br /&gt;
            {&lt;br /&gt;
                Notecard2Fetch = message;                &lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_READ, message, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + message + &amp;quot; not found.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_NOTECARD_FETCHED)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + Notecard2Fetch &lt;br /&gt;
                            + &amp;quot; was empty or could not be read.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Home address is: &amp;quot; + GetHomeAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SetHomeAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_INFO)&lt;br /&gt;
        {&lt;br /&gt;
            Info();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
// End SL Mail AddressBook V1.2.lsl&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail FetchNotecard V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch the contents of a notecard and return it via link message as a string.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Notecard&lt;br /&gt;
&lt;br /&gt;
integer Line=0;&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
key     reqNotecard=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=10.0;&lt;br /&gt;
integer Fetched=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Lines&lt;br /&gt;
&lt;br /&gt;
list LineList=[];&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    /////////////////////// dataserver() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqNotecard)&lt;br /&gt;
        {&lt;br /&gt;
            reqNotecard=NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                LineList = (LineList=[]) + LineList + [ data ];&lt;br /&gt;
                reqNotecard = llGetNotecardLine(Notecard2Fetch, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Fetched=TRUE;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, llDumpList2String(LineList, &amp;quot;\n&amp;quot;), NULL_KEY);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /////////////////////// timer() ///////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        if (!Fetched)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            llSetTimerEvent(0.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer send, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_NOTECARD_READ)&lt;br /&gt;
        {&lt;br /&gt;
            Line=0;&lt;br /&gt;
            Notecard2Fetch=message;&lt;br /&gt;
            LineList=[];&lt;br /&gt;
            Fetched=FALSE;&lt;br /&gt;
            reqNotecard=llGetNotecardLine(Notecard2Fetch, Line);&lt;br /&gt;
            llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL OnlineStatus V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch online status of owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Online status&lt;br /&gt;
&lt;br /&gt;
key     reqOnlineStatus=NULL_KEY;&lt;br /&gt;
float   STATUS_INTERVAL=2.0;&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_STATUS_ONLINE       = 30000;&lt;br /&gt;
integer MS_STATUS_OFFLINE       = 30100;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus=llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
        llSetTimerEvent(STATUS_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// dataserver() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqOnlineStatus)&lt;br /&gt;
        {&lt;br /&gt;
            reqOnlineStatus = NULL_KEY;&lt;br /&gt;
        &lt;br /&gt;
            if (data==&amp;quot;1&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_STATUS_ONLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if (data==&amp;quot;0&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MS_STATUS_OFFLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus = llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Help V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Display help information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail Help V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP    = 10000;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Help() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Help()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;HELP for SL Mail V1.2.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;COMMANDS:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HELP               - displays help info.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@INFO               - display mailaddress of this object.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RECORD             - start recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CONTINUE           - continue recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@STOP               - stop recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@IGNORE             - ignore the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SHOW               - show what your recorded.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SEND               - send the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@MAIL &amp;lt;mailadress&amp;gt;  - set the mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SUBJECT subject    - set the mail subject.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LIST               - list messages in mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SELECT &amp;lt;message&amp;gt;   - select message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@READ               - read current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@NEXT               - read next message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@PREV               - read previous message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@FIRST              - read first message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LAST               - read last message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@DELETE             - delete current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CLEAR              - clear the mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@REPLY              - reply to current message.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RESET              - reset the script.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HOME               - set the home mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@OFF                - switch mailbox OFF.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@ON                 - switch mailbox ON.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_HELP)&lt;br /&gt;
        {&lt;br /&gt;
            Help();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail Help V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}&lt;/div&gt;</description>
			<pubDate>Sun, 07 Oct 2007 10:21:16 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:SL_Mail_V1.2</comments>
		</item>
		<item>
			<title>SL Mail V1.2</title>
			<link>https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34584</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34584</guid>
			<description>&lt;p&gt;Flennan Roffo: /* &amp;#039;&amp;#039;&amp;#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&amp;#039;&amp;#039;&amp;#039;= */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}} __NOTOC__&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=&#039;&#039;&#039;Second Life mail client&#039;&#039;&#039;=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Send and receive email from within Second Life from and to any address.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implemented with Address Book function (in a notecard named &#039;Address Book&#039;) to stores addresses by name  and to compile groups of named addresses. Current version is stand-alone (no server functionality) and uses chat commands only.&lt;br /&gt;
&lt;br /&gt;
[[Image:BannerSLMail.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=Release Notes V1.2=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 Release notes (edition 2, 4 sept 2007)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LICENCE INFO&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is released under GNU free software licence&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;PRODUCTION &amp;amp; MAINTANENCE&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
by Logic Scripted Products and Script Services&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
SLurl:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Contact: [[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;DESCRIPTION&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is a simple tool to send and receive mail from within SL.&lt;br /&gt;
You can either compose a message yourself using chat recording, or choose a notecard from inventory to send. The Address Book functionality allows you to use short names for mail recipients stored in a notecard. The current version does not have a persisent mail address. Watch out for the upcoming next release (V1.3) which will facilitate persisent in-world mail addresses and will be enhanced with many new features (See: Requests For Change (RFC).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;COMMANDS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Help&#039;&#039;&#039;&lt;br /&gt;
||Show Help about available commands&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Record&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording (for owner only).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Stop&#039;&#039;&#039;&lt;br /&gt;
||Stops the chat recording without sending&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Continue&#039;&#039;&#039;&lt;br /&gt;
||Continues a previously stopped chat recording. Lines will be appended to you recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Show&#039;&#039;&#039;&lt;br /&gt;
||Shows the content of the recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send&#039;&#039;&#039;&lt;br /&gt;
||If recording, stops the recording, and sends the mail (need to supply mail address and subject first!)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send &amp;lt;notecard&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Sends the content of the notecard, instead of the chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Ignore&#039;&#039;&#039;&lt;br /&gt;
||Ignores your current chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject &amp;lt;subject&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the subject of the mail.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail subject.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Set the HOME address of the owner (mail will be forwarder to this address when offline).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home&#039;&#039;&#039;&lt;br /&gt;
||Show the HOME address.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Info&#039;&#039;&#039;&lt;br /&gt;
||Shows the mail address the object this script is running in uses (e.g. &amp;lt;object-key&amp;gt;@lsl.secondlife.com).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Read&#039;&#039;&#039;&lt;br /&gt;
||Reads the current message from the mail buffer (the mail buffer gets filled with mail you receive)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Select &amp;lt;msg&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Select a message number from the availabe messages in the mail buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Next&#039;&#039;&#039;&lt;br /&gt;
||Make next message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Prev&#039;&#039;&#039;&lt;br /&gt;
||Make previous message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@First&#039;&#039;&#039;&lt;br /&gt;
||Make the first message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Last&#039;&#039;&#039;&lt;br /&gt;
||Make the last message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Clear&#039;&#039;&#039;&lt;br /&gt;
||Clear the mail buffer&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Delete&#039;&#039;&#039;&lt;br /&gt;
||Deletes only the current message&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Reply&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording to reply to the current message. Mail adress and subject are filled in automatically.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* Commands are case insensitive (&amp;quot;@read&amp;quot; == &amp;quot;@READ&amp;quot;). Arguments might not be case insensitive.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;ADDRESS BOOK FORMAT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
A notecard of the name &#039;Address Book&#039; is read during initialization which may contain Address Book items and Groups.&lt;br /&gt;
The notecard is split in two sections, which need to be defined in that particular order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[ADDRESS BOOK]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Defines the section in which you can put names for mail addresses,  like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name1=account@thisdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name2=user@otherdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[GROUP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define groups of previously defined names under a new name, like for instance:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyGroup=Name1, Name2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note that names of groups and individual mail adresses share the same namespace and must be unique.&lt;br /&gt;
&lt;br /&gt;
So when you filled in your mail adresses in the Address Book, you can now use:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail Name1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to  &amp;lt;account@thisdomain.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail MyGroup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to &amp;lt;account@thisdomain.com&amp;gt; and &amp;lt;user@otherdomain.com&amp;gt;&lt;br /&gt;
Mails will be sent one after another.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* Names for Addreses and Groups are case insensitive (e.g. &amp;quot;mary&amp;quot;  == &amp;quot;MARY&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* The special address &#039;Self&#039; can be used in commands where otherwise an address specification can be used. &#039;Self&#039; is case insensitive (e.g. &amp;quot;self&amp;quot; == &amp;quot;SELF&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LIMITATIONS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
The current version is limited by the following:&lt;br /&gt;
&lt;br /&gt;
* Chat recording lines are limited by the 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Output of lines from the mail buffer are also limited by this 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Incoming mail is limited to a 1000 (1024?) byte limit&lt;br /&gt;
&lt;br /&gt;
* Outgoing mai is limited by a 4096 byte limit, which includes the standard mail header (region/location info on the first two lines)&lt;br /&gt;
&lt;br /&gt;
We are making adjustments to this release to help overcome these limitations. At least the line lenght limit can be overcome by introducing a line continuation character (for example a hyphen &#039;-&#039;) that when used at the end of a line appends the next line, so lines longer then 255 bytes are possible then.&lt;br /&gt;
&lt;br /&gt;
To overcome the outgoing mail length limit, the mail can be broken textualy into parts, and each part can be send seperatedely, with an indication in the subject or in an introduced primary line of the mail body to indicate that the mail was split into parts.&lt;br /&gt;
For incoming mail and at least to receive mail from other SL Mail programs, a protocol will be introduced to receive mail in parts that are joined together after receiving them to form a single mail.&lt;br /&gt;
&lt;br /&gt;
These enhancements will be made available in the next release (V1.3) of SL Mail &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;BUGS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Report any bugs you find in this release to Logic (IM: Flennan Roffo).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;REQUEST FOR CHANGE (RFC)&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Do you have additional wishes for enhancement of this product?&lt;br /&gt;
Contact Flennan Roffo and we will see if they can be implemented in the next release.&lt;br /&gt;
&lt;br /&gt;
Existing RFC&#039;s are:&lt;br /&gt;
&lt;br /&gt;
* Menu support for commands.&lt;br /&gt;
&lt;br /&gt;
* Lines on incoming/outgoing mail longer than 255 bytes.&lt;br /&gt;
&lt;br /&gt;
* Send messages longer than 4096 (minus SL mail header) bytes.&lt;br /&gt;
&lt;br /&gt;
* Receive messages longer than 1024 bytes.&lt;br /&gt;
&lt;br /&gt;
* Permanent mail addresses for the SL Mail client (like: &amp;lt;Flennan.Roffo@somedomain.sl&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Add your RFC!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In-world join the group &amp;quot;SL Mail&amp;quot; for bug reports, feature requests, the latest SL Mail release, and notices about development issues.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scripts=&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==Script: SL Mail v1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail core module which scans for incoming mail messages and executes commands used by the owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail V1.2.lsl&lt;br /&gt;
// (c) 2007 Logic Scripted Products and Script Services&lt;br /&gt;
// Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
// VERSION&lt;br /&gt;
// Version: 1.2&lt;br /&gt;
&lt;br /&gt;
// HISTORY&lt;br /&gt;
// Date         Version     Author              Comment&lt;br /&gt;
// --------------------------------------------------------------------------------------&lt;br /&gt;
// 28 aug 2007  V 1.0       Flennan Roffo       Created&lt;br /&gt;
//&lt;br /&gt;
//  1 sep 2007  V 1.1       Flennan Roffo       @Reply empties the recording buffer.&lt;br /&gt;
//                                                @Send while recording ends recording&lt;br /&gt;
//                                                and sends the mail if a mail address&lt;br /&gt;
//                                                and subject are supplied.&lt;br /&gt;
//                                                Fixed incorrect date in Unix2DateTime.&lt;br /&gt;
//  3 sep 2007  V 1.2       Flennan Roffo       Notification options:&lt;br /&gt;
//                                              - When online, send an IM when mail is received.&lt;br /&gt;
//                                              - When offline, send to HOME mail adress.&lt;br /&gt;
//                                              Adressbook&lt;br /&gt;
//                                              - Read adress book from config notecard.&lt;br /&gt;
&lt;br /&gt;
// LICENCE&lt;br /&gt;
// This program is free software; you can redistribute it and/or&lt;br /&gt;
// modify it under the terms of the GNU General Public License&lt;br /&gt;
// as published by the Free Software Foundation; either version 2&lt;br /&gt;
// of the License, or (at your option) any later version.&lt;br /&gt;
// &lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
// &lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program; if not, write to the Free Software&lt;br /&gt;
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
// (Also available at http://www.gnu.org/copyleft/gpl.html) &lt;br /&gt;
&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// Let&#039;s you record a message and sent to email and get messages and reply to messages.&lt;br /&gt;
// Must supply a valid mail adress and non-empty subject using chat commands.&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
// 1) Check for the maximum length of an email message (including newline and header).&lt;br /&gt;
// 2) Read adress book from notecard.                                    *DONE*&lt;br /&gt;
// 3) Send incoming mail to personal mail adress when offline.            *DONE*&lt;br /&gt;
// 4) Alert with an IM when online upon receiving new mail.                *DONE*&lt;br /&gt;
&lt;br /&gt;
string   SL_MAIL_VERSION = &amp;quot;V 1.2&amp;quot;;&lt;br /&gt;
string   SL_MAIL_DATE    = &amp;quot; 2 sep 2007&amp;quot;;&lt;br /&gt;
integer  ErrorFlag         = FALSE;&lt;br /&gt;
list     ScriptList        = [ &amp;quot;SL Mail Help V1.2&amp;quot;, &amp;quot;SL Mail AddressBook V1.2&amp;quot;, &lt;br /&gt;
                                &amp;quot;SL Mail OnlineStatus V1.2&amp;quot;, &amp;quot;SL Mail FetchNotecard V1.2&amp;quot; ];    &lt;br /&gt;
string   LSL_DOMAIN=&amp;quot;lsl.secondlife.com&amp;quot;; &lt;br /&gt;
integer  StatusOnline=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Commands&lt;br /&gt;
&lt;br /&gt;
string  COMMAND_RECORD     = &amp;quot;@RECORD&amp;quot;;&lt;br /&gt;
string  COMMAND_CONTINUE   = &amp;quot;@CONTINUE&amp;quot;;&lt;br /&gt;
string  COMMAND_STOP       = &amp;quot;@STOP&amp;quot;;&lt;br /&gt;
string  COMMAND_MAIL       = &amp;quot;@MAIL&amp;quot;;&lt;br /&gt;
string  COMMAND_SUBJECT    = &amp;quot;@SUBJECT&amp;quot;;&lt;br /&gt;
string  COMMAND_SEND       = &amp;quot;@SEND&amp;quot;;&lt;br /&gt;
string  COMMAND_SEE        = &amp;quot;@SEE&amp;quot;;&lt;br /&gt;
string  COMMAND_IGNORE     = &amp;quot;@IGNORE&amp;quot;;&lt;br /&gt;
string  COMMAND_READ       = &amp;quot;@READ&amp;quot;;&lt;br /&gt;
string  COMMAND_DELETE     = &amp;quot;@DELETE&amp;quot;;&lt;br /&gt;
string  COMMAND_CLEAR      = &amp;quot;@CLEAR&amp;quot;;&lt;br /&gt;
string  COMMAND_REPLY      = &amp;quot;@REPLY&amp;quot;;&lt;br /&gt;
string  COMMAND_NEXT       = &amp;quot;@NEXT&amp;quot;;&lt;br /&gt;
string  COMMAND_PREV       = &amp;quot;@PREV&amp;quot;;&lt;br /&gt;
string  COMMAND_FIRST      = &amp;quot;@FIRST&amp;quot;;&lt;br /&gt;
string  COMMAND_LAST       = &amp;quot;@LAST&amp;quot;;&lt;br /&gt;
string  COMMAND_LIST       = &amp;quot;@LIST&amp;quot;;&lt;br /&gt;
string  COMMAND_SELECT     = &amp;quot;@SELECT&amp;quot;;&lt;br /&gt;
string  COMMAND_HELP       = &amp;quot;@HELP&amp;quot;;&lt;br /&gt;
string  COMMAND_INFO       = &amp;quot;@INFO&amp;quot;;&lt;br /&gt;
string  COMMAND_RESET      = &amp;quot;@RESET&amp;quot;;&lt;br /&gt;
string  COMMAND_SHOW       = &amp;quot;@SHOW&amp;quot;;&lt;br /&gt;
string  COMMAND_ON         = &amp;quot;@ON&amp;quot;;&lt;br /&gt;
string  COMMAND_OFF        = &amp;quot;@OFF&amp;quot;;&lt;br /&gt;
string  COMMAND_HOME       = &amp;quot;@HOME&amp;quot;;&lt;br /&gt;
string  COMMAND_LOAD       = &amp;quot;@LOAD&amp;quot;;&lt;br /&gt;
string  COMMAND_ADDRESS    = &amp;quot;@ADDRESS&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Recording&lt;br /&gt;
&lt;br /&gt;
integer Recording = FALSE;&lt;br /&gt;
&lt;br /&gt;
list    ChatRecording=[];&lt;br /&gt;
integer NumLines=0;&lt;br /&gt;
integer Length=0;&lt;br /&gt;
&lt;br /&gt;
list     TimeList=[];&lt;br /&gt;
list     AddressList=[];&lt;br /&gt;
list     SubjectList=[];&lt;br /&gt;
list     BodyList=[];&lt;br /&gt;
integer  NumMessages=0;&lt;br /&gt;
integer  CurrentMessage=-1;&lt;br /&gt;
&lt;br /&gt;
float    MAIL_FETCH_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
// Link Messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP                        = 10000;&lt;br /&gt;
integer MSG_STATUS_ONLINE               = 30000;&lt;br /&gt;
integer MSG_STATUS_OFFLINE              = 30100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED          = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR           = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Unix Time conversion //////////////////&lt;br /&gt;
&lt;br /&gt;
integer DAYS_PER_YEAR        = 365;                // Non leap year&lt;br /&gt;
integer SECONDS_PER_YEAR     = 31536000;          // Non leap year&lt;br /&gt;
integer SECONDS_PER_DAY      = 86400;&lt;br /&gt;
integer SECONDS_PER_HOUR     = 3600;&lt;br /&gt;
integer SECONDS_PER_MINUTE   = 60;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// LeapYear() /////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer LeapYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (year % 4 == 0)&lt;br /&gt;
    {&lt;br /&gt;
        if (year % 100 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (year % 400 == 0)&lt;br /&gt;
            {&lt;br /&gt;
                return 1;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// DaysPerMonth() ///////////////////////////////////////&lt;br /&gt;
                &lt;br /&gt;
integer DaysPerMonth(integer year,integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;lt; 8)&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (month == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if (LeapYear(year))&lt;br /&gt;
                {&lt;br /&gt;
                    return 29;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    return 28;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 30;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 30;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////// DaysPerYear() ////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DaysPerYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (LeapYear(year))&lt;br /&gt;
        return DAYS_PER_YEAR + 1;&lt;br /&gt;
    else&lt;br /&gt;
        return DAYS_PER_YEAR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Unix2DataTime() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list Unix2DateTime(integer unixtime)&lt;br /&gt;
{&lt;br /&gt;
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;&lt;br /&gt;
    integer day = days_since_1_1_1970 + 1;&lt;br /&gt;
    integer year  = 1970;&lt;br /&gt;
    integer days_per_year = DaysPerYear(year);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_year)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_year;&lt;br /&gt;
        ++year;&lt;br /&gt;
        days_per_year = DaysPerYear(year);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer month = 1;&lt;br /&gt;
    integer days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_month)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_month;&lt;br /&gt;
        &lt;br /&gt;
        if (++month &amp;gt; 12)&lt;br /&gt;
        {    &lt;br /&gt;
            ++year;&lt;br /&gt;
            month = 1;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;&lt;br /&gt;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;&lt;br /&gt;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;&lt;br /&gt;
    integer minute      = second / SECONDS_PER_MINUTE;&lt;br /&gt;
    second               = second % SECONDS_PER_MINUTE;&lt;br /&gt;
    &lt;br /&gt;
    return [ year, month, day, hour, minute, second ];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// MonthName() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list MonthNameList = [     &amp;quot;JAN&amp;quot;, &amp;quot;FEB&amp;quot;, &amp;quot;MAR&amp;quot;, &amp;quot;APR&amp;quot;, &amp;quot;MAY&amp;quot;, &amp;quot;JUN&amp;quot;, &lt;br /&gt;
                        &amp;quot;JUL&amp;quot;, &amp;quot;AUG&amp;quot;, &amp;quot;SEP&amp;quot;, &amp;quot;OCT&amp;quot; , &amp;quot;NOV&amp;quot;, &amp;quot;DEC&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
string MonthName(integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;gt;= 0 &amp;amp;&amp;amp; month &amp;lt; 12)&lt;br /&gt;
        return llList2String(MonthNameList, month);&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// DateString() ///////////////////////////&lt;br /&gt;
&lt;br /&gt;
string DateString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer year       = llList2Integer(timelist,0);&lt;br /&gt;
    integer month      = llList2Integer(timelist,1);&lt;br /&gt;
    integer day        = llList2Integer(timelist,2);&lt;br /&gt;
    &lt;br /&gt;
    return (string)day + &amp;quot;-&amp;quot; + MonthName(month - 1) + &amp;quot;-&amp;quot; + (string)year;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// TimeString() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string TimeString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer hour          = llList2Integer(timelist,3);&lt;br /&gt;
    integer minute         = llList2Integer(timelist,4);&lt;br /&gt;
    integer second         = llList2Integer(timelist,5);&lt;br /&gt;
    string  hourstr     = (string)hour;&lt;br /&gt;
    string  minutestr   = (string)minute;&lt;br /&gt;
    string  secondstr   = (string)second;&lt;br /&gt;
    &lt;br /&gt;
    if (hour &amp;lt; 10)         hourstr     = &amp;quot;0&amp;quot; + hourstr;&lt;br /&gt;
    if (minute &amp;lt; 10)     minutestr     = &amp;quot;0&amp;quot; + minutestr;&lt;br /&gt;
    if (second &amp;lt; 10)    secondstr    = &amp;quot;0&amp;quot; + secondstr;&lt;br /&gt;
    return hourstr + &amp;quot;:&amp;quot; + minutestr + &amp;quot;:&amp;quot; + secondstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() /////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string body)&lt;br /&gt;
{&lt;br /&gt;
    // llOwnerSay(&amp;quot;Sending message to &#039;&amp;quot; + address + &amp;quot;&#039; with subject &#039;&amp;quot; + subject +&amp;quot;&#039;.&amp;quot;);&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND, body, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// SendHome() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendHome(string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SENDHOME, body, (key)subject);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Show() ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Show()&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;Current chat recording is:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; NumLines; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(ChatRecording,i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;Lines is &amp;quot; + (string)NumLines);&lt;br /&gt;
    llOwnerSay(&amp;quot;Message length is &amp;quot; + (string)Length);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Read() /////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Read()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;Reading message &amp;quot; + (string)CurrentMessage + &amp;quot; from mail buffer.&amp;quot;);&lt;br /&gt;
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);&lt;br /&gt;
    list timelist=Unix2DateTime(time);&lt;br /&gt;
    string Address = llList2String(AddressList,CurrentMessage);&lt;br /&gt;
    string Subject = llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
    string Body    = llList2String(BodyList,CurrentMessage);&lt;br /&gt;
    llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Address: &amp;quot; + Address);&lt;br /&gt;
    llOwnerSay(&amp;quot;Subject: &amp;quot; + Subject);&lt;br /&gt;
    llOwnerSay(&amp;quot;Begin of message body:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    list bodylist=llParseStringKeepNulls(Body, [ &amp;quot;\n&amp;quot; ], []);&lt;br /&gt;
    integer num=llGetListLength(bodylist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(bodylist,i));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;End of message body.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////// List ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
List()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;The mail buffer contains the following messages:\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; NumMessages; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer time=llList2Integer(TimeList,i);&lt;br /&gt;
        list timelist=Unix2DateTime(time);&lt;br /&gt;
        if (i &amp;gt; 0) llOwnerSay(&amp;quot;+-+-+-+-+-+-+-+-+-+-+-+-&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Message: &amp;quot; + (string)i);&lt;br /&gt;
        llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;From:    &amp;quot; + llList2String(AddressList,i));&lt;br /&gt;
        llOwnerSay(&amp;quot;Subject: &amp;quot; + llList2String(SubjectList,i));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////// NotifyNewMail() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
NotifyNewMail(string time, string address, string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    list timelist=Unix2DateTime((integer)time);&lt;br /&gt;
&lt;br /&gt;
    if (StatusOnline)&lt;br /&gt;
    {&lt;br /&gt;
        llInstantMessage(llGetOwner(), &amp;quot;You received a new mail message on &amp;quot; &lt;br /&gt;
                                    + DateString(timelist) + &amp;quot; at &amp;quot; + TimeString(timelist)&lt;br /&gt;
                                    + &amp;quot; from &amp;quot; + address &lt;br /&gt;
                                    + &amp;quot; with the subject &amp;quot; + subject);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        SendHome(&amp;quot;FW: &amp;quot; + subject, &amp;quot;Received at: &amp;quot; + DateString(timelist) + &amp;quot; &amp;quot; + TimeString(timelist) + &amp;quot;\nFrom: &amp;quot; +  address &lt;br /&gt;
                    + &amp;quot;\nBegin message body:\n-------------------\n&amp;quot; + body + &amp;quot;\n-------------------\nEnd message body.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ResetOtherScripts() //////////////////////&lt;br /&gt;
&lt;br /&gt;
ResetOtherScripts()&lt;br /&gt;
{&lt;br /&gt;
    string     name;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(ScriptList);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        name = llList2String(ScriptList,i);&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(name) == INVENTORY_SCRIPT)&lt;br /&gt;
        {&lt;br /&gt;
            llResetOtherScript(name);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Error - script &#039;&amp;quot; + name + &amp;quot;&#039; not found.&amp;quot;);&lt;br /&gt;
            ErrorFlag = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
// default &lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ////////////////////// state_entry() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Welcome to SL Mail, released under GNU software licence.&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Version &amp;quot; + SL_MAIL_VERSION + &amp;quot; &amp;quot; + SL_MAIL_DATE);&lt;br /&gt;
        llOwnerSay(&amp;quot;Produced by Logic Scripted Products &amp;amp; Product Services&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Free memory: &amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
        ResetOtherScripts();&lt;br /&gt;
        &lt;br /&gt;
        if (ErrorFlag)&lt;br /&gt;
            state Error;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// on_rez() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// changed() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_LOADED)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_ERROR)&lt;br /&gt;
        {&lt;br /&gt;
            state Error;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() //////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(MAIL_FETCH_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //////////////////////// on_rez() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// listen() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string trimmessage=llStringTrim(message,STRING_TRIM);&lt;br /&gt;
        list   parse = llParseStringKeepNulls(trimmessage, [ &amp;quot; &amp;quot;], []);&lt;br /&gt;
        string command = llToUpper(llList2String(parse,0));&lt;br /&gt;
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        integer nargs  = llGetListLength(parse);&lt;br /&gt;
        string argstr=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (nargs &amp;gt; 1) argstr=llGetSubString(message, llSubStringIndex(message, &amp;quot; &amp;quot;) + 1, -1);&lt;br /&gt;
            &lt;br /&gt;
        if (Recording)&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Recording stopped. Type @SHOW to see the message you have entered,&amp;quot;&lt;br /&gt;
                            + &amp;quot; or @SEND to send it.&amp;quot;);&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                &lt;br /&gt;
                SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];&lt;br /&gt;
                ++NumLines;&lt;br /&gt;
                Length += llStringLength(message) + 2;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_RECORD)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Start recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                ChatRecording = [];&lt;br /&gt;
                NumLines=0;&lt;br /&gt;
                Length=0;&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CONTINUE)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Continue recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_REPLY)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    string address=llList2String(AddressList,CurrentMessage);&lt;br /&gt;
                    string subject=&amp;quot;Re: &amp;quot; + llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, address, NULL_KEY);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, subject, NULL_KEY);&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines=0;&lt;br /&gt;
                    Length=0;&lt;br /&gt;
                    Recording = TRUE;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_MAIL)&lt;br /&gt;
            {&lt;br /&gt;
                string mailaddress=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailaddress != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, mailaddress, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETADDRESS, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SUBJECT)&lt;br /&gt;
            {&lt;br /&gt;
                string mailsubject=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailsubject != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, mailsubject, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETSUBJECT, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Not recording.&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    if (NumLines == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND_NOTECARD, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_IGNORE)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines = 0;&lt;br /&gt;
                    Length = 0;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Show();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_READ)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumMessages == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Read();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        ++CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        --CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_FIRST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = 0;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LAST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LIST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    List();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SELECT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;Need to supply a message number.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    integer msgnum = (integer)arg;&lt;br /&gt;
                     &lt;br /&gt;
                    if (msgnum &amp;lt; 0 || msgnum &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Message number &amp;quot; + arg + &amp;quot; not in mail buffer.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = msgnum;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_DELETE)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    --NumMessages;&lt;br /&gt;
                     &lt;br /&gt;
                    if (NumMessages == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = -1;&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (CurrentMessage &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CLEAR)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList=[];&lt;br /&gt;
                    AddressList=[];&lt;br /&gt;
                    SubjectList=[];&lt;br /&gt;
                    BodyList=[];&lt;br /&gt;
                    NumMessages=0;&lt;br /&gt;
                    CurrentMessage=-1;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_HELP, arg, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_INFO)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                Show();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_RESET)&lt;br /&gt;
            {&lt;br /&gt;
                llResetScript();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                state not_running;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HOME)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs==1)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETHOME, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETHOME, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// email() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    email(string time, string address, string subject, string body, integer queued)&lt;br /&gt;
    {&lt;br /&gt;
        NotifyNewMail(time, address, subject, body);&lt;br /&gt;
        TimeList = (TimeList=[]) + TimeList + [time];&lt;br /&gt;
        AddressList = (AddressList=[]) + AddressList + [address];&lt;br /&gt;
        SubjectList = (SubjectList=[]) + SubjectList + [subject];&lt;br /&gt;
        BodyList = (BodyList=[]) + BodyList + [body];&lt;br /&gt;
        ++NumMessages;&lt;br /&gt;
        &lt;br /&gt;
        if (CurrentMessage == -1)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = NumMessages - 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_REPLY)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state not_running&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state not_running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;SL Mailbox switched OFF. Say @ON to switch it back on.&amp;quot;);&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// on_rez() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// listen() ////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer chan, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string command=llToUpper(message);&lt;br /&gt;
        &lt;br /&gt;
        if (command == COMMAND_ON)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state Error&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state Error&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Error in SL Mail: not all component scripts found.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// End SL Mail V1.2.lsl&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Address Book V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Read and interpret the contents of the Address Book.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail AddressBook V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// &lt;br /&gt;
//  Read the Address Book from a notecard named &amp;quot;Address Book&amp;quot;.&lt;br /&gt;
//&lt;br /&gt;
//  The Address Book has the following format:&lt;br /&gt;
//  &lt;br /&gt;
//  [ADDRESS BOOK]&lt;br /&gt;
//  Name1=username@yourdomain.com&lt;br /&gt;
//  Name2=otheruser@otherdomain.com&lt;br /&gt;
//  ...&lt;br /&gt;
//  [GROUP]&lt;br /&gt;
//  group1=Name1, Name2&lt;br /&gt;
//  ...&lt;br /&gt;
//&lt;br /&gt;
//  Notes:&lt;br /&gt;
//  1. Group and Name share the same namespace, and must be unique.&lt;br /&gt;
//  2. It is allowed to have a name in the addressbook with multiple addresses, seperated by comma&#039;s.&lt;br /&gt;
// &lt;br /&gt;
/////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string  CurrentMailAddress = &amp;quot;&amp;quot;;&lt;br /&gt;
string  CurrentMailSubject = &amp;quot;&amp;quot;;&lt;br /&gt;
integer StatusOnline = FALSE;&lt;br /&gt;
&lt;br /&gt;
// Fetch or Send notecard&lt;br /&gt;
&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Names&lt;br /&gt;
&lt;br /&gt;
list    AddressBookList=[];&lt;br /&gt;
list    MailAddressList=[];&lt;br /&gt;
&lt;br /&gt;
string  STRING_HOME=&amp;quot;HOME&amp;quot;;&lt;br /&gt;
string  STRING_SELF=&amp;quot;SELF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Groups&lt;br /&gt;
&lt;br /&gt;
list   GroupList=[];&lt;br /&gt;
list   GroupNameList=[];&lt;br /&gt;
&lt;br /&gt;
string LSL_DOMAIN = &amp;quot;lsl.secondlife.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Read Address Book notecard&lt;br /&gt;
&lt;br /&gt;
string  ADDRESSBOOK_NOTECARD=&amp;quot;Address Book&amp;quot;;&lt;br /&gt;
integer Line=0;&lt;br /&gt;
key     reqAddressBook=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
integer Section=0;&lt;br /&gt;
integer SECTION_ADDRESS_BOOK=1;&lt;br /&gt;
integer SECTION_GROUP=2;&lt;br /&gt;
string  STRING_ADDRESS_BOOK=&amp;quot;ADDRESS BOOK&amp;quot;;&lt;br /&gt;
string  STRING_GROUP=&amp;quot;GROUP&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Links messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
integer MSG_MESSAGE_NOTIFY              = 90900;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED            = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR            = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// GetSelfAddress() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
string GetSelfAddress()&lt;br /&gt;
{&lt;br /&gt;
    return (string)llGetKey() + &amp;quot;@&amp;quot; + LSL_DOMAIN;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Info() /////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Info()&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;The mail address for this object is: &amp;quot; &lt;br /&gt;
                    + GetSelfAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// IsValidKeyFormat() //////////////////////&lt;br /&gt;
&lt;br /&gt;
integer IsValidKeyFormat(string str)&lt;br /&gt;
{&lt;br /&gt;
    string keychars = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    if (llStringLength(str) != 36)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    if( (llGetSubString( str, 8, 8 )   != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 13, 13 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 18, 18 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 23, 23 )  != &amp;quot;-&amp;quot; ) )&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 9; i &amp;lt; 13; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 14; i &amp;lt; 18; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 19; i &amp;lt; 23; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 24; i &amp;lt; 36; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// ValidMailAddress() ////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer ValidMailAddress(string arg)&lt;br /&gt;
{&lt;br /&gt;
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));&lt;br /&gt;
    &lt;br /&gt;
    if (adress == &amp;quot;&amp;quot;)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    list parse = llParseStringKeepNulls(adress, [ &amp;quot;@&amp;quot; ], []);&lt;br /&gt;
    string account = llList2String(parse,0);&lt;br /&gt;
    string domain  = llList2String(parse,1);&lt;br /&gt;
    &lt;br /&gt;
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    &lt;br /&gt;
    if (domain == LSL_DOMAIN)&lt;br /&gt;
    {&lt;br /&gt;
        return IsValidKeyFormat(account);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list parsedomain = llParseString2List(domain, [ &amp;quot;.&amp;quot; ], []);&lt;br /&gt;
    &lt;br /&gt;
        if (llGetListLength(parsedomain) &amp;lt; 2)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        &lt;br /&gt;
        integer num = llGetListLength(parsedomain);&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llStringLength(llList2String(parsedomain,i)) &amp;lt; 2)&lt;br /&gt;
            {&lt;br /&gt;
                return FALSE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetAddressStr() ///////////////////&lt;br /&gt;
&lt;br /&gt;
string GetAndCheckAddressStr(string address)&lt;br /&gt;
{&lt;br /&gt;
    list addresslist = llCSV2List(address);&lt;br /&gt;
    integer num=llGetListLength(addresslist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    string addressstr=&amp;quot;&amp;quot;;&lt;br /&gt;
    string curaddress=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        curaddress=llList2String(addresslist,i);&lt;br /&gt;
        &lt;br /&gt;
        if (ValidMailAddress(curaddress))&lt;br /&gt;
        {&lt;br /&gt;
            addressstr = (addressstr=&amp;quot;&amp;quot;) + addressstr + curaddress + &amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address string: &#039;&amp;quot; &lt;br /&gt;
                            + curaddress + &amp;quot;&#039;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return llGetSubString(addressstr, 0, -2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ProcessLine() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
ProcessLine(string rawline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(rawline,STRING_TRIM);&lt;br /&gt;
    string first=llGetSubString(line,0,0);&lt;br /&gt;
    string last=llGetSubString(line,-1,-1);&lt;br /&gt;
    &lt;br /&gt;
    // Ignore a blank line or comment line&lt;br /&gt;
    if (line == &amp;quot;&amp;quot; || first == &amp;quot;#&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // Check for the right section&lt;br /&gt;
    &lt;br /&gt;
    if (first == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; last == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        string sectionstr=llToUpper(llStringTrim(llGetSubString(line,1,-2),STRING_TRIM));&lt;br /&gt;
        &lt;br /&gt;
        if (sectionstr == STRING_ADDRESS_BOOK)&lt;br /&gt;
        {&lt;br /&gt;
            Section = SECTION_ADDRESS_BOOK;&lt;br /&gt;
        }&lt;br /&gt;
        else if (sectionstr == STRING_GROUP)&lt;br /&gt;
        {&lt;br /&gt;
            if (Section == 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                        + &amp;quot;. Group section defined before Address Book section.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Section = SECTION_GROUP;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid section header &#039;&amp;quot; + sectionstr &lt;br /&gt;
                        + &amp;quot;&#039; in &amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Must be in a section&lt;br /&gt;
    &lt;br /&gt;
    if (Section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;. No section header.&amp;quot;, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    list     parse=llParseString2List(line, [ &amp;quot;=&amp;quot; ], []);&lt;br /&gt;
    integer  num=llGetListLength(parse);&lt;br /&gt;
    &lt;br /&gt;
    // Format must be correct&lt;br /&gt;
    &lt;br /&gt;
    if (num != 2)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; +  (string)(Line+1) + &amp;quot;:\n&amp;quot; + rawline, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (Section == SECTION_ADDRESS_BOOK)&lt;br /&gt;
    {&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(name) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + name &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ name ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            string address=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
            string addressstr=GetAndCheckAddressStr(address);&lt;br /&gt;
            &lt;br /&gt;
            if (addressstr != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                AddressBookList     = (AddressBookList=[])     + AddressBookList     + [ name ];&lt;br /&gt;
                MailAddressList     = (MailAddressList=[])     + MailAddressList     + [ addressstr ];&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;No valid mail address for &#039;&amp;quot; + name &lt;br /&gt;
                    + &amp;quot;&#039;. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                    + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name &lt;br /&gt;
                + &amp;quot;&#039; already defined. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // Group&lt;br /&gt;
    {&lt;br /&gt;
        string group=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(group) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + group &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ group ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(GroupList, [ group ]) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                string names=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
                list   namelist=llCSV2List(names);&lt;br /&gt;
                integer num=llGetListLength(namelist);&lt;br /&gt;
                integer i;&lt;br /&gt;
                integer index;&lt;br /&gt;
                string  name;&lt;br /&gt;
                string  namestr=&amp;quot;&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
                for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                    name=llList2String(namelist,i);&lt;br /&gt;
                    index=llListFindList(AddressBookList, [ name ]);&lt;br /&gt;
            &lt;br /&gt;
                    if (index == -1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name + &amp;quot;&#039; defined in Group &#039;&amp;quot; &lt;br /&gt;
                                + group + &amp;quot;&#039; not found in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY); &lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        namestr = (namestr=&amp;quot;&amp;quot;) + namestr + name + &amp;quot;,&amp;quot;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (namestr != &amp;quot;&amp;quot;)&lt;br /&gt;
                {    &lt;br /&gt;
                    namestr=llGetSubString(namestr,0,-2);&lt;br /&gt;
                    GroupList         = (GroupList=[])         + GroupList     + [ group ];&lt;br /&gt;
                    GroupNameList     = (GroupNameList=[])    + GroupNameList + [ namestr ];&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                        + &amp;quot;&#039; has no valid names. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                        + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                    + &amp;quot;&#039; already defined in Group. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                    + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group&lt;br /&gt;
                + &amp;quot;&#039; already defined in Address Book. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// GetGroupAddressList ///////////////&lt;br /&gt;
&lt;br /&gt;
string GetGroupAddressList(string group)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(GroupList, [ group ]);&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(GroupList);&lt;br /&gt;
    string  grouplist=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        for (i = index; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2String(GroupList,i) == group)&lt;br /&gt;
            {&lt;br /&gt;
                grouplist = (grouplist=&amp;quot;&amp;quot;) + grouplist + llList2String(GroupNameList,i) + &amp;quot;,&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (grouplist != &amp;quot;&amp;quot;) grouplist=llGetSubString(grouplist,0,-2);   // remove last &amp;quot;,&amp;quot;&lt;br /&gt;
        return grouplist;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// SetMailAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetMailAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ address ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        index=llListFindList(GroupList, [ address ]);&lt;br /&gt;
        &lt;br /&gt;
        if (index == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llToUpper(address) == STRING_SELF)&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = GetSelfAddress();&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if(ValidMailAddress(address))&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = address;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Mail adress &amp;quot; + address &lt;br /&gt;
                            + &amp;quot; : not found in adress book or invalid format.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailAddress = GetGroupAddressList(address);&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        CurrentMailAddress = llList2String(MailAddressList,index);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                        + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string message)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No mail address defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No subject defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list mailaddresslist=llCSV2List(CurrentMailAddress);&lt;br /&gt;
        integer num=llGetListLength(mailaddresslist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(mailaddresslist,i);&lt;br /&gt;
            llEmail(address, CurrentMailSubject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMailHome() ////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMailHome(string message, string subject)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, STRING_HOME &lt;br /&gt;
                + &amp;quot; not set. Set your home adress with @HOME &amp;lt;address&amp;gt;.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        string homeaddress=llList2String(AddressBookList,index);&lt;br /&gt;
        list   homelist=llCSV2List(homeaddress);&lt;br /&gt;
        integer num=llGetListLength(homelist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(homelist,i);&lt;br /&gt;
            llEmail(address, subject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
string GetHomeAddress()&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;not set&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2String(MailAddressList,index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetHomeAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        AddressBookList     = (AddressBookList=[]) + [ STRING_HOME ] + AddressBookList;&lt;br /&gt;
        MailAddressList     = (MailAddressList=[]) + [ GetAndCheckAddressStr(address) ]  + MailAddressList;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MailAddressList = llListReplaceList(MailAddressList, [ GetAndCheckAddressStr(address) ], index, index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        Line=0;&lt;br /&gt;
        Section=0;&lt;br /&gt;
        llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// dataserver() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqAddressBook)&lt;br /&gt;
        {&lt;br /&gt;
            reqAddressBook = NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                ProcessLine(data);&lt;br /&gt;
                reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Address Book loaded.&amp;quot;, NULL_KEY);&lt;br /&gt;
                state running;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// timer() ///////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_ERROR, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Could not read Address Book: &amp;quot; &lt;br /&gt;
                            + ADDRESSBOOK_NOTECARD + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// link_message() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_MESSAGE_GETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is empty.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailSubject = message;&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is empty.&amp;quot;, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            SetMailAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Body of message to send is empty. &amp;quot; &lt;br /&gt;
                                +  &amp;quot;No mail is send.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SENDHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SendMailHome(message, (string)id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetInventoryType(message) == INVENTORY_NOTECARD)&lt;br /&gt;
            {&lt;br /&gt;
                Notecard2Fetch = message;                &lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_READ, message, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + message + &amp;quot; not found.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_NOTECARD_FETCHED)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + Notecard2Fetch &lt;br /&gt;
                            + &amp;quot; was empty or could not be read.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Home address is: &amp;quot; + GetHomeAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SetHomeAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_INFO)&lt;br /&gt;
        {&lt;br /&gt;
            Info();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
// End SL Mail AddressBook V1.2.lsl&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail FetchNotecard V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch the contents of a notecard and return it via link message as a string.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Notecard&lt;br /&gt;
&lt;br /&gt;
integer Line=0;&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
key     reqNotecard=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=10.0;&lt;br /&gt;
integer Fetched=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Lines&lt;br /&gt;
&lt;br /&gt;
list LineList=[];&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    /////////////////////// dataserver() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqNotecard)&lt;br /&gt;
        {&lt;br /&gt;
            reqNotecard=NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                LineList = (LineList=[]) + LineList + [ data ];&lt;br /&gt;
                reqNotecard = llGetNotecardLine(Notecard2Fetch, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Fetched=TRUE;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, llDumpList2String(LineList, &amp;quot;\n&amp;quot;), NULL_KEY);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /////////////////////// timer() ///////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        if (!Fetched)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            llSetTimerEvent(0.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer send, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_NOTECARD_READ)&lt;br /&gt;
        {&lt;br /&gt;
            Line=0;&lt;br /&gt;
            Notecard2Fetch=message;&lt;br /&gt;
            LineList=[];&lt;br /&gt;
            Fetched=FALSE;&lt;br /&gt;
            reqNotecard=llGetNotecardLine(Notecard2Fetch, Line);&lt;br /&gt;
            llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL OnlineStatus V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch online status of owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Online status&lt;br /&gt;
&lt;br /&gt;
key     reqOnlineStatus=NULL_KEY;&lt;br /&gt;
float   STATUS_INTERVAL=2.0;&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_STATUS_ONLINE       = 30000;&lt;br /&gt;
integer MS_STATUS_OFFLINE       = 30100;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus=llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
        llSetTimerEvent(STATUS_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// dataserver() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqOnlineStatus)&lt;br /&gt;
        {&lt;br /&gt;
            reqOnlineStatus = NULL_KEY;&lt;br /&gt;
        &lt;br /&gt;
            if (data==&amp;quot;1&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_STATUS_ONLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if (data==&amp;quot;0&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MS_STATUS_OFFLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus = llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Help V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Display help information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail Help V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP    = 10000;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Help() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Help()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;HELP for SL Mail V1.2.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;COMMANDS:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HELP               - displays help info.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@INFO               - display mailaddress of this object.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RECORD             - start recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CONTINUE           - continue recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@STOP               - stop recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@IGNORE             - ignore the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SHOW               - show what your recorded.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SEND               - send the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@MAIL &amp;lt;mailadress&amp;gt;  - set the mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SUBJECT subject    - set the mail subject.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LIST               - list messages in mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SELECT &amp;lt;message&amp;gt;   - select message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@READ               - read current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@NEXT               - read next message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@PREV               - read previous message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@FIRST              - read first message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LAST               - read last message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@DELETE             - delete current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CLEAR              - clear the mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@REPLY              - reply to current message.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RESET              - reset the script.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HOME               - set the home mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@OFF                - switch mailbox OFF.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@ON                 - switch mailbox ON.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_HELP)&lt;br /&gt;
        {&lt;br /&gt;
            Help();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail Help V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}&lt;/div&gt;</description>
			<pubDate>Sun, 07 Oct 2007 09:49:32 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:SL_Mail_V1.2</comments>
		</item>
		<item>
			<title>SL Mail V1.2</title>
			<link>https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34583</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34583</guid>
			<description>&lt;p&gt;Flennan Roffo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}} __NOTOC__&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=&#039;&#039;&#039;Second Life mail client&#039;&#039;&#039;=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Send and receive email from within Second Life from and to any address.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implemented with Address Book function (in a notecard named &#039;Address Book&#039;) to stores addresses by name  and to compile groups of named addresses. Current version is stand-alone (no server functionality) and uses chat commands only.&lt;br /&gt;
&lt;br /&gt;
[[Image:BannerSLMail.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=Release Notes V1.2=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 Release notes (edition 2, 4 sept 2007)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LICENCE INFO&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is released under GNU free software licence&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;PRODUCTION &amp;amp; MAINTANENCE&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
by Logic Scripted Products and Script Services&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
SLurl:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Contact: [[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;DESCRIPTION&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is a simple tool to send and receive mail from within SL.&lt;br /&gt;
You can either compose a message yourself using chat recording, or choose a notecard from inventory to send. The Address Book functionality allows you to use short names for mail recipients stored in a notecard. The current version does not have a persisent mail address. Watch out for the upcoming next release (V1.3) which will facilitate persisent in-world mail addresses and will be enhanced with many new features (See: Requests For Change (RFC).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;COMMANDS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Help&#039;&#039;&#039;&lt;br /&gt;
||Show Help about available commands&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Record&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording (for owner only).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Stop&#039;&#039;&#039;&lt;br /&gt;
||Stops the chat recording without sending&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Continue&#039;&#039;&#039;&lt;br /&gt;
||Continues a previously stopped chat recording. Lines will be appended to you recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Show&#039;&#039;&#039;&lt;br /&gt;
||Shows the content of the recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send&#039;&#039;&#039;&lt;br /&gt;
||If recording, stops the recording, and sends the mail (need to supply mail address and subject first!)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send &amp;lt;notecard&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Sends the content of the notecard, instead of the chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Ignore&#039;&#039;&#039;&lt;br /&gt;
||Ignores your current chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject &amp;lt;subject&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the subject of the mail.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail subject.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Set the HOME address of the owner (mail will be forwarder to this address when offline).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home&#039;&#039;&#039;&lt;br /&gt;
||Show the HOME address.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Info&#039;&#039;&#039;&lt;br /&gt;
||Shows the mail address the object this script is running in uses (e.g. &amp;lt;object-key&amp;gt;@lsl.secondlife.com).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Read&#039;&#039;&#039;&lt;br /&gt;
||Reads the current message from the mail buffer (the mail buffer gets filled with mail you receive)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Select &amp;lt;msg&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Select a message number from the availabe messages in the mail buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Next&#039;&#039;&#039;&lt;br /&gt;
||Make next message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Prev&#039;&#039;&#039;&lt;br /&gt;
||Make previous message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@First&#039;&#039;&#039;&lt;br /&gt;
||Make the first message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Last&#039;&#039;&#039;&lt;br /&gt;
||Make the last message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Clear&#039;&#039;&#039;&lt;br /&gt;
||Clear the mail buffer&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Delete&#039;&#039;&#039;&lt;br /&gt;
||Deletes only the current message&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Reply&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording to reply to the current message. Mail adress and subject are filled in automatically.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* Commands are case insensitive (&amp;quot;@read&amp;quot; == &amp;quot;@READ&amp;quot;). Arguments might not be case insensitive.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;ADDRESS BOOK FORMAT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
A notecard of the name &#039;Address Book&#039; is read during initialization which may contain Address Book items and Groups.&lt;br /&gt;
The notecard is split in two sections, which need to be defined in that particular order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[ADDRESS BOOK]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Defines the section in which you can put names for mail addresses,  like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name1=account@thisdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name2=user@otherdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[GROUP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define groups of previously defined names under a new name, like for instance:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyGroup=Name1, Name2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note that names of groups and individual mail adresses share the same namespace and must be unique.&lt;br /&gt;
&lt;br /&gt;
So when you filled in your mail adresses in the Address Book, you can now use:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail Name1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to  &amp;lt;account@thisdomain.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail MyGroup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to &amp;lt;account@thisdomain.com&amp;gt; and &amp;lt;user@otherdomain.com&amp;gt;&lt;br /&gt;
Mails will be sent one after another.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* Names for Addreses and Groups are case insensitive (e.g. &amp;quot;mary&amp;quot;  == &amp;quot;MARY&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* The special address &#039;Self&#039; can be used in commands where otherwise an address specification can be used. &#039;Self&#039; is case insensitive (e.g. &amp;quot;self&amp;quot; == &amp;quot;SELF&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LIMITATIONS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
The current version is limited by the following:&lt;br /&gt;
&lt;br /&gt;
* Chat recording lines are limited by the 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Output of lines from the mail buffer are also limited by this 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Incoming mail is limited to a 1000 (1024?) byte limit&lt;br /&gt;
&lt;br /&gt;
* Outgoing mai is limited by a 4096 byte limit, which includes the standard mail header (region/location info on the first two lines)&lt;br /&gt;
&lt;br /&gt;
We are making adjustments to this release to help overcome these limitations. At least the line lenght limit can be overcome by introducing a line continuation character (for example a hyphen &#039;-&#039;) that when used at the end of a line appends the next line, so lines longer then 255 bytes are possible then.&lt;br /&gt;
&lt;br /&gt;
To overcome the outgoing mail length limit, the mail can be broken textualy into parts, and each part can be send seperatedely, with an indication in the subject or in an introduced primary line of the mail body to indicate that the mail was split into parts.&lt;br /&gt;
For incoming mail and at least to receive mail from other SL Mail programs, a protocol will be introduced to receive mail in parts that are joined together after receiving them to form a single mail.&lt;br /&gt;
&lt;br /&gt;
These enhancements will be made available in the next release (V1.3) of SL Mail &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;BUGS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Report any bugs you find in this release to Logic (IM: Flennan Roffo).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;REQUEST FOR CHANGE (RFC)&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Do you have additional wishes for enhancement of this product?&lt;br /&gt;
Contact Flennan Roffo and we will see if they can be implemented in the next release.&lt;br /&gt;
&lt;br /&gt;
Existing RFC&#039;s are:&lt;br /&gt;
&lt;br /&gt;
* Menu support for commands.&lt;br /&gt;
&lt;br /&gt;
* Lines on incoming/outgoing mail longer than 255 bytes.&lt;br /&gt;
&lt;br /&gt;
* Send messages longer than 4096 (minus SL mail header) bytes.&lt;br /&gt;
&lt;br /&gt;
* Receive messages longer than 1024 bytes.&lt;br /&gt;
&lt;br /&gt;
* Permanent mail addresses for the SL Mail client (like: &amp;lt;Flennan.Roffo@somedomain.sl&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Add your RFC!&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&#039;&#039;&#039;===&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In-world join the group &amp;quot;SL Mail&amp;quot; for bug reports, feature requests, the latest SL Mail release, and notices about development issues.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=Scripts=&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==Script: SL Mail v1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail core module which scans for incoming mail messages and executes commands used by the owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail V1.2.lsl&lt;br /&gt;
// (c) 2007 Logic Scripted Products and Script Services&lt;br /&gt;
// Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
// VERSION&lt;br /&gt;
// Version: 1.2&lt;br /&gt;
&lt;br /&gt;
// HISTORY&lt;br /&gt;
// Date         Version     Author              Comment&lt;br /&gt;
// --------------------------------------------------------------------------------------&lt;br /&gt;
// 28 aug 2007  V 1.0       Flennan Roffo       Created&lt;br /&gt;
//&lt;br /&gt;
//  1 sep 2007  V 1.1       Flennan Roffo       @Reply empties the recording buffer.&lt;br /&gt;
//                                                @Send while recording ends recording&lt;br /&gt;
//                                                and sends the mail if a mail address&lt;br /&gt;
//                                                and subject are supplied.&lt;br /&gt;
//                                                Fixed incorrect date in Unix2DateTime.&lt;br /&gt;
//  3 sep 2007  V 1.2       Flennan Roffo       Notification options:&lt;br /&gt;
//                                              - When online, send an IM when mail is received.&lt;br /&gt;
//                                              - When offline, send to HOME mail adress.&lt;br /&gt;
//                                              Adressbook&lt;br /&gt;
//                                              - Read adress book from config notecard.&lt;br /&gt;
&lt;br /&gt;
// LICENCE&lt;br /&gt;
// This program is free software; you can redistribute it and/or&lt;br /&gt;
// modify it under the terms of the GNU General Public License&lt;br /&gt;
// as published by the Free Software Foundation; either version 2&lt;br /&gt;
// of the License, or (at your option) any later version.&lt;br /&gt;
// &lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
// &lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program; if not, write to the Free Software&lt;br /&gt;
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
// (Also available at http://www.gnu.org/copyleft/gpl.html) &lt;br /&gt;
&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// Let&#039;s you record a message and sent to email and get messages and reply to messages.&lt;br /&gt;
// Must supply a valid mail adress and non-empty subject using chat commands.&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
// 1) Check for the maximum length of an email message (including newline and header).&lt;br /&gt;
// 2) Read adress book from notecard.                                    *DONE*&lt;br /&gt;
// 3) Send incoming mail to personal mail adress when offline.            *DONE*&lt;br /&gt;
// 4) Alert with an IM when online upon receiving new mail.                *DONE*&lt;br /&gt;
&lt;br /&gt;
string   SL_MAIL_VERSION = &amp;quot;V 1.2&amp;quot;;&lt;br /&gt;
string   SL_MAIL_DATE    = &amp;quot; 2 sep 2007&amp;quot;;&lt;br /&gt;
integer  ErrorFlag         = FALSE;&lt;br /&gt;
list     ScriptList        = [ &amp;quot;SL Mail Help V1.2&amp;quot;, &amp;quot;SL Mail AddressBook V1.2&amp;quot;, &lt;br /&gt;
                                &amp;quot;SL Mail OnlineStatus V1.2&amp;quot;, &amp;quot;SL Mail FetchNotecard V1.2&amp;quot; ];    &lt;br /&gt;
string   LSL_DOMAIN=&amp;quot;lsl.secondlife.com&amp;quot;; &lt;br /&gt;
integer  StatusOnline=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Commands&lt;br /&gt;
&lt;br /&gt;
string  COMMAND_RECORD     = &amp;quot;@RECORD&amp;quot;;&lt;br /&gt;
string  COMMAND_CONTINUE   = &amp;quot;@CONTINUE&amp;quot;;&lt;br /&gt;
string  COMMAND_STOP       = &amp;quot;@STOP&amp;quot;;&lt;br /&gt;
string  COMMAND_MAIL       = &amp;quot;@MAIL&amp;quot;;&lt;br /&gt;
string  COMMAND_SUBJECT    = &amp;quot;@SUBJECT&amp;quot;;&lt;br /&gt;
string  COMMAND_SEND       = &amp;quot;@SEND&amp;quot;;&lt;br /&gt;
string  COMMAND_SEE        = &amp;quot;@SEE&amp;quot;;&lt;br /&gt;
string  COMMAND_IGNORE     = &amp;quot;@IGNORE&amp;quot;;&lt;br /&gt;
string  COMMAND_READ       = &amp;quot;@READ&amp;quot;;&lt;br /&gt;
string  COMMAND_DELETE     = &amp;quot;@DELETE&amp;quot;;&lt;br /&gt;
string  COMMAND_CLEAR      = &amp;quot;@CLEAR&amp;quot;;&lt;br /&gt;
string  COMMAND_REPLY      = &amp;quot;@REPLY&amp;quot;;&lt;br /&gt;
string  COMMAND_NEXT       = &amp;quot;@NEXT&amp;quot;;&lt;br /&gt;
string  COMMAND_PREV       = &amp;quot;@PREV&amp;quot;;&lt;br /&gt;
string  COMMAND_FIRST      = &amp;quot;@FIRST&amp;quot;;&lt;br /&gt;
string  COMMAND_LAST       = &amp;quot;@LAST&amp;quot;;&lt;br /&gt;
string  COMMAND_LIST       = &amp;quot;@LIST&amp;quot;;&lt;br /&gt;
string  COMMAND_SELECT     = &amp;quot;@SELECT&amp;quot;;&lt;br /&gt;
string  COMMAND_HELP       = &amp;quot;@HELP&amp;quot;;&lt;br /&gt;
string  COMMAND_INFO       = &amp;quot;@INFO&amp;quot;;&lt;br /&gt;
string  COMMAND_RESET      = &amp;quot;@RESET&amp;quot;;&lt;br /&gt;
string  COMMAND_SHOW       = &amp;quot;@SHOW&amp;quot;;&lt;br /&gt;
string  COMMAND_ON         = &amp;quot;@ON&amp;quot;;&lt;br /&gt;
string  COMMAND_OFF        = &amp;quot;@OFF&amp;quot;;&lt;br /&gt;
string  COMMAND_HOME       = &amp;quot;@HOME&amp;quot;;&lt;br /&gt;
string  COMMAND_LOAD       = &amp;quot;@LOAD&amp;quot;;&lt;br /&gt;
string  COMMAND_ADDRESS    = &amp;quot;@ADDRESS&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Recording&lt;br /&gt;
&lt;br /&gt;
integer Recording = FALSE;&lt;br /&gt;
&lt;br /&gt;
list    ChatRecording=[];&lt;br /&gt;
integer NumLines=0;&lt;br /&gt;
integer Length=0;&lt;br /&gt;
&lt;br /&gt;
list     TimeList=[];&lt;br /&gt;
list     AddressList=[];&lt;br /&gt;
list     SubjectList=[];&lt;br /&gt;
list     BodyList=[];&lt;br /&gt;
integer  NumMessages=0;&lt;br /&gt;
integer  CurrentMessage=-1;&lt;br /&gt;
&lt;br /&gt;
float    MAIL_FETCH_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
// Link Messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP                        = 10000;&lt;br /&gt;
integer MSG_STATUS_ONLINE               = 30000;&lt;br /&gt;
integer MSG_STATUS_OFFLINE              = 30100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED          = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR           = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Unix Time conversion //////////////////&lt;br /&gt;
&lt;br /&gt;
integer DAYS_PER_YEAR        = 365;                // Non leap year&lt;br /&gt;
integer SECONDS_PER_YEAR     = 31536000;          // Non leap year&lt;br /&gt;
integer SECONDS_PER_DAY      = 86400;&lt;br /&gt;
integer SECONDS_PER_HOUR     = 3600;&lt;br /&gt;
integer SECONDS_PER_MINUTE   = 60;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// LeapYear() /////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer LeapYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (year % 4 == 0)&lt;br /&gt;
    {&lt;br /&gt;
        if (year % 100 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (year % 400 == 0)&lt;br /&gt;
            {&lt;br /&gt;
                return 1;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// DaysPerMonth() ///////////////////////////////////////&lt;br /&gt;
                &lt;br /&gt;
integer DaysPerMonth(integer year,integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;lt; 8)&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (month == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if (LeapYear(year))&lt;br /&gt;
                {&lt;br /&gt;
                    return 29;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    return 28;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 30;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 30;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////// DaysPerYear() ////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DaysPerYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (LeapYear(year))&lt;br /&gt;
        return DAYS_PER_YEAR + 1;&lt;br /&gt;
    else&lt;br /&gt;
        return DAYS_PER_YEAR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Unix2DataTime() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list Unix2DateTime(integer unixtime)&lt;br /&gt;
{&lt;br /&gt;
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;&lt;br /&gt;
    integer day = days_since_1_1_1970 + 1;&lt;br /&gt;
    integer year  = 1970;&lt;br /&gt;
    integer days_per_year = DaysPerYear(year);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_year)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_year;&lt;br /&gt;
        ++year;&lt;br /&gt;
        days_per_year = DaysPerYear(year);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer month = 1;&lt;br /&gt;
    integer days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_month)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_month;&lt;br /&gt;
        &lt;br /&gt;
        if (++month &amp;gt; 12)&lt;br /&gt;
        {    &lt;br /&gt;
            ++year;&lt;br /&gt;
            month = 1;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;&lt;br /&gt;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;&lt;br /&gt;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;&lt;br /&gt;
    integer minute      = second / SECONDS_PER_MINUTE;&lt;br /&gt;
    second               = second % SECONDS_PER_MINUTE;&lt;br /&gt;
    &lt;br /&gt;
    return [ year, month, day, hour, minute, second ];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// MonthName() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list MonthNameList = [     &amp;quot;JAN&amp;quot;, &amp;quot;FEB&amp;quot;, &amp;quot;MAR&amp;quot;, &amp;quot;APR&amp;quot;, &amp;quot;MAY&amp;quot;, &amp;quot;JUN&amp;quot;, &lt;br /&gt;
                        &amp;quot;JUL&amp;quot;, &amp;quot;AUG&amp;quot;, &amp;quot;SEP&amp;quot;, &amp;quot;OCT&amp;quot; , &amp;quot;NOV&amp;quot;, &amp;quot;DEC&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
string MonthName(integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;gt;= 0 &amp;amp;&amp;amp; month &amp;lt; 12)&lt;br /&gt;
        return llList2String(MonthNameList, month);&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// DateString() ///////////////////////////&lt;br /&gt;
&lt;br /&gt;
string DateString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer year       = llList2Integer(timelist,0);&lt;br /&gt;
    integer month      = llList2Integer(timelist,1);&lt;br /&gt;
    integer day        = llList2Integer(timelist,2);&lt;br /&gt;
    &lt;br /&gt;
    return (string)day + &amp;quot;-&amp;quot; + MonthName(month - 1) + &amp;quot;-&amp;quot; + (string)year;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// TimeString() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string TimeString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer hour          = llList2Integer(timelist,3);&lt;br /&gt;
    integer minute         = llList2Integer(timelist,4);&lt;br /&gt;
    integer second         = llList2Integer(timelist,5);&lt;br /&gt;
    string  hourstr     = (string)hour;&lt;br /&gt;
    string  minutestr   = (string)minute;&lt;br /&gt;
    string  secondstr   = (string)second;&lt;br /&gt;
    &lt;br /&gt;
    if (hour &amp;lt; 10)         hourstr     = &amp;quot;0&amp;quot; + hourstr;&lt;br /&gt;
    if (minute &amp;lt; 10)     minutestr     = &amp;quot;0&amp;quot; + minutestr;&lt;br /&gt;
    if (second &amp;lt; 10)    secondstr    = &amp;quot;0&amp;quot; + secondstr;&lt;br /&gt;
    return hourstr + &amp;quot;:&amp;quot; + minutestr + &amp;quot;:&amp;quot; + secondstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() /////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string body)&lt;br /&gt;
{&lt;br /&gt;
    // llOwnerSay(&amp;quot;Sending message to &#039;&amp;quot; + address + &amp;quot;&#039; with subject &#039;&amp;quot; + subject +&amp;quot;&#039;.&amp;quot;);&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND, body, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// SendHome() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendHome(string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SENDHOME, body, (key)subject);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Show() ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Show()&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;Current chat recording is:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; NumLines; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(ChatRecording,i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;Lines is &amp;quot; + (string)NumLines);&lt;br /&gt;
    llOwnerSay(&amp;quot;Message length is &amp;quot; + (string)Length);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Read() /////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Read()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;Reading message &amp;quot; + (string)CurrentMessage + &amp;quot; from mail buffer.&amp;quot;);&lt;br /&gt;
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);&lt;br /&gt;
    list timelist=Unix2DateTime(time);&lt;br /&gt;
    string Address = llList2String(AddressList,CurrentMessage);&lt;br /&gt;
    string Subject = llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
    string Body    = llList2String(BodyList,CurrentMessage);&lt;br /&gt;
    llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Address: &amp;quot; + Address);&lt;br /&gt;
    llOwnerSay(&amp;quot;Subject: &amp;quot; + Subject);&lt;br /&gt;
    llOwnerSay(&amp;quot;Begin of message body:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    list bodylist=llParseStringKeepNulls(Body, [ &amp;quot;\n&amp;quot; ], []);&lt;br /&gt;
    integer num=llGetListLength(bodylist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(bodylist,i));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;End of message body.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////// List ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
List()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;The mail buffer contains the following messages:\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; NumMessages; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer time=llList2Integer(TimeList,i);&lt;br /&gt;
        list timelist=Unix2DateTime(time);&lt;br /&gt;
        if (i &amp;gt; 0) llOwnerSay(&amp;quot;+-+-+-+-+-+-+-+-+-+-+-+-&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Message: &amp;quot; + (string)i);&lt;br /&gt;
        llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;From:    &amp;quot; + llList2String(AddressList,i));&lt;br /&gt;
        llOwnerSay(&amp;quot;Subject: &amp;quot; + llList2String(SubjectList,i));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////// NotifyNewMail() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
NotifyNewMail(string time, string address, string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    list timelist=Unix2DateTime((integer)time);&lt;br /&gt;
&lt;br /&gt;
    if (StatusOnline)&lt;br /&gt;
    {&lt;br /&gt;
        llInstantMessage(llGetOwner(), &amp;quot;You received a new mail message on &amp;quot; &lt;br /&gt;
                                    + DateString(timelist) + &amp;quot; at &amp;quot; + TimeString(timelist)&lt;br /&gt;
                                    + &amp;quot; from &amp;quot; + address &lt;br /&gt;
                                    + &amp;quot; with the subject &amp;quot; + subject);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        SendHome(&amp;quot;FW: &amp;quot; + subject, &amp;quot;Received at: &amp;quot; + DateString(timelist) + &amp;quot; &amp;quot; + TimeString(timelist) + &amp;quot;\nFrom: &amp;quot; +  address &lt;br /&gt;
                    + &amp;quot;\nBegin message body:\n-------------------\n&amp;quot; + body + &amp;quot;\n-------------------\nEnd message body.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ResetOtherScripts() //////////////////////&lt;br /&gt;
&lt;br /&gt;
ResetOtherScripts()&lt;br /&gt;
{&lt;br /&gt;
    string     name;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(ScriptList);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        name = llList2String(ScriptList,i);&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(name) == INVENTORY_SCRIPT)&lt;br /&gt;
        {&lt;br /&gt;
            llResetOtherScript(name);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Error - script &#039;&amp;quot; + name + &amp;quot;&#039; not found.&amp;quot;);&lt;br /&gt;
            ErrorFlag = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
// default &lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ////////////////////// state_entry() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Welcome to SL Mail, released under GNU software licence.&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Version &amp;quot; + SL_MAIL_VERSION + &amp;quot; &amp;quot; + SL_MAIL_DATE);&lt;br /&gt;
        llOwnerSay(&amp;quot;Produced by Logic Scripted Products &amp;amp; Product Services&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Free memory: &amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
        ResetOtherScripts();&lt;br /&gt;
        &lt;br /&gt;
        if (ErrorFlag)&lt;br /&gt;
            state Error;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// on_rez() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// changed() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_LOADED)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_ERROR)&lt;br /&gt;
        {&lt;br /&gt;
            state Error;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() //////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(MAIL_FETCH_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //////////////////////// on_rez() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// listen() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string trimmessage=llStringTrim(message,STRING_TRIM);&lt;br /&gt;
        list   parse = llParseStringKeepNulls(trimmessage, [ &amp;quot; &amp;quot;], []);&lt;br /&gt;
        string command = llToUpper(llList2String(parse,0));&lt;br /&gt;
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        integer nargs  = llGetListLength(parse);&lt;br /&gt;
        string argstr=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (nargs &amp;gt; 1) argstr=llGetSubString(message, llSubStringIndex(message, &amp;quot; &amp;quot;) + 1, -1);&lt;br /&gt;
            &lt;br /&gt;
        if (Recording)&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Recording stopped. Type @SHOW to see the message you have entered,&amp;quot;&lt;br /&gt;
                            + &amp;quot; or @SEND to send it.&amp;quot;);&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                &lt;br /&gt;
                SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];&lt;br /&gt;
                ++NumLines;&lt;br /&gt;
                Length += llStringLength(message) + 2;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_RECORD)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Start recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                ChatRecording = [];&lt;br /&gt;
                NumLines=0;&lt;br /&gt;
                Length=0;&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CONTINUE)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Continue recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_REPLY)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    string address=llList2String(AddressList,CurrentMessage);&lt;br /&gt;
                    string subject=&amp;quot;Re: &amp;quot; + llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, address, NULL_KEY);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, subject, NULL_KEY);&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines=0;&lt;br /&gt;
                    Length=0;&lt;br /&gt;
                    Recording = TRUE;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_MAIL)&lt;br /&gt;
            {&lt;br /&gt;
                string mailaddress=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailaddress != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, mailaddress, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETADDRESS, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SUBJECT)&lt;br /&gt;
            {&lt;br /&gt;
                string mailsubject=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailsubject != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, mailsubject, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETSUBJECT, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Not recording.&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    if (NumLines == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND_NOTECARD, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_IGNORE)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines = 0;&lt;br /&gt;
                    Length = 0;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Show();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_READ)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumMessages == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Read();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        ++CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        --CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_FIRST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = 0;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LAST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LIST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    List();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SELECT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;Need to supply a message number.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    integer msgnum = (integer)arg;&lt;br /&gt;
                     &lt;br /&gt;
                    if (msgnum &amp;lt; 0 || msgnum &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Message number &amp;quot; + arg + &amp;quot; not in mail buffer.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = msgnum;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_DELETE)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    --NumMessages;&lt;br /&gt;
                     &lt;br /&gt;
                    if (NumMessages == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = -1;&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (CurrentMessage &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CLEAR)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList=[];&lt;br /&gt;
                    AddressList=[];&lt;br /&gt;
                    SubjectList=[];&lt;br /&gt;
                    BodyList=[];&lt;br /&gt;
                    NumMessages=0;&lt;br /&gt;
                    CurrentMessage=-1;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_HELP, arg, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_INFO)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                Show();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_RESET)&lt;br /&gt;
            {&lt;br /&gt;
                llResetScript();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                state not_running;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HOME)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs==1)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETHOME, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETHOME, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// email() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    email(string time, string address, string subject, string body, integer queued)&lt;br /&gt;
    {&lt;br /&gt;
        NotifyNewMail(time, address, subject, body);&lt;br /&gt;
        TimeList = (TimeList=[]) + TimeList + [time];&lt;br /&gt;
        AddressList = (AddressList=[]) + AddressList + [address];&lt;br /&gt;
        SubjectList = (SubjectList=[]) + SubjectList + [subject];&lt;br /&gt;
        BodyList = (BodyList=[]) + BodyList + [body];&lt;br /&gt;
        ++NumMessages;&lt;br /&gt;
        &lt;br /&gt;
        if (CurrentMessage == -1)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = NumMessages - 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_REPLY)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state not_running&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state not_running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;SL Mailbox switched OFF. Say @ON to switch it back on.&amp;quot;);&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// on_rez() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// listen() ////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer chan, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string command=llToUpper(message);&lt;br /&gt;
        &lt;br /&gt;
        if (command == COMMAND_ON)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state Error&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state Error&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Error in SL Mail: not all component scripts found.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// End SL Mail V1.2.lsl&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Address Book V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Read and interpret the contents of the Address Book.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail AddressBook V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// &lt;br /&gt;
//  Read the Address Book from a notecard named &amp;quot;Address Book&amp;quot;.&lt;br /&gt;
//&lt;br /&gt;
//  The Address Book has the following format:&lt;br /&gt;
//  &lt;br /&gt;
//  [ADDRESS BOOK]&lt;br /&gt;
//  Name1=username@yourdomain.com&lt;br /&gt;
//  Name2=otheruser@otherdomain.com&lt;br /&gt;
//  ...&lt;br /&gt;
//  [GROUP]&lt;br /&gt;
//  group1=Name1, Name2&lt;br /&gt;
//  ...&lt;br /&gt;
//&lt;br /&gt;
//  Notes:&lt;br /&gt;
//  1. Group and Name share the same namespace, and must be unique.&lt;br /&gt;
//  2. It is allowed to have a name in the addressbook with multiple addresses, seperated by comma&#039;s.&lt;br /&gt;
// &lt;br /&gt;
/////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string  CurrentMailAddress = &amp;quot;&amp;quot;;&lt;br /&gt;
string  CurrentMailSubject = &amp;quot;&amp;quot;;&lt;br /&gt;
integer StatusOnline = FALSE;&lt;br /&gt;
&lt;br /&gt;
// Fetch or Send notecard&lt;br /&gt;
&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Names&lt;br /&gt;
&lt;br /&gt;
list    AddressBookList=[];&lt;br /&gt;
list    MailAddressList=[];&lt;br /&gt;
&lt;br /&gt;
string  STRING_HOME=&amp;quot;HOME&amp;quot;;&lt;br /&gt;
string  STRING_SELF=&amp;quot;SELF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Groups&lt;br /&gt;
&lt;br /&gt;
list   GroupList=[];&lt;br /&gt;
list   GroupNameList=[];&lt;br /&gt;
&lt;br /&gt;
string LSL_DOMAIN = &amp;quot;lsl.secondlife.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Read Address Book notecard&lt;br /&gt;
&lt;br /&gt;
string  ADDRESSBOOK_NOTECARD=&amp;quot;Address Book&amp;quot;;&lt;br /&gt;
integer Line=0;&lt;br /&gt;
key     reqAddressBook=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
integer Section=0;&lt;br /&gt;
integer SECTION_ADDRESS_BOOK=1;&lt;br /&gt;
integer SECTION_GROUP=2;&lt;br /&gt;
string  STRING_ADDRESS_BOOK=&amp;quot;ADDRESS BOOK&amp;quot;;&lt;br /&gt;
string  STRING_GROUP=&amp;quot;GROUP&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Links messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
integer MSG_MESSAGE_NOTIFY              = 90900;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED            = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR            = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// GetSelfAddress() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
string GetSelfAddress()&lt;br /&gt;
{&lt;br /&gt;
    return (string)llGetKey() + &amp;quot;@&amp;quot; + LSL_DOMAIN;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Info() /////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Info()&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;The mail address for this object is: &amp;quot; &lt;br /&gt;
                    + GetSelfAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// IsValidKeyFormat() //////////////////////&lt;br /&gt;
&lt;br /&gt;
integer IsValidKeyFormat(string str)&lt;br /&gt;
{&lt;br /&gt;
    string keychars = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    if (llStringLength(str) != 36)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    if( (llGetSubString( str, 8, 8 )   != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 13, 13 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 18, 18 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 23, 23 )  != &amp;quot;-&amp;quot; ) )&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 9; i &amp;lt; 13; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 14; i &amp;lt; 18; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 19; i &amp;lt; 23; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 24; i &amp;lt; 36; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// ValidMailAddress() ////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer ValidMailAddress(string arg)&lt;br /&gt;
{&lt;br /&gt;
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));&lt;br /&gt;
    &lt;br /&gt;
    if (adress == &amp;quot;&amp;quot;)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    list parse = llParseStringKeepNulls(adress, [ &amp;quot;@&amp;quot; ], []);&lt;br /&gt;
    string account = llList2String(parse,0);&lt;br /&gt;
    string domain  = llList2String(parse,1);&lt;br /&gt;
    &lt;br /&gt;
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    &lt;br /&gt;
    if (domain == LSL_DOMAIN)&lt;br /&gt;
    {&lt;br /&gt;
        return IsValidKeyFormat(account);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list parsedomain = llParseString2List(domain, [ &amp;quot;.&amp;quot; ], []);&lt;br /&gt;
    &lt;br /&gt;
        if (llGetListLength(parsedomain) &amp;lt; 2)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        &lt;br /&gt;
        integer num = llGetListLength(parsedomain);&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llStringLength(llList2String(parsedomain,i)) &amp;lt; 2)&lt;br /&gt;
            {&lt;br /&gt;
                return FALSE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetAddressStr() ///////////////////&lt;br /&gt;
&lt;br /&gt;
string GetAndCheckAddressStr(string address)&lt;br /&gt;
{&lt;br /&gt;
    list addresslist = llCSV2List(address);&lt;br /&gt;
    integer num=llGetListLength(addresslist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    string addressstr=&amp;quot;&amp;quot;;&lt;br /&gt;
    string curaddress=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        curaddress=llList2String(addresslist,i);&lt;br /&gt;
        &lt;br /&gt;
        if (ValidMailAddress(curaddress))&lt;br /&gt;
        {&lt;br /&gt;
            addressstr = (addressstr=&amp;quot;&amp;quot;) + addressstr + curaddress + &amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address string: &#039;&amp;quot; &lt;br /&gt;
                            + curaddress + &amp;quot;&#039;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return llGetSubString(addressstr, 0, -2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ProcessLine() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
ProcessLine(string rawline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(rawline,STRING_TRIM);&lt;br /&gt;
    string first=llGetSubString(line,0,0);&lt;br /&gt;
    string last=llGetSubString(line,-1,-1);&lt;br /&gt;
    &lt;br /&gt;
    // Ignore a blank line or comment line&lt;br /&gt;
    if (line == &amp;quot;&amp;quot; || first == &amp;quot;#&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // Check for the right section&lt;br /&gt;
    &lt;br /&gt;
    if (first == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; last == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        string sectionstr=llToUpper(llStringTrim(llGetSubString(line,1,-2),STRING_TRIM));&lt;br /&gt;
        &lt;br /&gt;
        if (sectionstr == STRING_ADDRESS_BOOK)&lt;br /&gt;
        {&lt;br /&gt;
            Section = SECTION_ADDRESS_BOOK;&lt;br /&gt;
        }&lt;br /&gt;
        else if (sectionstr == STRING_GROUP)&lt;br /&gt;
        {&lt;br /&gt;
            if (Section == 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                        + &amp;quot;. Group section defined before Address Book section.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Section = SECTION_GROUP;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid section header &#039;&amp;quot; + sectionstr &lt;br /&gt;
                        + &amp;quot;&#039; in &amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Must be in a section&lt;br /&gt;
    &lt;br /&gt;
    if (Section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;. No section header.&amp;quot;, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    list     parse=llParseString2List(line, [ &amp;quot;=&amp;quot; ], []);&lt;br /&gt;
    integer  num=llGetListLength(parse);&lt;br /&gt;
    &lt;br /&gt;
    // Format must be correct&lt;br /&gt;
    &lt;br /&gt;
    if (num != 2)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; +  (string)(Line+1) + &amp;quot;:\n&amp;quot; + rawline, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (Section == SECTION_ADDRESS_BOOK)&lt;br /&gt;
    {&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(name) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + name &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ name ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            string address=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
            string addressstr=GetAndCheckAddressStr(address);&lt;br /&gt;
            &lt;br /&gt;
            if (addressstr != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                AddressBookList     = (AddressBookList=[])     + AddressBookList     + [ name ];&lt;br /&gt;
                MailAddressList     = (MailAddressList=[])     + MailAddressList     + [ addressstr ];&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;No valid mail address for &#039;&amp;quot; + name &lt;br /&gt;
                    + &amp;quot;&#039;. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                    + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name &lt;br /&gt;
                + &amp;quot;&#039; already defined. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // Group&lt;br /&gt;
    {&lt;br /&gt;
        string group=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(group) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + group &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ group ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(GroupList, [ group ]) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                string names=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
                list   namelist=llCSV2List(names);&lt;br /&gt;
                integer num=llGetListLength(namelist);&lt;br /&gt;
                integer i;&lt;br /&gt;
                integer index;&lt;br /&gt;
                string  name;&lt;br /&gt;
                string  namestr=&amp;quot;&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
                for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                    name=llList2String(namelist,i);&lt;br /&gt;
                    index=llListFindList(AddressBookList, [ name ]);&lt;br /&gt;
            &lt;br /&gt;
                    if (index == -1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name + &amp;quot;&#039; defined in Group &#039;&amp;quot; &lt;br /&gt;
                                + group + &amp;quot;&#039; not found in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY); &lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        namestr = (namestr=&amp;quot;&amp;quot;) + namestr + name + &amp;quot;,&amp;quot;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (namestr != &amp;quot;&amp;quot;)&lt;br /&gt;
                {    &lt;br /&gt;
                    namestr=llGetSubString(namestr,0,-2);&lt;br /&gt;
                    GroupList         = (GroupList=[])         + GroupList     + [ group ];&lt;br /&gt;
                    GroupNameList     = (GroupNameList=[])    + GroupNameList + [ namestr ];&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                        + &amp;quot;&#039; has no valid names. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                        + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                    + &amp;quot;&#039; already defined in Group. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                    + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group&lt;br /&gt;
                + &amp;quot;&#039; already defined in Address Book. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// GetGroupAddressList ///////////////&lt;br /&gt;
&lt;br /&gt;
string GetGroupAddressList(string group)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(GroupList, [ group ]);&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(GroupList);&lt;br /&gt;
    string  grouplist=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        for (i = index; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2String(GroupList,i) == group)&lt;br /&gt;
            {&lt;br /&gt;
                grouplist = (grouplist=&amp;quot;&amp;quot;) + grouplist + llList2String(GroupNameList,i) + &amp;quot;,&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (grouplist != &amp;quot;&amp;quot;) grouplist=llGetSubString(grouplist,0,-2);   // remove last &amp;quot;,&amp;quot;&lt;br /&gt;
        return grouplist;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// SetMailAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetMailAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ address ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        index=llListFindList(GroupList, [ address ]);&lt;br /&gt;
        &lt;br /&gt;
        if (index == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llToUpper(address) == STRING_SELF)&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = GetSelfAddress();&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if(ValidMailAddress(address))&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = address;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Mail adress &amp;quot; + address &lt;br /&gt;
                            + &amp;quot; : not found in adress book or invalid format.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailAddress = GetGroupAddressList(address);&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        CurrentMailAddress = llList2String(MailAddressList,index);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                        + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string message)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No mail address defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No subject defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list mailaddresslist=llCSV2List(CurrentMailAddress);&lt;br /&gt;
        integer num=llGetListLength(mailaddresslist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(mailaddresslist,i);&lt;br /&gt;
            llEmail(address, CurrentMailSubject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMailHome() ////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMailHome(string message, string subject)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, STRING_HOME &lt;br /&gt;
                + &amp;quot; not set. Set your home adress with @HOME &amp;lt;address&amp;gt;.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        string homeaddress=llList2String(AddressBookList,index);&lt;br /&gt;
        list   homelist=llCSV2List(homeaddress);&lt;br /&gt;
        integer num=llGetListLength(homelist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(homelist,i);&lt;br /&gt;
            llEmail(address, subject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
string GetHomeAddress()&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;not set&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2String(MailAddressList,index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetHomeAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        AddressBookList     = (AddressBookList=[]) + [ STRING_HOME ] + AddressBookList;&lt;br /&gt;
        MailAddressList     = (MailAddressList=[]) + [ GetAndCheckAddressStr(address) ]  + MailAddressList;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MailAddressList = llListReplaceList(MailAddressList, [ GetAndCheckAddressStr(address) ], index, index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        Line=0;&lt;br /&gt;
        Section=0;&lt;br /&gt;
        llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// dataserver() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqAddressBook)&lt;br /&gt;
        {&lt;br /&gt;
            reqAddressBook = NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                ProcessLine(data);&lt;br /&gt;
                reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Address Book loaded.&amp;quot;, NULL_KEY);&lt;br /&gt;
                state running;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// timer() ///////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_ERROR, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Could not read Address Book: &amp;quot; &lt;br /&gt;
                            + ADDRESSBOOK_NOTECARD + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// link_message() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_MESSAGE_GETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is empty.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailSubject = message;&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is empty.&amp;quot;, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            SetMailAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Body of message to send is empty. &amp;quot; &lt;br /&gt;
                                +  &amp;quot;No mail is send.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SENDHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SendMailHome(message, (string)id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetInventoryType(message) == INVENTORY_NOTECARD)&lt;br /&gt;
            {&lt;br /&gt;
                Notecard2Fetch = message;                &lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_READ, message, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + message + &amp;quot; not found.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_NOTECARD_FETCHED)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + Notecard2Fetch &lt;br /&gt;
                            + &amp;quot; was empty or could not be read.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Home address is: &amp;quot; + GetHomeAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SetHomeAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_INFO)&lt;br /&gt;
        {&lt;br /&gt;
            Info();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
// End SL Mail AddressBook V1.2.lsl&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail FetchNotecard V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch the contents of a notecard and return it via link message as a string.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Notecard&lt;br /&gt;
&lt;br /&gt;
integer Line=0;&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
key     reqNotecard=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=10.0;&lt;br /&gt;
integer Fetched=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Lines&lt;br /&gt;
&lt;br /&gt;
list LineList=[];&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    /////////////////////// dataserver() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqNotecard)&lt;br /&gt;
        {&lt;br /&gt;
            reqNotecard=NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                LineList = (LineList=[]) + LineList + [ data ];&lt;br /&gt;
                reqNotecard = llGetNotecardLine(Notecard2Fetch, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Fetched=TRUE;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, llDumpList2String(LineList, &amp;quot;\n&amp;quot;), NULL_KEY);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /////////////////////// timer() ///////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        if (!Fetched)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            llSetTimerEvent(0.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer send, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_NOTECARD_READ)&lt;br /&gt;
        {&lt;br /&gt;
            Line=0;&lt;br /&gt;
            Notecard2Fetch=message;&lt;br /&gt;
            LineList=[];&lt;br /&gt;
            Fetched=FALSE;&lt;br /&gt;
            reqNotecard=llGetNotecardLine(Notecard2Fetch, Line);&lt;br /&gt;
            llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL OnlineStatus V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch online status of owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Online status&lt;br /&gt;
&lt;br /&gt;
key     reqOnlineStatus=NULL_KEY;&lt;br /&gt;
float   STATUS_INTERVAL=2.0;&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_STATUS_ONLINE       = 30000;&lt;br /&gt;
integer MS_STATUS_OFFLINE       = 30100;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus=llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
        llSetTimerEvent(STATUS_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// dataserver() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqOnlineStatus)&lt;br /&gt;
        {&lt;br /&gt;
            reqOnlineStatus = NULL_KEY;&lt;br /&gt;
        &lt;br /&gt;
            if (data==&amp;quot;1&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_STATUS_ONLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if (data==&amp;quot;0&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MS_STATUS_OFFLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus = llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Help V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Display help information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail Help V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP    = 10000;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Help() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Help()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;HELP for SL Mail V1.2.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;COMMANDS:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HELP               - displays help info.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@INFO               - display mailaddress of this object.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RECORD             - start recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CONTINUE           - continue recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@STOP               - stop recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@IGNORE             - ignore the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SHOW               - show what your recorded.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SEND               - send the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@MAIL &amp;lt;mailadress&amp;gt;  - set the mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SUBJECT subject    - set the mail subject.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LIST               - list messages in mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SELECT &amp;lt;message&amp;gt;   - select message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@READ               - read current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@NEXT               - read next message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@PREV               - read previous message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@FIRST              - read first message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LAST               - read last message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@DELETE             - delete current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CLEAR              - clear the mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@REPLY              - reply to current message.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RESET              - reset the script.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HOME               - set the home mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@OFF                - switch mailbox OFF.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@ON                 - switch mailbox ON.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_HELP)&lt;br /&gt;
        {&lt;br /&gt;
            Help();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail Help V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}&lt;/div&gt;</description>
			<pubDate>Sun, 07 Oct 2007 09:49:12 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:SL_Mail_V1.2</comments>
		</item>
		<item>
			<title>SL Mail V1.2</title>
			<link>https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34582</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=SL_Mail_V1.2&amp;diff=34582</guid>
			<description>&lt;p&gt;Flennan Roffo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header}} __NOTOC__&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=&#039;&#039;&#039;Second Life mail client&#039;&#039;&#039;=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Send and receive email from within Second Life from and to any address.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Implemented with Address Book function (in a notecard named &#039;Address Book&#039;) to stores addresses by name  and to compile groups of named addresses. Current version is stand-alone (no server functionality) and uses chat commands only.&lt;br /&gt;
&lt;br /&gt;
[[Image:BannerSLMail.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=Release Notes V1.2=&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 Release notes (edition 2, 4 sept 2007)&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LICENCE INFO&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is released under GNU free software licence&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;PRODUCTION &amp;amp; MAINTANENCE&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
by Logic Scripted Products and Script Services&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
SLurl:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Contact: [[User:Flennan Roffo|Flennan Roffo]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;DESCRIPTION&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail V1.2 is a simple tool to send and receive mail from within SL.&lt;br /&gt;
You can either compose a message yourself using chat recording, or choose a notecard from inventory to send. The Address Book functionality allows you to use short names for mail recipients stored in a notecard. The current version does not have a persisent mail address. Watch out for the upcoming next release (V1.3) which will facilitate persisent in-world mail addresses and will be enhanced with many new features (See: Requests For Change (RFC).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;COMMANDS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
{| {{Prettytable}}&lt;br /&gt;
|-&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|{{Hl2}}| &#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Help&#039;&#039;&#039;&lt;br /&gt;
||Show Help about available commands&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Record&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording (for owner only).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Stop&#039;&#039;&#039;&lt;br /&gt;
||Stops the chat recording without sending&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Continue&#039;&#039;&#039;&lt;br /&gt;
||Continues a previously stopped chat recording. Lines will be appended to you recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Show&#039;&#039;&#039;&lt;br /&gt;
||Shows the content of the recording buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send&#039;&#039;&#039;&lt;br /&gt;
||If recording, stops the recording, and sends the mail (need to supply mail address and subject first!)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Send &amp;lt;notecard&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Sends the content of the notecard, instead of the chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Ignore&#039;&#039;&#039;&lt;br /&gt;
||Ignores your current chat recording.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Mail&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail address to send to.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject &amp;lt;subject&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Define the subject of the mail.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Subject&#039;&#039;&#039;&lt;br /&gt;
||Shows the current mail subject.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home &amp;lt;address&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Set the HOME address of the owner (mail will be forwarder to this address when offline).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Home&#039;&#039;&#039;&lt;br /&gt;
||Show the HOME address.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Info&#039;&#039;&#039;&lt;br /&gt;
||Shows the mail address the object this script is running in uses (e.g. &amp;lt;object-key&amp;gt;@lsl.secondlife.com).&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Read&#039;&#039;&#039;&lt;br /&gt;
||Reads the current message from the mail buffer (the mail buffer gets filled with mail you receive)&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Select &amp;lt;msg&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
||Select a message number from the availabe messages in the mail buffer.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Next&#039;&#039;&#039;&lt;br /&gt;
||Make next message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Prev&#039;&#039;&#039;&lt;br /&gt;
||Make previous message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@First&#039;&#039;&#039;&lt;br /&gt;
||Make the first message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Last&#039;&#039;&#039;&lt;br /&gt;
||Make the last message the current message.&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Clear&#039;&#039;&#039;&lt;br /&gt;
||Clear the mail buffer&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Delete&#039;&#039;&#039;&lt;br /&gt;
||Deletes only the current message&lt;br /&gt;
|-&lt;br /&gt;
||&#039;&#039;&#039;@Reply&#039;&#039;&#039;&lt;br /&gt;
||Starts a chat recording to reply to the current message. Mail adress and subject are filled in automatically.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* Commands are case insensitive (&amp;quot;@read&amp;quot; == &amp;quot;@READ&amp;quot;). Arguments might not be case insensitive.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;ADDRESS BOOK FORMAT&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
A notecard of the name &#039;Address Book&#039; is read during initialization which may contain Address Book items and Groups.&lt;br /&gt;
The notecard is split in two sections, which need to be defined in that particular order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[ADDRESS BOOK]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Defines the section in which you can put names for mail addresses,  like this:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name1=account@thisdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Name2=user@otherdomain.com&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[GROUP]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Define groups of previously defined names under a new name, like for instance:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MyGroup=Name1, Name2&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Note that names of groups and individual mail adresses share the same namespace and must be unique.&lt;br /&gt;
&lt;br /&gt;
So when you filled in your mail adresses in the Address Book, you can now use:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail Name1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to  &amp;lt;account@thisdomain.com&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or you can use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;@Mail MyGroup&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
To send mail to &amp;lt;account@thisdomain.com&amp;gt; and &amp;lt;user@otherdomain.com&amp;gt;&lt;br /&gt;
Mails will be sent one after another.&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
&lt;br /&gt;
* Names for Addreses and Groups are case insensitive (e.g. &amp;quot;mary&amp;quot;  == &amp;quot;MARY&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
* The special address &#039;Self&#039; can be used in commands where otherwise an address specification can be used. &#039;Self&#039; is case insensitive (e.g. &amp;quot;self&amp;quot; == &amp;quot;SELF&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;LIMITATIONS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
The current version is limited by the following:&lt;br /&gt;
&lt;br /&gt;
* Chat recording lines are limited by the 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Output of lines from the mail buffer are also limited by this 255 byte limit&lt;br /&gt;
&lt;br /&gt;
* Incoming mail is limited to a 1000 (1024?) byte limit&lt;br /&gt;
&lt;br /&gt;
* Outgoing mai is limited by a 4096 byte limit, which includes the standard mail header (region/location info on the first two lines)&lt;br /&gt;
&lt;br /&gt;
We are making adjustments to this release to help overcome these limitations. At least the line lenght limit can be overcome by introducing a line continuation character (for example a hyphen &#039;-&#039;) that when used at the end of a line appends the next line, so lines longer then 255 bytes are possible then.&lt;br /&gt;
&lt;br /&gt;
To overcome the outgoing mail length limit, the mail can be broken textualy into parts, and each part can be send seperatedely, with an indication in the subject or in an introduced primary line of the mail body to indicate that the mail was split into parts.&lt;br /&gt;
For incoming mail and at least to receive mail from other SL Mail programs, a protocol will be introduced to receive mail in parts that are joined together after receiving them to form a single mail.&lt;br /&gt;
&lt;br /&gt;
These enhancements will be made available in the next release (V1.3) of SL Mail &lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;BUGS&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Report any bugs you find in this release to Logic (IM: Flennan Roffo).&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==&#039;&#039;&#039;REQUEST FOR CHANGE (RFC)&#039;&#039;&#039;==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em&amp;quot;&amp;gt;&lt;br /&gt;
Do you have additional wishes for enhancement of this product?&lt;br /&gt;
Contact Flennan Roffo and we will see if they can be implemented in the next release.&lt;br /&gt;
&lt;br /&gt;
Existing RFC&#039;s are:&lt;br /&gt;
&lt;br /&gt;
* Menu support for commands.&lt;br /&gt;
&lt;br /&gt;
* Lines on incoming/outgoing mail longer than 255 bytes.&lt;br /&gt;
&lt;br /&gt;
* Send messages longer than 4096 (minus SL mail header) bytes.&lt;br /&gt;
&lt;br /&gt;
* Receive messages longer than 1024 bytes.&lt;br /&gt;
&lt;br /&gt;
* Permanent mail addresses for the SL Mail client (like: &amp;lt;Flennan.Roffo@somedomain.sl&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Add your RFC!&lt;br /&gt;
&lt;br /&gt;
==&#039;&#039;&#039;SL MAIL SUPPORT &amp;amp; DEVELOPMENT&#039;&#039;&#039;===&lt;br /&gt;
&lt;br /&gt;
In-world join the group &amp;quot;SL Mail&amp;quot; for bug reports, feature requests, the latest SL Mail release, and notices about development issues.&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
=Scripts=&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
==Script: SL Mail v1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
SL Mail core module which scans for incoming mail messages and executes commands used by the owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail V1.2.lsl&lt;br /&gt;
// (c) 2007 Logic Scripted Products and Script Services&lt;br /&gt;
// Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
// VERSION&lt;br /&gt;
// Version: 1.2&lt;br /&gt;
&lt;br /&gt;
// HISTORY&lt;br /&gt;
// Date         Version     Author              Comment&lt;br /&gt;
// --------------------------------------------------------------------------------------&lt;br /&gt;
// 28 aug 2007  V 1.0       Flennan Roffo       Created&lt;br /&gt;
//&lt;br /&gt;
//  1 sep 2007  V 1.1       Flennan Roffo       @Reply empties the recording buffer.&lt;br /&gt;
//                                                @Send while recording ends recording&lt;br /&gt;
//                                                and sends the mail if a mail address&lt;br /&gt;
//                                                and subject are supplied.&lt;br /&gt;
//                                                Fixed incorrect date in Unix2DateTime.&lt;br /&gt;
//  3 sep 2007  V 1.2       Flennan Roffo       Notification options:&lt;br /&gt;
//                                              - When online, send an IM when mail is received.&lt;br /&gt;
//                                              - When offline, send to HOME mail adress.&lt;br /&gt;
//                                              Adressbook&lt;br /&gt;
//                                              - Read adress book from config notecard.&lt;br /&gt;
&lt;br /&gt;
// LICENCE&lt;br /&gt;
// This program is free software; you can redistribute it and/or&lt;br /&gt;
// modify it under the terms of the GNU General Public License&lt;br /&gt;
// as published by the Free Software Foundation; either version 2&lt;br /&gt;
// of the License, or (at your option) any later version.&lt;br /&gt;
// &lt;br /&gt;
// This program is distributed in the hope that it will be useful,&lt;br /&gt;
// but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
// GNU General Public License for more details.&lt;br /&gt;
// &lt;br /&gt;
// You should have received a copy of the GNU General Public License&lt;br /&gt;
// along with this program; if not, write to the Free Software&lt;br /&gt;
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.&lt;br /&gt;
// (Also available at http://www.gnu.org/copyleft/gpl.html) &lt;br /&gt;
&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// Let&#039;s you record a message and sent to email and get messages and reply to messages.&lt;br /&gt;
// Must supply a valid mail adress and non-empty subject using chat commands.&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
// 1) Check for the maximum length of an email message (including newline and header).&lt;br /&gt;
// 2) Read adress book from notecard.                                    *DONE*&lt;br /&gt;
// 3) Send incoming mail to personal mail adress when offline.            *DONE*&lt;br /&gt;
// 4) Alert with an IM when online upon receiving new mail.                *DONE*&lt;br /&gt;
&lt;br /&gt;
string   SL_MAIL_VERSION = &amp;quot;V 1.2&amp;quot;;&lt;br /&gt;
string   SL_MAIL_DATE    = &amp;quot; 2 sep 2007&amp;quot;;&lt;br /&gt;
integer  ErrorFlag         = FALSE;&lt;br /&gt;
list     ScriptList        = [ &amp;quot;SL Mail Help V1.2&amp;quot;, &amp;quot;SL Mail AddressBook V1.2&amp;quot;, &lt;br /&gt;
                                &amp;quot;SL Mail OnlineStatus V1.2&amp;quot;, &amp;quot;SL Mail FetchNotecard V1.2&amp;quot; ];    &lt;br /&gt;
string   LSL_DOMAIN=&amp;quot;lsl.secondlife.com&amp;quot;; &lt;br /&gt;
integer  StatusOnline=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Commands&lt;br /&gt;
&lt;br /&gt;
string  COMMAND_RECORD     = &amp;quot;@RECORD&amp;quot;;&lt;br /&gt;
string  COMMAND_CONTINUE   = &amp;quot;@CONTINUE&amp;quot;;&lt;br /&gt;
string  COMMAND_STOP       = &amp;quot;@STOP&amp;quot;;&lt;br /&gt;
string  COMMAND_MAIL       = &amp;quot;@MAIL&amp;quot;;&lt;br /&gt;
string  COMMAND_SUBJECT    = &amp;quot;@SUBJECT&amp;quot;;&lt;br /&gt;
string  COMMAND_SEND       = &amp;quot;@SEND&amp;quot;;&lt;br /&gt;
string  COMMAND_SEE        = &amp;quot;@SEE&amp;quot;;&lt;br /&gt;
string  COMMAND_IGNORE     = &amp;quot;@IGNORE&amp;quot;;&lt;br /&gt;
string  COMMAND_READ       = &amp;quot;@READ&amp;quot;;&lt;br /&gt;
string  COMMAND_DELETE     = &amp;quot;@DELETE&amp;quot;;&lt;br /&gt;
string  COMMAND_CLEAR      = &amp;quot;@CLEAR&amp;quot;;&lt;br /&gt;
string  COMMAND_REPLY      = &amp;quot;@REPLY&amp;quot;;&lt;br /&gt;
string  COMMAND_NEXT       = &amp;quot;@NEXT&amp;quot;;&lt;br /&gt;
string  COMMAND_PREV       = &amp;quot;@PREV&amp;quot;;&lt;br /&gt;
string  COMMAND_FIRST      = &amp;quot;@FIRST&amp;quot;;&lt;br /&gt;
string  COMMAND_LAST       = &amp;quot;@LAST&amp;quot;;&lt;br /&gt;
string  COMMAND_LIST       = &amp;quot;@LIST&amp;quot;;&lt;br /&gt;
string  COMMAND_SELECT     = &amp;quot;@SELECT&amp;quot;;&lt;br /&gt;
string  COMMAND_HELP       = &amp;quot;@HELP&amp;quot;;&lt;br /&gt;
string  COMMAND_INFO       = &amp;quot;@INFO&amp;quot;;&lt;br /&gt;
string  COMMAND_RESET      = &amp;quot;@RESET&amp;quot;;&lt;br /&gt;
string  COMMAND_SHOW       = &amp;quot;@SHOW&amp;quot;;&lt;br /&gt;
string  COMMAND_ON         = &amp;quot;@ON&amp;quot;;&lt;br /&gt;
string  COMMAND_OFF        = &amp;quot;@OFF&amp;quot;;&lt;br /&gt;
string  COMMAND_HOME       = &amp;quot;@HOME&amp;quot;;&lt;br /&gt;
string  COMMAND_LOAD       = &amp;quot;@LOAD&amp;quot;;&lt;br /&gt;
string  COMMAND_ADDRESS    = &amp;quot;@ADDRESS&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Recording&lt;br /&gt;
&lt;br /&gt;
integer Recording = FALSE;&lt;br /&gt;
&lt;br /&gt;
list    ChatRecording=[];&lt;br /&gt;
integer NumLines=0;&lt;br /&gt;
integer Length=0;&lt;br /&gt;
&lt;br /&gt;
list     TimeList=[];&lt;br /&gt;
list     AddressList=[];&lt;br /&gt;
list     SubjectList=[];&lt;br /&gt;
list     BodyList=[];&lt;br /&gt;
integer  NumMessages=0;&lt;br /&gt;
integer  CurrentMessage=-1;&lt;br /&gt;
&lt;br /&gt;
float    MAIL_FETCH_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
// Link Messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP                        = 10000;&lt;br /&gt;
integer MSG_STATUS_ONLINE               = 30000;&lt;br /&gt;
integer MSG_STATUS_OFFLINE              = 30100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED          = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR           = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Unix Time conversion //////////////////&lt;br /&gt;
&lt;br /&gt;
integer DAYS_PER_YEAR        = 365;                // Non leap year&lt;br /&gt;
integer SECONDS_PER_YEAR     = 31536000;          // Non leap year&lt;br /&gt;
integer SECONDS_PER_DAY      = 86400;&lt;br /&gt;
integer SECONDS_PER_HOUR     = 3600;&lt;br /&gt;
integer SECONDS_PER_MINUTE   = 60;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// LeapYear() /////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer LeapYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (year % 4 == 0)&lt;br /&gt;
    {&lt;br /&gt;
        if (year % 100 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (year % 400 == 0)&lt;br /&gt;
            {&lt;br /&gt;
                return 1;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 0;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////// DaysPerMonth() ///////////////////////////////////////&lt;br /&gt;
                &lt;br /&gt;
integer DaysPerMonth(integer year,integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;lt; 8)&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            if (month == 2)&lt;br /&gt;
            {&lt;br /&gt;
                if (LeapYear(year))&lt;br /&gt;
                {&lt;br /&gt;
                    return 29;&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    return 28;&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                return 30;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        if (month % 2 == 0)&lt;br /&gt;
        {&lt;br /&gt;
            return 31;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            return 30;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////// DaysPerYear() ////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer DaysPerYear(integer year)&lt;br /&gt;
{&lt;br /&gt;
    if (LeapYear(year))&lt;br /&gt;
        return DAYS_PER_YEAR + 1;&lt;br /&gt;
    else&lt;br /&gt;
        return DAYS_PER_YEAR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Unix2DataTime() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list Unix2DateTime(integer unixtime)&lt;br /&gt;
{&lt;br /&gt;
    integer days_since_1_1_1970     = unixtime / SECONDS_PER_DAY;&lt;br /&gt;
    integer day = days_since_1_1_1970 + 1;&lt;br /&gt;
    integer year  = 1970;&lt;br /&gt;
    integer days_per_year = DaysPerYear(year);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_year)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_year;&lt;br /&gt;
        ++year;&lt;br /&gt;
        days_per_year = DaysPerYear(year);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer month = 1;&lt;br /&gt;
    integer days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    &lt;br /&gt;
    while (day &amp;gt; days_per_month)&lt;br /&gt;
    {&lt;br /&gt;
        day -= days_per_month;&lt;br /&gt;
        &lt;br /&gt;
        if (++month &amp;gt; 12)&lt;br /&gt;
        {    &lt;br /&gt;
            ++year;&lt;br /&gt;
            month = 1;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        days_per_month = DaysPerMonth(year,month);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    integer seconds_since_midnight  = unixtime % SECONDS_PER_DAY;&lt;br /&gt;
    integer hour          = seconds_since_midnight / SECONDS_PER_HOUR;&lt;br /&gt;
    integer second         = seconds_since_midnight % SECONDS_PER_HOUR;&lt;br /&gt;
    integer minute      = second / SECONDS_PER_MINUTE;&lt;br /&gt;
    second               = second % SECONDS_PER_MINUTE;&lt;br /&gt;
    &lt;br /&gt;
    return [ year, month, day, hour, minute, second ];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// MonthName() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
list MonthNameList = [     &amp;quot;JAN&amp;quot;, &amp;quot;FEB&amp;quot;, &amp;quot;MAR&amp;quot;, &amp;quot;APR&amp;quot;, &amp;quot;MAY&amp;quot;, &amp;quot;JUN&amp;quot;, &lt;br /&gt;
                        &amp;quot;JUL&amp;quot;, &amp;quot;AUG&amp;quot;, &amp;quot;SEP&amp;quot;, &amp;quot;OCT&amp;quot; , &amp;quot;NOV&amp;quot;, &amp;quot;DEC&amp;quot; ];&lt;br /&gt;
&lt;br /&gt;
string MonthName(integer month)&lt;br /&gt;
{&lt;br /&gt;
    if (month &amp;gt;= 0 &amp;amp;&amp;amp; month &amp;lt; 12)&lt;br /&gt;
        return llList2String(MonthNameList, month);&lt;br /&gt;
    else&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// DateString() ///////////////////////////&lt;br /&gt;
&lt;br /&gt;
string DateString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer year       = llList2Integer(timelist,0);&lt;br /&gt;
    integer month      = llList2Integer(timelist,1);&lt;br /&gt;
    integer day        = llList2Integer(timelist,2);&lt;br /&gt;
    &lt;br /&gt;
    return (string)day + &amp;quot;-&amp;quot; + MonthName(month - 1) + &amp;quot;-&amp;quot; + (string)year;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// TimeString() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string TimeString(list timelist)&lt;br /&gt;
{&lt;br /&gt;
    integer hour          = llList2Integer(timelist,3);&lt;br /&gt;
    integer minute         = llList2Integer(timelist,4);&lt;br /&gt;
    integer second         = llList2Integer(timelist,5);&lt;br /&gt;
    string  hourstr     = (string)hour;&lt;br /&gt;
    string  minutestr   = (string)minute;&lt;br /&gt;
    string  secondstr   = (string)second;&lt;br /&gt;
    &lt;br /&gt;
    if (hour &amp;lt; 10)         hourstr     = &amp;quot;0&amp;quot; + hourstr;&lt;br /&gt;
    if (minute &amp;lt; 10)     minutestr     = &amp;quot;0&amp;quot; + minutestr;&lt;br /&gt;
    if (second &amp;lt; 10)    secondstr    = &amp;quot;0&amp;quot; + secondstr;&lt;br /&gt;
    return hourstr + &amp;quot;:&amp;quot; + minutestr + &amp;quot;:&amp;quot; + secondstr;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() /////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string body)&lt;br /&gt;
{&lt;br /&gt;
    // llOwnerSay(&amp;quot;Sending message to &#039;&amp;quot; + address + &amp;quot;&#039; with subject &#039;&amp;quot; + subject +&amp;quot;&#039;.&amp;quot;);&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND, body, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// SendHome() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
SendHome(string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_SENDHOME, body, (key)subject);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Show() ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Show()&lt;br /&gt;
{&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;Current chat recording is:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; NumLines; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(ChatRecording,i));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    llOwnerSay(&amp;quot;--------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;Lines is &amp;quot; + (string)NumLines);&lt;br /&gt;
    llOwnerSay(&amp;quot;Message length is &amp;quot; + (string)Length);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////// Read() /////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Read()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;Reading message &amp;quot; + (string)CurrentMessage + &amp;quot; from mail buffer.&amp;quot;);&lt;br /&gt;
    integer time = (integer)llList2Integer(TimeList,CurrentMessage);&lt;br /&gt;
    list timelist=Unix2DateTime(time);&lt;br /&gt;
    string Address = llList2String(AddressList,CurrentMessage);&lt;br /&gt;
    string Subject = llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
    string Body    = llList2String(BodyList,CurrentMessage);&lt;br /&gt;
    llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
    llOwnerSay(&amp;quot;Address: &amp;quot; + Address);&lt;br /&gt;
    llOwnerSay(&amp;quot;Subject: &amp;quot; + Subject);&lt;br /&gt;
    llOwnerSay(&amp;quot;Begin of message body:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    list bodylist=llParseStringKeepNulls(Body, [ &amp;quot;\n&amp;quot; ], []);&lt;br /&gt;
    integer num=llGetListLength(bodylist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(llList2String(bodylist,i));&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    llOwnerSay(&amp;quot;-------------------------&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;End of message body.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////// List ////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
List()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;The mail buffer contains the following messages:\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; NumMessages; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        integer time=llList2Integer(TimeList,i);&lt;br /&gt;
        list timelist=Unix2DateTime(time);&lt;br /&gt;
        if (i &amp;gt; 0) llOwnerSay(&amp;quot;+-+-+-+-+-+-+-+-+-+-+-+-&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Message: &amp;quot; + (string)i);&lt;br /&gt;
        llOwnerSay(&amp;quot;Date   : &amp;quot; + DateString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;Time   : &amp;quot; + TimeString(timelist));&lt;br /&gt;
        llOwnerSay(&amp;quot;From:    &amp;quot; + llList2String(AddressList,i));&lt;br /&gt;
        llOwnerSay(&amp;quot;Subject: &amp;quot; + llList2String(SubjectList,i));&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////// NotifyNewMail() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
NotifyNewMail(string time, string address, string subject, string body)&lt;br /&gt;
{&lt;br /&gt;
    list timelist=Unix2DateTime((integer)time);&lt;br /&gt;
&lt;br /&gt;
    if (StatusOnline)&lt;br /&gt;
    {&lt;br /&gt;
        llInstantMessage(llGetOwner(), &amp;quot;You received a new mail message on &amp;quot; &lt;br /&gt;
                                    + DateString(timelist) + &amp;quot; at &amp;quot; + TimeString(timelist)&lt;br /&gt;
                                    + &amp;quot; from &amp;quot; + address &lt;br /&gt;
                                    + &amp;quot; with the subject &amp;quot; + subject);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        SendHome(&amp;quot;FW: &amp;quot; + subject, &amp;quot;Received at: &amp;quot; + DateString(timelist) + &amp;quot; &amp;quot; + TimeString(timelist) + &amp;quot;\nFrom: &amp;quot; +  address &lt;br /&gt;
                    + &amp;quot;\nBegin message body:\n-------------------\n&amp;quot; + body + &amp;quot;\n-------------------\nEnd message body.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ResetOtherScripts() //////////////////////&lt;br /&gt;
&lt;br /&gt;
ResetOtherScripts()&lt;br /&gt;
{&lt;br /&gt;
    string     name;&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(ScriptList);&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        name = llList2String(ScriptList,i);&lt;br /&gt;
        &lt;br /&gt;
        if (llGetInventoryType(name) == INVENTORY_SCRIPT)&lt;br /&gt;
        {&lt;br /&gt;
            llResetOtherScript(name);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(&amp;quot;Error - script &#039;&amp;quot; + name + &amp;quot;&#039; not found.&amp;quot;);&lt;br /&gt;
            ErrorFlag = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
// default &lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ////////////////////// state_entry() /////////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Welcome to SL Mail, released under GNU software licence.&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Version &amp;quot; + SL_MAIL_VERSION + &amp;quot; &amp;quot; + SL_MAIL_DATE);&lt;br /&gt;
        llOwnerSay(&amp;quot;Produced by Logic Scripted Products &amp;amp; Product Services&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;Free memory: &amp;quot; + (string)llGetFreeMemory());&lt;br /&gt;
        ResetOtherScripts();&lt;br /&gt;
        &lt;br /&gt;
        if (ErrorFlag)&lt;br /&gt;
            state Error;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// on_rez() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// changed() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_LOADED)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_ADDRESSBOOK_ERROR)&lt;br /&gt;
        {&lt;br /&gt;
            state Error;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
//////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() //////////////////////&lt;br /&gt;
&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
        llOwnerSay(&amp;quot;SL mail ready.\nSend and Get mail in Second Life.\nType @HELP for more info.&amp;quot;);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
        llSetTimerEvent(MAIL_FETCH_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //////////////////////// on_rez() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// listen() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer channel, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string trimmessage=llStringTrim(message,STRING_TRIM);&lt;br /&gt;
        list   parse = llParseStringKeepNulls(trimmessage, [ &amp;quot; &amp;quot;], []);&lt;br /&gt;
        string command = llToUpper(llList2String(parse,0));&lt;br /&gt;
        string arg     = llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
        integer nargs  = llGetListLength(parse);&lt;br /&gt;
        string argstr=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        if (nargs &amp;gt; 1) argstr=llGetSubString(message, llSubStringIndex(message, &amp;quot; &amp;quot;) + 1, -1);&lt;br /&gt;
            &lt;br /&gt;
        if (Recording)&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Recording stopped. Type @SHOW to see the message you have entered,&amp;quot;&lt;br /&gt;
                            + &amp;quot; or @SEND to send it.&amp;quot;);&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                Recording = FALSE;&lt;br /&gt;
                &lt;br /&gt;
                SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                ChatRecording = (ChatRecording=[]) + ChatRecording + [ message ];&lt;br /&gt;
                ++NumLines;&lt;br /&gt;
                Length += llStringLength(message) + 2;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            if (command == COMMAND_RECORD)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Start recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                ChatRecording = [];&lt;br /&gt;
                NumLines=0;&lt;br /&gt;
                Length=0;&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CONTINUE)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Continue recording your message. Type @STOP to end recording.&amp;quot;);&lt;br /&gt;
                Recording = TRUE;&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_REPLY)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    string address=llList2String(AddressList,CurrentMessage);&lt;br /&gt;
                    string subject=&amp;quot;Re: &amp;quot; + llList2String(SubjectList,CurrentMessage);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, address, NULL_KEY);&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, subject, NULL_KEY);&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines=0;&lt;br /&gt;
                    Length=0;&lt;br /&gt;
                    Recording = TRUE;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_MAIL)&lt;br /&gt;
            {&lt;br /&gt;
                string mailaddress=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailaddress != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETADDRESS, mailaddress, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETADDRESS, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SUBJECT)&lt;br /&gt;
            {&lt;br /&gt;
                string mailsubject=llStringTrim(argstr,STRING_TRIM);&lt;br /&gt;
                &lt;br /&gt;
                if (mailsubject != &amp;quot;&amp;quot;)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETSUBJECT, mailsubject, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETSUBJECT, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_STOP)&lt;br /&gt;
            {&lt;br /&gt;
                llOwnerSay(&amp;quot;Not recording.&amp;quot;);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SEND)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    if (NumLines == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        SendMail(llDumpList2String(ChatRecording, &amp;quot;\n&amp;quot;));&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SEND_NOTECARD, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_IGNORE)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    ChatRecording = [];&lt;br /&gt;
                    NumLines = 0;&lt;br /&gt;
                    Length = 0;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumLines == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;No lines recorded.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Show();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_READ)&lt;br /&gt;
            {&lt;br /&gt;
                if (NumMessages == 0)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    Read();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_NEXT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        ++CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_PREV)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        --CurrentMessage;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_FIRST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at first message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = 0;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LAST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    if (CurrentMessage == NumMessages - 1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Already at last message.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                        Read();&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_LIST)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    List();&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SELECT)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else if (nargs == 1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;Need to supply a message number.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    integer msgnum = (integer)arg;&lt;br /&gt;
                     &lt;br /&gt;
                    if (msgnum &amp;lt; 0 || msgnum &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        llOwnerSay(&amp;quot;Message number &amp;quot; + arg + &amp;quot; not in mail buffer.&amp;quot;);&lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = msgnum;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_DELETE)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList = llDeleteSubList(TimeList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    AddressList = llDeleteSubList(AddressList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    SubjectList = llDeleteSubList(SubjectList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    BodyList = llDeleteSubList(BodyList,CurrentMessage,CurrentMessage);&lt;br /&gt;
                    --NumMessages;&lt;br /&gt;
                     &lt;br /&gt;
                    if (NumMessages == 0)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = -1;&lt;br /&gt;
                    }&lt;br /&gt;
                    else if (CurrentMessage &amp;gt;= NumMessages)&lt;br /&gt;
                    {&lt;br /&gt;
                        CurrentMessage = NumMessages - 1;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_CLEAR)&lt;br /&gt;
            {&lt;br /&gt;
                if (CurrentMessage == -1)&lt;br /&gt;
                {&lt;br /&gt;
                    llOwnerSay(&amp;quot;The mail buffer is empty.&amp;quot;);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    TimeList=[];&lt;br /&gt;
                    AddressList=[];&lt;br /&gt;
                    SubjectList=[];&lt;br /&gt;
                    BodyList=[];&lt;br /&gt;
                    NumMessages=0;&lt;br /&gt;
                    CurrentMessage=-1;&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HELP)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_HELP, arg, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_INFO)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_INFO, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_SHOW)&lt;br /&gt;
            {&lt;br /&gt;
                Show();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_RESET)&lt;br /&gt;
            {&lt;br /&gt;
                llResetScript();&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_OFF)&lt;br /&gt;
            {&lt;br /&gt;
                state not_running;&lt;br /&gt;
            }&lt;br /&gt;
            if (command == COMMAND_HOME)&lt;br /&gt;
            {&lt;br /&gt;
                if (nargs==1)&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_GETHOME, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_SETHOME, argstr, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
                return;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llGetNextEmail(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// email() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    email(string time, string address, string subject, string body, integer queued)&lt;br /&gt;
    {&lt;br /&gt;
        NotifyNewMail(time, address, subject, body);&lt;br /&gt;
        TimeList = (TimeList=[]) + TimeList + [time];&lt;br /&gt;
        AddressList = (AddressList=[]) + AddressList + [address];&lt;br /&gt;
        SubjectList = (SubjectList=[]) + SubjectList + [subject];&lt;br /&gt;
        BodyList = (BodyList=[]) + BodyList + [body];&lt;br /&gt;
        ++NumMessages;&lt;br /&gt;
        &lt;br /&gt;
        if (CurrentMessage == -1)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = 0;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMessage = NumMessages - 1;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_REPLY)&lt;br /&gt;
        {&lt;br /&gt;
            llOwnerSay(message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state not_running&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state not_running&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;SL Mailbox switched OFF. Say @ON to switch it back on.&amp;quot;);&lt;br /&gt;
        llListen(0, &amp;quot;&amp;quot;, llGetOwner(), &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// on_rez() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////// listen() ////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    listen(integer chan, string name, key id, string message)&lt;br /&gt;
    {&lt;br /&gt;
        string command=llToUpper(message);&lt;br /&gt;
        &lt;br /&gt;
        if (command == COMMAND_ON)&lt;br /&gt;
        {&lt;br /&gt;
            state running;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// link_message() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_STATUS_ONLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = TRUE;&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_STATUS_OFFLINE)&lt;br /&gt;
        {&lt;br /&gt;
            StatusOnline = FALSE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// state Error&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state Error&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llOwnerSay(&amp;quot;Error in SL Mail: not all component scripts found.&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    changed(integer mask)&lt;br /&gt;
    {&lt;br /&gt;
        if (mask &amp;amp; CHANGED_INVENTORY)&lt;br /&gt;
        {&lt;br /&gt;
            llResetScript();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    on_rez(integer start_param)&lt;br /&gt;
    {&lt;br /&gt;
        llResetScript();&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
// End SL Mail V1.2.lsl&lt;br /&gt;
//////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Address Book V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Read and interpret the contents of the Address Book.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail AddressBook V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
// DESCRIPTION&lt;br /&gt;
// &lt;br /&gt;
//  Read the Address Book from a notecard named &amp;quot;Address Book&amp;quot;.&lt;br /&gt;
//&lt;br /&gt;
//  The Address Book has the following format:&lt;br /&gt;
//  &lt;br /&gt;
//  [ADDRESS BOOK]&lt;br /&gt;
//  Name1=username@yourdomain.com&lt;br /&gt;
//  Name2=otheruser@otherdomain.com&lt;br /&gt;
//  ...&lt;br /&gt;
//  [GROUP]&lt;br /&gt;
//  group1=Name1, Name2&lt;br /&gt;
//  ...&lt;br /&gt;
//&lt;br /&gt;
//  Notes:&lt;br /&gt;
//  1. Group and Name share the same namespace, and must be unique.&lt;br /&gt;
//  2. It is allowed to have a name in the addressbook with multiple addresses, seperated by comma&#039;s.&lt;br /&gt;
// &lt;br /&gt;
/////////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
string  CurrentMailAddress = &amp;quot;&amp;quot;;&lt;br /&gt;
string  CurrentMailSubject = &amp;quot;&amp;quot;;&lt;br /&gt;
integer StatusOnline = FALSE;&lt;br /&gt;
&lt;br /&gt;
// Fetch or Send notecard&lt;br /&gt;
&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Names&lt;br /&gt;
&lt;br /&gt;
list    AddressBookList=[];&lt;br /&gt;
list    MailAddressList=[];&lt;br /&gt;
&lt;br /&gt;
string  STRING_HOME=&amp;quot;HOME&amp;quot;;&lt;br /&gt;
string  STRING_SELF=&amp;quot;SELF&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Address Book Groups&lt;br /&gt;
&lt;br /&gt;
list   GroupList=[];&lt;br /&gt;
list   GroupNameList=[];&lt;br /&gt;
&lt;br /&gt;
string LSL_DOMAIN = &amp;quot;lsl.secondlife.com&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Read Address Book notecard&lt;br /&gt;
&lt;br /&gt;
string  ADDRESSBOOK_NOTECARD=&amp;quot;Address Book&amp;quot;;&lt;br /&gt;
integer Line=0;&lt;br /&gt;
key     reqAddressBook=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=5.0;&lt;br /&gt;
&lt;br /&gt;
integer Section=0;&lt;br /&gt;
integer SECTION_ADDRESS_BOOK=1;&lt;br /&gt;
integer SECTION_GROUP=2;&lt;br /&gt;
string  STRING_ADDRESS_BOOK=&amp;quot;ADDRESS BOOK&amp;quot;;&lt;br /&gt;
string  STRING_GROUP=&amp;quot;GROUP&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
// Links messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_SETADDRESS          = 90000;&lt;br /&gt;
integer MSG_MESSAGE_GETADDRESS          = 90050;&lt;br /&gt;
integer MSG_MESSAGE_SETSUBJECT          = 90100;&lt;br /&gt;
integer MSG_MESSAGE_GETSUBJECT          = 90150;&lt;br /&gt;
integer MSG_MESSAGE_SEND                = 90200;&lt;br /&gt;
integer MSG_MESSAGE_SENDHOME            = 90300;&lt;br /&gt;
integer MSG_MESSAGE_SEND_NOTECARD       = 90400;&lt;br /&gt;
integer MSG_MESSAGE_ADDRESSBOOK         = 90500;&lt;br /&gt;
integer MSG_MESSAGE_GETHOME             = 90600;&lt;br /&gt;
integer MSG_MESSAGE_SETHOME             = 90700;&lt;br /&gt;
integer MSG_MESSAGE_INFO                = 90800;&lt;br /&gt;
integer MSG_MESSAGE_NOTIFY              = 90900;&lt;br /&gt;
&lt;br /&gt;
integer MSG_ADDRESSBOOK_LOADED            = 91000;&lt;br /&gt;
integer MSG_ADDRESSBOOK_ERROR            = 91100;&lt;br /&gt;
&lt;br /&gt;
integer MSG_MESSAGE_REPLY               = 99000;&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// GetSelfAddress() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
string GetSelfAddress()&lt;br /&gt;
{&lt;br /&gt;
    return (string)llGetKey() + &amp;quot;@&amp;quot; + LSL_DOMAIN;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// Info() /////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Info()&lt;br /&gt;
{&lt;br /&gt;
    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;The mail address for this object is: &amp;quot; &lt;br /&gt;
                    + GetSelfAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// IsValidKeyFormat() //////////////////////&lt;br /&gt;
&lt;br /&gt;
integer IsValidKeyFormat(string str)&lt;br /&gt;
{&lt;br /&gt;
    string keychars = &amp;quot;0123456789abcdef&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    if (llStringLength(str) != 36)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    if( (llGetSubString( str, 8, 8 )   != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 13, 13 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 18, 18 )  != &amp;quot;-&amp;quot; ||&lt;br /&gt;
        llGetSubString( str, 23, 23 )  != &amp;quot;-&amp;quot; ) )&lt;br /&gt;
        return FALSE;&lt;br /&gt;
&lt;br /&gt;
    integer i;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; 8; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 9; i &amp;lt; 13; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 14; i &amp;lt; 18; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 19; i &amp;lt; 23; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    for (i = 24; i &amp;lt; 36; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        if (llSubStringIndex(keychars, llGetSubString(str,i,i)) == -1)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// ValidMailAddress() ////////////////////////&lt;br /&gt;
&lt;br /&gt;
integer ValidMailAddress(string arg)&lt;br /&gt;
{&lt;br /&gt;
    string adress = llToLower(llStringTrim(arg,STRING_TRIM));&lt;br /&gt;
    &lt;br /&gt;
    if (adress == &amp;quot;&amp;quot;)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
        &lt;br /&gt;
    list parse = llParseStringKeepNulls(adress, [ &amp;quot;@&amp;quot; ], []);&lt;br /&gt;
    string account = llList2String(parse,0);&lt;br /&gt;
    string domain  = llList2String(parse,1);&lt;br /&gt;
    &lt;br /&gt;
    if (llGetListLength(parse) != 2 || llStringLength(account) == 0 || llStringLength(domain) == 0)&lt;br /&gt;
        return FALSE;&lt;br /&gt;
    &lt;br /&gt;
    if (domain == LSL_DOMAIN)&lt;br /&gt;
    {&lt;br /&gt;
        return IsValidKeyFormat(account);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list parsedomain = llParseString2List(domain, [ &amp;quot;.&amp;quot; ], []);&lt;br /&gt;
    &lt;br /&gt;
        if (llGetListLength(parsedomain) &amp;lt; 2)&lt;br /&gt;
            return FALSE;&lt;br /&gt;
        &lt;br /&gt;
        integer num = llGetListLength(parsedomain);&lt;br /&gt;
        integer i;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llStringLength(llList2String(parsedomain,i)) &amp;lt; 2)&lt;br /&gt;
            {&lt;br /&gt;
                return FALSE;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return TRUE;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetAddressStr() ///////////////////&lt;br /&gt;
&lt;br /&gt;
string GetAndCheckAddressStr(string address)&lt;br /&gt;
{&lt;br /&gt;
    list addresslist = llCSV2List(address);&lt;br /&gt;
    integer num=llGetListLength(addresslist);&lt;br /&gt;
    integer i;&lt;br /&gt;
    string addressstr=&amp;quot;&amp;quot;;&lt;br /&gt;
    string curaddress=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
    {&lt;br /&gt;
        curaddress=llList2String(addresslist,i);&lt;br /&gt;
        &lt;br /&gt;
        if (ValidMailAddress(curaddress))&lt;br /&gt;
        {&lt;br /&gt;
            addressstr = (addressstr=&amp;quot;&amp;quot;) + addressstr + curaddress + &amp;quot;,&amp;quot;;&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address string: &#039;&amp;quot; &lt;br /&gt;
                            + curaddress + &amp;quot;&#039;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    return llGetSubString(addressstr, 0, -2);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////// ProcessLine() ////////////////////////////&lt;br /&gt;
&lt;br /&gt;
ProcessLine(string rawline)&lt;br /&gt;
{&lt;br /&gt;
    string line=llStringTrim(rawline,STRING_TRIM);&lt;br /&gt;
    string first=llGetSubString(line,0,0);&lt;br /&gt;
    string last=llGetSubString(line,-1,-1);&lt;br /&gt;
    &lt;br /&gt;
    // Ignore a blank line or comment line&lt;br /&gt;
    if (line == &amp;quot;&amp;quot; || first == &amp;quot;#&amp;quot;)&lt;br /&gt;
        return;&lt;br /&gt;
&lt;br /&gt;
    // Check for the right section&lt;br /&gt;
    &lt;br /&gt;
    if (first == &amp;quot;[&amp;quot; &amp;amp;&amp;amp; last == &amp;quot;]&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        string sectionstr=llToUpper(llStringTrim(llGetSubString(line,1,-2),STRING_TRIM));&lt;br /&gt;
        &lt;br /&gt;
        if (sectionstr == STRING_ADDRESS_BOOK)&lt;br /&gt;
        {&lt;br /&gt;
            Section = SECTION_ADDRESS_BOOK;&lt;br /&gt;
        }&lt;br /&gt;
        else if (sectionstr == STRING_GROUP)&lt;br /&gt;
        {&lt;br /&gt;
            if (Section == 0)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                        + &amp;quot;. Group section defined before Address Book section.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Section = SECTION_GROUP;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid section header &#039;&amp;quot; + sectionstr &lt;br /&gt;
                        + &amp;quot;&#039; in &amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Must be in a section&lt;br /&gt;
    &lt;br /&gt;
    if (Section == 0)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;. No section header.&amp;quot;, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    list     parse=llParseString2List(line, [ &amp;quot;=&amp;quot; ], []);&lt;br /&gt;
    integer  num=llGetListLength(parse);&lt;br /&gt;
    &lt;br /&gt;
    // Format must be correct&lt;br /&gt;
    &lt;br /&gt;
    if (num != 2)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid syntax in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; +  (string)(Line+1) + &amp;quot;:\n&amp;quot; + rawline, NULL_KEY);&lt;br /&gt;
        return;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    if (Section == SECTION_ADDRESS_BOOK)&lt;br /&gt;
    {&lt;br /&gt;
        string name=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(name) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + name &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ name ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            string address=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
            string addressstr=GetAndCheckAddressStr(address);&lt;br /&gt;
            &lt;br /&gt;
            if (addressstr != &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                AddressBookList     = (AddressBookList=[])     + AddressBookList     + [ name ];&lt;br /&gt;
                MailAddressList     = (MailAddressList=[])     + MailAddressList     + [ addressstr ];&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;No valid mail address for &#039;&amp;quot; + name &lt;br /&gt;
                    + &amp;quot;&#039;. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) &lt;br /&gt;
                    + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name &lt;br /&gt;
                + &amp;quot;&#039; already defined. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else // Group&lt;br /&gt;
    {&lt;br /&gt;
        string group=llStringTrim(llList2String(parse,0),STRING_TRIM);&lt;br /&gt;
        &lt;br /&gt;
        if (llToUpper(group) == STRING_SELF)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Invalid address book entry &#039;&amp;quot; + group &lt;br /&gt;
                            + &amp;quot;&#039;. Reserved word in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD &lt;br /&gt;
                        + &amp;quot;&#039; at line &amp;quot; + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (llListFindList(AddressBookList, [ group ]) == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llListFindList(GroupList, [ group ]) == -1)&lt;br /&gt;
            {&lt;br /&gt;
                string names=llStringTrim(llList2String(parse,1),STRING_TRIM);&lt;br /&gt;
                list   namelist=llCSV2List(names);&lt;br /&gt;
                integer num=llGetListLength(namelist);&lt;br /&gt;
                integer i;&lt;br /&gt;
                integer index;&lt;br /&gt;
                string  name;&lt;br /&gt;
                string  namestr=&amp;quot;&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
                for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
                {&lt;br /&gt;
                    name=llList2String(namelist,i);&lt;br /&gt;
                    index=llListFindList(AddressBookList, [ name ]);&lt;br /&gt;
            &lt;br /&gt;
                    if (index == -1)&lt;br /&gt;
                    {&lt;br /&gt;
                        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Name &#039;&amp;quot; + name + &amp;quot;&#039; defined in Group &#039;&amp;quot; &lt;br /&gt;
                                + group + &amp;quot;&#039; not found in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY); &lt;br /&gt;
                    }&lt;br /&gt;
                    else&lt;br /&gt;
                    {&lt;br /&gt;
                        namestr = (namestr=&amp;quot;&amp;quot;) + namestr + name + &amp;quot;,&amp;quot;;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
&lt;br /&gt;
                if (namestr != &amp;quot;&amp;quot;)&lt;br /&gt;
                {    &lt;br /&gt;
                    namestr=llGetSubString(namestr,0,-2);&lt;br /&gt;
                    GroupList         = (GroupList=[])         + GroupList     + [ group ];&lt;br /&gt;
                    GroupNameList     = (GroupNameList=[])    + GroupNameList + [ namestr ];&lt;br /&gt;
                }&lt;br /&gt;
                else&lt;br /&gt;
                {&lt;br /&gt;
                    llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                        + &amp;quot;&#039; has no valid names. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                        + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group &lt;br /&gt;
                    + &amp;quot;&#039; already defined in Group. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                    + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Group &#039;&amp;quot; + group&lt;br /&gt;
                + &amp;quot;&#039; already defined in Address Book. Entry skipped in &#039;&amp;quot; + ADDRESSBOOK_NOTECARD + &amp;quot;&#039; at line &amp;quot; &lt;br /&gt;
                + (string)(Line + 1) + &amp;quot;.&amp;quot;, NULL_KEY);            &lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// GetGroupAddressList ///////////////&lt;br /&gt;
&lt;br /&gt;
string GetGroupAddressList(string group)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(GroupList, [ group ]);&lt;br /&gt;
    integer i;&lt;br /&gt;
    integer num=llGetListLength(GroupList);&lt;br /&gt;
    string  grouplist=&amp;quot;&amp;quot;;&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        for (i = index; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            if (llList2String(GroupList,i) == group)&lt;br /&gt;
            {&lt;br /&gt;
                grouplist = (grouplist=&amp;quot;&amp;quot;) + grouplist + llList2String(GroupNameList,i) + &amp;quot;,&amp;quot;;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        if (grouplist != &amp;quot;&amp;quot;) grouplist=llGetSubString(grouplist,0,-2);   // remove last &amp;quot;,&amp;quot;&lt;br /&gt;
        return grouplist;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//////////////////////////////// SetMailAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetMailAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ address ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        index=llListFindList(GroupList, [ address ]);&lt;br /&gt;
        &lt;br /&gt;
        if (index == -1)&lt;br /&gt;
        {&lt;br /&gt;
            if (llToUpper(address) == STRING_SELF)&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = GetSelfAddress();&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if(ValidMailAddress(address))&lt;br /&gt;
            {&lt;br /&gt;
                CurrentMailAddress = address;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                                + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Mail adress &amp;quot; + address &lt;br /&gt;
                            + &amp;quot; : not found in adress book or invalid format.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailAddress = GetGroupAddressList(address);&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        CurrentMailAddress = llList2String(MailAddressList,index);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address set to: &amp;quot; &lt;br /&gt;
                        + CurrentMailAddress, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMail() ///////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMail(string message)&lt;br /&gt;
{&lt;br /&gt;
    if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No mail address defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;SendMail: No subject defined.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        list mailaddresslist=llCSV2List(CurrentMailAddress);&lt;br /&gt;
        integer num=llGetListLength(mailaddresslist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(mailaddresslist,i);&lt;br /&gt;
            llEmail(address, CurrentMailSubject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SendMailHome() ////////////////////&lt;br /&gt;
&lt;br /&gt;
SendMailHome(string message, string subject)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, STRING_HOME &lt;br /&gt;
                + &amp;quot; not set. Set your home adress with @HOME &amp;lt;address&amp;gt;.&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        string homeaddress=llList2String(AddressBookList,index);&lt;br /&gt;
        list   homelist=llCSV2List(homeaddress);&lt;br /&gt;
        integer num=llGetListLength(homelist);&lt;br /&gt;
        integer i;&lt;br /&gt;
        string address;&lt;br /&gt;
        &lt;br /&gt;
        for (i = 0; i &amp;lt; num; ++i)&lt;br /&gt;
        {&lt;br /&gt;
            address=llList2String(homelist,i);&lt;br /&gt;
            llEmail(address, subject, message);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// GetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
string GetHomeAddress()&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        return &amp;quot;not set&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        return llList2String(MailAddressList,index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////// SetHomeAddress() //////////////////&lt;br /&gt;
&lt;br /&gt;
SetHomeAddress(string address)&lt;br /&gt;
{&lt;br /&gt;
    integer index=llListFindList(AddressBookList, [ STRING_HOME ]);&lt;br /&gt;
    &lt;br /&gt;
    if (index == -1)&lt;br /&gt;
    {&lt;br /&gt;
        AddressBookList     = (AddressBookList=[]) + [ STRING_HOME ] + AddressBookList;&lt;br /&gt;
        MailAddressList     = (MailAddressList=[]) + [ GetAndCheckAddressStr(address) ]  + MailAddressList;&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        MailAddressList = llListReplaceList(MailAddressList, [ GetAndCheckAddressStr(address) ], index, index);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////// state_entry() //////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        Line=0;&lt;br /&gt;
        Section=0;&lt;br /&gt;
        llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, 0);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////// dataserver() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqAddressBook)&lt;br /&gt;
        {&lt;br /&gt;
            reqAddressBook = NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                ProcessLine(data);&lt;br /&gt;
                reqAddressBook=llGetNotecardLine(ADDRESSBOOK_NOTECARD, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Address Book loaded.&amp;quot;, NULL_KEY);&lt;br /&gt;
                state running;&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    //////////////////////// timer() ///////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_ERROR, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Could not read Address Book: &amp;quot; &lt;br /&gt;
                            + ADDRESSBOOK_NOTECARD + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
// state running&lt;br /&gt;
////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
state running&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llMessageLinked(LINK_THIS, MSG_ADDRESSBOOK_LOADED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// link_message() ////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_MESSAGE_GETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailSubject == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is empty.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject is: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETSUBJECT)&lt;br /&gt;
        {&lt;br /&gt;
            CurrentMailSubject = message;&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail subject set to: &amp;quot; &lt;br /&gt;
                            + CurrentMailSubject, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            if (CurrentMailAddress == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is empty.&amp;quot;, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Current mail address is: &amp;quot; &lt;br /&gt;
                            + CurrentMailAddress, NULL_KEY);        &lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETADDRESS)&lt;br /&gt;
        {&lt;br /&gt;
            SetMailAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Body of message to send is empty. &amp;quot; &lt;br /&gt;
                                +  &amp;quot;No mail is send.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SENDHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SendMailHome(message, (string)id);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SEND_NOTECARD)&lt;br /&gt;
        {&lt;br /&gt;
            if (llGetInventoryType(message) == INVENTORY_NOTECARD)&lt;br /&gt;
            {&lt;br /&gt;
                Notecard2Fetch = message;                &lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_READ, message, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + message + &amp;quot; not found.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_NOTECARD_FETCHED)&lt;br /&gt;
        {&lt;br /&gt;
            if (message == &amp;quot;&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Notecard &amp;quot; + Notecard2Fetch &lt;br /&gt;
                            + &amp;quot; was empty or could not be read.&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                SendMail(message);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_GETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_MESSAGE_REPLY, &amp;quot;Home address is: &amp;quot; + GetHomeAddress() + &amp;quot;.&amp;quot;, NULL_KEY);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_SETHOME)&lt;br /&gt;
        {&lt;br /&gt;
            SetHomeAddress(message);&lt;br /&gt;
        }&lt;br /&gt;
        else if (msgid == MSG_MESSAGE_INFO)&lt;br /&gt;
        {&lt;br /&gt;
            Info();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
// End SL Mail AddressBook V1.2.lsl&lt;br /&gt;
/////////////////////////////////////&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail FetchNotecard V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch the contents of a notecard and return it via link message as a string.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Notecard&lt;br /&gt;
&lt;br /&gt;
integer Line=0;&lt;br /&gt;
string  Notecard2Fetch=&amp;quot;&amp;quot;;&lt;br /&gt;
key     reqNotecard=NULL_KEY;&lt;br /&gt;
float   TIMEOUT_INTERVAL=10.0;&lt;br /&gt;
integer Fetched=FALSE;&lt;br /&gt;
&lt;br /&gt;
// Lines&lt;br /&gt;
&lt;br /&gt;
list LineList=[];&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_NOTECARD_READ               = 100000;&lt;br /&gt;
integer MSG_NOTECARD_FETCHED            = 100100;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    /////////////////////// dataserver() //////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqNotecard)&lt;br /&gt;
        {&lt;br /&gt;
            reqNotecard=NULL_KEY;&lt;br /&gt;
            &lt;br /&gt;
            if (data != EOF)&lt;br /&gt;
            {&lt;br /&gt;
                LineList = (LineList=[]) + LineList + [ data ];&lt;br /&gt;
                reqNotecard = llGetNotecardLine(Notecard2Fetch, ++Line);&lt;br /&gt;
            }&lt;br /&gt;
            else&lt;br /&gt;
            {&lt;br /&gt;
                Fetched=TRUE;&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, llDumpList2String(LineList, &amp;quot;\n&amp;quot;), NULL_KEY);&lt;br /&gt;
                llSetTimerEvent(0.0);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /////////////////////// timer() ///////////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        if (!Fetched)&lt;br /&gt;
        {&lt;br /&gt;
            llMessageLinked(LINK_THIS, MSG_NOTECARD_FETCHED, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            llSetTimerEvent(0.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /////////////////////// link_message() ////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    link_message(integer send, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_NOTECARD_READ)&lt;br /&gt;
        {&lt;br /&gt;
            Line=0;&lt;br /&gt;
            Notecard2Fetch=message;&lt;br /&gt;
            LineList=[];&lt;br /&gt;
            Fetched=FALSE;&lt;br /&gt;
            reqNotecard=llGetNotecardLine(Notecard2Fetch, Line);&lt;br /&gt;
            llSetTimerEvent(TIMEOUT_INTERVAL);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail FetchNotecard V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL OnlineStatus V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Fetch online status of owner.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
// Online status&lt;br /&gt;
&lt;br /&gt;
key     reqOnlineStatus=NULL_KEY;&lt;br /&gt;
float   STATUS_INTERVAL=2.0;&lt;br /&gt;
&lt;br /&gt;
// Link messages&lt;br /&gt;
&lt;br /&gt;
integer MSG_STATUS_ONLINE       = 30000;&lt;br /&gt;
integer MS_STATUS_OFFLINE       = 30100;&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    ///////////////////////// state_entry() /////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus=llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
        llSetTimerEvent(STATUS_INTERVAL);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// dataserver() //////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    dataserver(key id, string data)&lt;br /&gt;
    {&lt;br /&gt;
        if (id == reqOnlineStatus)&lt;br /&gt;
        {&lt;br /&gt;
            reqOnlineStatus = NULL_KEY;&lt;br /&gt;
        &lt;br /&gt;
            if (data==&amp;quot;1&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MSG_STATUS_ONLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
            else if (data==&amp;quot;0&amp;quot;)&lt;br /&gt;
            {&lt;br /&gt;
                llMessageLinked(LINK_THIS, MS_STATUS_OFFLINE, &amp;quot;&amp;quot;, NULL_KEY);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    ///////////////////////// timer() ///////////////////////////////&lt;br /&gt;
    &lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        reqOnlineStatus = llRequestAgentData(llGetOwner(), DATA_ONLINE);&lt;br /&gt;
    }    &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail OnlineStatus V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div id=&amp;quot;box&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Script: SL Mail Help V1.2==&lt;br /&gt;
&amp;lt;div style=&amp;quot;padding: 0.5em;&amp;quot;&amp;gt;&lt;br /&gt;
Display help information.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// SL Mail Help V1.2.lsl&lt;br /&gt;
//&lt;br /&gt;
//&lt;br /&gt;
&lt;br /&gt;
integer MSG_HELP    = 10000;&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////// Help() ///////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
Help()&lt;br /&gt;
{&lt;br /&gt;
    llOwnerSay(&amp;quot;HELP for SL Mail V1.2.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;COMMANDS:&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HELP               - displays help info.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@INFO               - display mailaddress of this object.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RECORD             - start recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CONTINUE           - continue recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@STOP               - stop recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@IGNORE             - ignore the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SHOW               - show what your recorded.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SEND               - send the recording.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@MAIL &amp;lt;mailadress&amp;gt;  - set the mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SUBJECT subject    - set the mail subject.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LIST               - list messages in mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@SELECT &amp;lt;message&amp;gt;   - select message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@READ               - read current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@NEXT               - read next message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@PREV               - read previous message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@FIRST              - read first message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@LAST               - read last message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@DELETE             - delete current message from mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@CLEAR              - clear the mail buffer.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@REPLY              - reply to current message.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@RESET              - reset the script.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@HOME               - set the home mail adress.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@OFF                - switch mailbox OFF.&amp;quot;);&lt;br /&gt;
    llOwnerSay(&amp;quot;@ON                 - switch mailbox ON.&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
// default&lt;br /&gt;
/////////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    link_message(integer sender, integer msgid, string message, key id)&lt;br /&gt;
    {&lt;br /&gt;
        if (msgid == MSG_HELP)&lt;br /&gt;
        {&lt;br /&gt;
            Help();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// End SL Mail Help V1.2.lsl&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
{{LSLC|Library}}&lt;/div&gt;</description>
			<pubDate>Sun, 07 Oct 2007 09:48:05 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/Talk:SL_Mail_V1.2</comments>
		</item>
		<item>
			<title>User:Flennan Roffo</title>
			<link>https://wiki.secondlife.com/w/index.php?title=User:Flennan_Roffo&amp;diff=34429</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=User:Flennan_Roffo&amp;diff=34429</guid>
			<description>&lt;p&gt;Flennan Roffo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
=About Flennan Roffo=&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
||[[Image:FlennanRoffo80x80.jpg|frameless|100px|Flennan Roffo]]&lt;br /&gt;
||Second Life resident since 11 July 2007. Scripter and owner of Logic Scripted products and Script services. You can visit me at my office in Peacock Park (189, 226, 69):&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logic Scripted products and Script services=&lt;br /&gt;
[[Image:Logicscripts.org.jpg]]&lt;br /&gt;
&lt;br /&gt;
==ABOUT LOGIC==&lt;br /&gt;
Logic Scripted Products and Script Services is, as you might have already guessed, all about LSL scripts and script services. My goal is to provide many good quality scripts for every business.&lt;br /&gt;
&lt;br /&gt;
==PRODUCTS==&lt;br /&gt;
&lt;br /&gt;
I am in the process of developing some very usefull products. Note though that each of these products are in early development phase and that new feautures will be released in upcoming releases. Currently I have released the following products:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Logic Mailbox Basic V 1.0&#039;&#039;&#039;&lt;br /&gt;
Basic model for a mailbox that allows anyone to drop you a notecard. Comes with a standard skin. For skin customization, contact Mad Maddy Studio.&lt;br /&gt;
&lt;br /&gt;
[[Image:Slmailbox.jpg]]&lt;br /&gt;
&lt;br /&gt;
See the demo at Logic office: &lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Logic Vendor V 1.0&#039;&#039;&#039;&lt;br /&gt;
Vendor that allows you to display many sellable items (objects) and per item you can give a customer a notecard. The sell price is split amongst multiple authors. Set up is easy, since you have to enter the key of each author only once, and can reference any author by nick.&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicvendorv10.jpg|300px]]&lt;br /&gt;
&lt;br /&gt;
See the demo at Logic office:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;SL Mail V 1.2&#039;&#039;&#039;&lt;br /&gt;
SecondLife mail client, released under GNU GPL licence. You can send and receive mail from within SecondLife both from and to other mail clients or external mail adresses. Has many command options and comes with an adjustable address book that allows to enter addresses and address groups.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Get your free copy today at logic office:&#039;&#039;&#039;&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Or, alternatively, get it from the Second Life wiki [[SL Mail V1.2|here]]&lt;br /&gt;
&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
==SERVICE CHARGING POLICY==&lt;br /&gt;
&lt;br /&gt;
The charging policy for script services depends on a number of factors:&lt;br /&gt;
* The usuability of the script. Simply stated, if the script does not provide what it is supposed to do no charge will be applied.&lt;br /&gt;
* The amount of work needed to create, adapt and test the script.&lt;br /&gt;
* The custumor. As a rule, the richer the customer, the higher the price, and the more the script or service I provide enhances business profits, the more is charged.&lt;br /&gt;
* The pricing will be based on the length of the service timeperiod.&lt;br /&gt;
* Prices are within reason.&lt;br /&gt;
* Part or whole price can be refunded if you have a well grounded complaint (script not behaving as specified or a large delay in delivering the scripts).&lt;br /&gt;
* Payment in advance for small projects are not necessary. For larger projects in which significant amount of time is invested advanced payment is asked for in the order of 10%-50% of the agreed price.&lt;br /&gt;
&lt;br /&gt;
==TERMS OF USE==&lt;br /&gt;
&lt;br /&gt;
The scripts I make available public will come with a Terms of Use or Fair Use policy.&lt;br /&gt;
&lt;br /&gt;
These terms of use include:&lt;br /&gt;
&lt;br /&gt;
* No selling or charging for free scripts&lt;br /&gt;
&lt;br /&gt;
Any script you purchase at Logic and/or is provided by Logic (either as a seperate script or as part of a Logic Scripted Product) MAY NOT BE RESOLD OR CHARGED FOR.&lt;br /&gt;
&lt;br /&gt;
If I find someone either selling Logic scripts or making a no-mod version of it, I will contact you about breaking this rule, and if necessary there will be made a public notice of this and take other measures if necessary.&lt;br /&gt;
&lt;br /&gt;
* No breaking of SL TOS&lt;br /&gt;
&lt;br /&gt;
You may not use any script or product (wether a Logic script or product or not) that breaks the Second Life Terms of Service (TOS). You can find the SL TOS on the official Second Life website:  http://www.secondlife.com&lt;br /&gt;
&lt;br /&gt;
* Donate for free scripts/services&lt;br /&gt;
&lt;br /&gt;
If you found my scripts and/or other services quite usefull and got them free of charge, you might consider giving a donation. A donation box will be installed any time soon.&lt;br /&gt;
&lt;br /&gt;
==HIRING==&lt;br /&gt;
&lt;br /&gt;
Logic can be hired for diverse projects. This includes besised LSL scripts and also website interfaces (PHP/MySQL) that interface with a scripted product in Second Life. Examples: visitor statistics, detectors, security devices, vendors, rental boxes, and so on. &lt;br /&gt;
&lt;br /&gt;
==LOGIC &amp;amp; STUDIO MAD MADDY==&lt;br /&gt;
&lt;br /&gt;
Logic Scripted Products and Script Services cooperates with Mad Maddy Studio. Mad Maddy Studio is specialised in custom made Textures, Business Logo&#039;s and so on. &lt;br /&gt;
&lt;br /&gt;
For more information about Mad Maddy Studio, and for all your graphical design requests, contact: [[User:Madeliefste Oh|Madeliefste Oh]].&lt;br /&gt;
&lt;br /&gt;
[[Image:MMbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=LSL Scripts &amp;amp; Tutorials=&lt;br /&gt;
Logic Scripted products and Script services is serving the broad public domain also by providing a good resource for scripts and script tutorials. This webservice is starting somewhere in october or november 2007.&lt;br /&gt;
The plan is to both collect &amp;amp; document existing scripts that reside in the inventory of residents or circulate in script groups and also create some new scripts ourselves that serve the interest of the public domain at large, and which will complement existing LSL wiki&#039;s, website and script resources/tutorials around the world wide web.&lt;br /&gt;
The website will provide usefull resources for both scripters and non-scripters (script users) and will accomodate both the interests of those that are new to scripting as well as die-hard LSL scripters.&lt;br /&gt;
==SCRIPT &amp;amp; SCRIPT TUTORIAL LIBRARY==&lt;br /&gt;
Both scripts and script tutorials will be placed in a repository/database which facilitates easy access and good searching options and is open for contributions by anyone. To maintain a good quality level some form of moderation will be put in place. User feedback to the site will be encouraged strongly, as  also the sharing of script knowledge, tips &amp;amp; tricks, etc. Other planned part of the website will be a page to make requests for scripts, either for scripts that do not yet exist in the public domain, or for feature requests on existing scripts. Be aware though that this service is not meant to be a place for hiring scripters or to buy a script, and is not intended to replace companies that provide those services for fees, but only is meant to serve the interests of the public in improving high quality scripts that are available as open source.&lt;br /&gt;
==SCRIPT USERS==&lt;br /&gt;
For those that do not do scripting themselves, and have no interest in becoming a scripter, but do use scripts and/or buy scripts or script services, and want to know more about scripting at the user level, also those demands will be served on the &#039;&#039;&#039;lslscripts.org&#039;&#039;&#039; website. Documentation will be provided on issues like: &lt;br /&gt;
* How much can be charged for a script/script service or hiring of a scripter?&lt;br /&gt;
* What licence model is applicable for the scripts I need for my project?&lt;br /&gt;
etc. &lt;br /&gt;
Linked to this website a script group in-world will be founded under the name: &#039;&#039;&#039;lslscripts.org&#039;&#039;&#039;. This group will be open for anyone to join.&lt;br /&gt;
==SUPPORT LSLSCRIPTS.ORG. DONATE YOUR SCRIPTS OR SCRIPT TUTORIALS==&lt;br /&gt;
Donations to &#039;&#039;&#039;lslscripts.org&#039;&#039;&#039; are welcome, both in the form of scripts, tutorials and some Linden$ for supporting the site and cover its costs are welcome. Want to become actively involved in developing  this website, or just want to communicate your ideas about it? Don&#039;t hesitate to contact the founder of &#039;&#039;&#039;lslscripts.org&#039;&#039;&#039; Flennan Roffo. All contributions, small or large, are welcome.&lt;br /&gt;
Those that are interested in providing some usefull information about scripting, for example in the form of Blog entries or tutorials or other usefull stuff that fits the purpose of this webservice, please contact me. Also if you can support &#039;&#039;&#039;lslscripts.org&#039;&#039;&#039; by placing an advertise free of charge for this webservice on your parcel which connects to the &#039;&#039;&#039;lslscripts.org&#039;&#039;&#039; webservice, do not hesitate to contact me.&lt;br /&gt;
&lt;br /&gt;
Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
Logic Scripted products and Script services&lt;br /&gt;
&lt;br /&gt;
[[Image:Lslscripts.org.jpg]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;DONATE YOUR SCRIPTS &amp;amp; SCRIPT TUTORIALS TO LSLSCRIPTS.ORG. BECOME INVOLVED.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{visl&lt;br /&gt;
|name=&lt;br /&gt;
|Scripter=*&lt;br /&gt;
|}}&lt;/div&gt;</description>
			<pubDate>Sat, 06 Oct 2007 00:23:03 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/User_talk:Flennan_Roffo</comments>
		</item>
		<item>
			<title>File:Slmailbox.jpg</title>
			<link>https://wiki.secondlife.com/w/index.php?title=File:Slmailbox.jpg&amp;diff=34428</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=File:Slmailbox.jpg&amp;diff=34428</guid>
			<description>&lt;p&gt;Flennan Roffo: SL Mailbox&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;SL Mailbox&lt;/div&gt;</description>
			<pubDate>Sat, 06 Oct 2007 00:22:14 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/File_talk:Slmailbox.jpg</comments>
		</item>
		<item>
			<title>User:Flennan Roffo</title>
			<link>https://wiki.secondlife.com/w/index.php?title=User:Flennan_Roffo&amp;diff=34421</link>
			<guid isPermaLink="false">https://wiki.secondlife.com/w/index.php?title=User:Flennan_Roffo&amp;diff=34421</guid>
			<description>&lt;p&gt;Flennan Roffo: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
=About Flennan Roffo=&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
||[[Image:FlennanRoffo80x80.jpg|frameless|100px|Flennan Roffo]]&lt;br /&gt;
||Second Life resident since 11 July 2007. Scripter and owner of Logic Scripted products and Script services. You can visit me at my office in Peacock Park (189, 226, 69):&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Logic Scripted products and Script services=&lt;br /&gt;
[[Image:Logicscripts.org.jpg]]&lt;br /&gt;
&lt;br /&gt;
==ABOUT LOGIC==&lt;br /&gt;
Logic Scripted Products and Script Services is, as you might have already guessed, all about LSL scripts and script services. My goal is to provide many good quality scripts for every business.&lt;br /&gt;
&lt;br /&gt;
==PRODUCTS==&lt;br /&gt;
&lt;br /&gt;
I am in the process of developing some very usefull products. Note though that each of these products are in early development phase and that new feautures will be released in upcoming releases. Currently I have released the following products:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Logic Mailbox Basic V 1.0&#039;&#039;&#039;&lt;br /&gt;
Basic model for a mailbox that allows anyone to drop you a notecard. Comes with a standard skin. For skin customization, contact Mad Maddy Studio.&lt;br /&gt;
See the demo at Logic office: &lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Logic Vendor V 1.0&#039;&#039;&#039;&lt;br /&gt;
Vendor that allows you to display many sellable items (objects) and per item you can give a customer a notecard. The sell price is split amongst multiple authors. Set up is easy, since you have to enter the key of each author only once, and can reference any author by nick.&lt;br /&gt;
&lt;br /&gt;
[[Image:Logicvendorv10.jpg|200px]]&lt;br /&gt;
&lt;br /&gt;
See the demo at Logic office:&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;SL Mail V 1.2&#039;&#039;&#039;&lt;br /&gt;
SecondLife mail client, released under GNU GPL licence. You can send and receive mail from within SecondLife both from and to other mail clients or external mail adresses. Has many command options and comes with an adjustable address book that allows to enter addresses and address groups.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Get your free copy today at logic office:&#039;&#039;&#039;&lt;br /&gt;
{{SLurl&lt;br /&gt;
|region=Peacock Park&lt;br /&gt;
|x=189&lt;br /&gt;
|y=226&lt;br /&gt;
|z=69&lt;br /&gt;
|title=Logic Scripted products and Script services&lt;br /&gt;
|}}&lt;br /&gt;
&lt;br /&gt;
Or, alternatively, get it from the Second Life wiki [[SL Mail V1.2|here]]&lt;br /&gt;
&lt;br /&gt;
[[Image:slmail.info.jpg]]&lt;br /&gt;
&lt;br /&gt;
==SERVICE CHARGING POLICY==&lt;br /&gt;
&lt;br /&gt;
The charging policy for script services depends on a number of factors:&lt;br /&gt;
* The usuability of the script. Simply stated, if the script does not provide what it is supposed to do no charge will be applied.&lt;br /&gt;
* The amount of work needed to create, adapt and test the script.&lt;br /&gt;
* The custumor. As a rule, the richer the customer, the higher the price, and the more the script or service I provide enhances business profits, the more is charged.&lt;br /&gt;
* The pricing will be based on the length of the service timeperiod.&lt;br /&gt;
* Prices are within reason.&lt;br /&gt;
* Part or whole price can be refunded if you have a well grounded complaint (script not behaving as specified or a large delay in delivering the scripts).&lt;br /&gt;
* Payment in advance for small projects are not necessary. For larger projects in which significant amount of time is invested advanced payment is asked for in the order of 10%-50% of the agreed price.&lt;br /&gt;
&lt;br /&gt;
==TERMS OF USE==&lt;br /&gt;
&lt;br /&gt;
The scripts I make available public will come with a Terms of Use or Fair Use policy.&lt;br /&gt;
&lt;br /&gt;
These terms of use include:&lt;br /&gt;
&lt;br /&gt;
* No selling or charging for free scripts&lt;br /&gt;
&lt;br /&gt;
Any script you purchase at Logic and/or is provided by Logic (either as a seperate script or as part of a Logic Scripted Product) MAY NOT BE RESOLD OR CHARGED FOR.&lt;br /&gt;
&lt;br /&gt;
If I find someone either selling Logic scripts or making a no-mod version of it, I will contact you about breaking this rule, and if necessary there will be made a public notice of this and take other measures if necessary.&lt;br /&gt;
&lt;br /&gt;
* No breaking of SL TOS&lt;br /&gt;
&lt;br /&gt;
You may not use any script or product (wether a Logic script or product or not) that breaks the Second Life Terms of Service (TOS). You can find the SL TOS on the official Second Life website:  http://www.secondlife.com&lt;br /&gt;
&lt;br /&gt;
* Donate for free scripts/services&lt;br /&gt;
&lt;br /&gt;
If you found my scripts and/or other services quite usefull and got them free of charge, you might consider giving a donation. A donation box will be installed any time soon.&lt;br /&gt;
&lt;br /&gt;
==HIRING==&lt;br /&gt;
&lt;br /&gt;
Logic can be hired for diverse projects. This includes besised LSL scripts and also website interfaces (PHP/MySQL) that interface with a scripted product in Second Life. Examples: visitor statistics, detectors, security devices, vendors, rental boxes, and so on. &lt;br /&gt;
&lt;br /&gt;
==LOGIC &amp;amp; STUDIO MAD MADDY==&lt;br /&gt;
&lt;br /&gt;
Logic Scripted Products and Script Services cooperates with Mad Maddy Studio. Mad Maddy Studio is specialised in custom made Textures, Business Logo&#039;s and so on. &lt;br /&gt;
&lt;br /&gt;
For more information about Mad Maddy Studio, and for all your graphical design requests, contact: [[User:Madeliefste Oh|Madeliefste Oh]].&lt;br /&gt;
&lt;br /&gt;
[[Image:MMbanner1.jpg]]&lt;br /&gt;
&lt;br /&gt;
=LSL Scripts &amp;amp; Tutorials=&lt;br /&gt;
Logic Scripted products and Script services is serving the broad public domain also by providing a good resource for scripts and script tutorials. This webservice is starting somewhere in october or november 2007.&lt;br /&gt;
The plan is to both collect &amp;amp; document existing scripts that reside in the inventory of residents or circulate in script groups and also create some new scripts ourselves that serve the interest of the public domain at large, and which will complement existing LSL wiki&#039;s, website and script resources/tutorials around the world wide web.&lt;br /&gt;
The website will provide usefull resources for both scripters and non-scripters (script users) and will accomodate both the interests of those that are new to scripting as well as die-hard LSL scripters.&lt;br /&gt;
==SCRIPT &amp;amp; SCRIPT TUTORIAL LIBRARY==&lt;br /&gt;
Both scripts and script tutorials will be placed in a repository/database which facilitates easy access and good searching options and is open for contributions by anyone. To maintain a good quality level some form of moderation will be put in place. User feedback to the site will be encouraged strongly, as  also the sharing of script knowledge, tips &amp;amp; tricks, etc. Other planned part of the website will be a page to make requests for scripts, either for scripts that do not yet exist in the public domain, or for feature requests on existing scripts. Be aware though that this service is not meant to be a place for hiring scripters or to buy a script, and is not intended to replace companies that provide those services for fees, but only is meant to serve the interests of the public in improving high quality scripts that are available as open source.&lt;br /&gt;
==SCRIPT USERS==&lt;br /&gt;
For those that do not do scripting themselves, and have no interest in becoming a scripter, but do use scripts and/or buy scripts or script services, and want to know more about scripting at the user level, also those demands will be served on the &#039;&#039;&#039;lslscripts.org&#039;&#039;&#039; website. Documentation will be provided on issues like: &lt;br /&gt;
* How much can be charged for a script/script service or hiring of a scripter?&lt;br /&gt;
* What licence model is applicable for the scripts I need for my project?&lt;br /&gt;
etc. &lt;br /&gt;
Linked to this website a script group in-world will be founded under the name: &#039;&#039;&#039;lslscripts.org&#039;&#039;&#039;. This group will be open for anyone to join.&lt;br /&gt;
==SUPPORT LSLSCRIPTS.ORG. DONATE YOUR SCRIPTS OR SCRIPT TUTORIALS==&lt;br /&gt;
Donations to &#039;&#039;&#039;lslscripts.org&#039;&#039;&#039; are welcome, both in the form of scripts, tutorials and some Linden$ for supporting the site and cover its costs are welcome. Want to become actively involved in developing  this website, or just want to communicate your ideas about it? Don&#039;t hesitate to contact the founder of &#039;&#039;&#039;lslscripts.org&#039;&#039;&#039; Flennan Roffo. All contributions, small or large, are welcome.&lt;br /&gt;
Those that are interested in providing some usefull information about scripting, for example in the form of Blog entries or tutorials or other usefull stuff that fits the purpose of this webservice, please contact me. Also if you can support &#039;&#039;&#039;lslscripts.org&#039;&#039;&#039; by placing an advertise free of charge for this webservice on your parcel which connects to the &#039;&#039;&#039;lslscripts.org&#039;&#039;&#039; webservice, do not hesitate to contact me.&lt;br /&gt;
&lt;br /&gt;
Flennan Roffo&lt;br /&gt;
&lt;br /&gt;
Logic Scripted products and Script services&lt;br /&gt;
&lt;br /&gt;
[[Image:Lslscripts.org.jpg]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;DONATE YOUR SCRIPTS &amp;amp; SCRIPT TUTORIALS TO LSLSCRIPTS.ORG. BECOME INVOLVED.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{visl&lt;br /&gt;
|name=&lt;br /&gt;
|Scripter=*&lt;br /&gt;
|}}&lt;/div&gt;</description>
			<pubDate>Fri, 05 Oct 2007 22:13:37 GMT</pubDate>
			<dc:creator>Flennan Roffo</dc:creator>
			<comments>https://wiki.secondlife.com/wiki/User_talk:Flennan_Roffo</comments>
		</item>
</channel></rss>