diff --git a/indra/lib/python/indra/base/metrics.py b/indra/lib/python/indra/base/metrics.py
index 751757d5b0551e3b3e384e3d043409229c04b6e9..d26f571be7d67c538bc5280569da7b3885137042 100644
--- a/indra/lib/python/indra/base/metrics.py
+++ b/indra/lib/python/indra/base/metrics.py
@@ -31,12 +31,23 @@
 import sys
 from indra.base import llsd
 
-def log(location, stats, file=None):
-    "Write a standard llmetrics log"
-    metrics = {'location':location, 'stats':stats}
-    if file is None:
+_sequence_id = 0
+
+def record_metrics(table, stats, dest=None):
+    "Write a standard metrics log"
+    _log("LLMETRICS", table, stats, dest)
+
+def record_event(table, data, dest=None):
+    "Write a standard logmessage log"
+    _log("LLLOGMESSAGE", table, data, dest)
+
+def _log(header, table, data, dest):
+    if dest is None:
         # do this check here in case sys.stdout changes at some
         # point. as a default parameter, it will never be
         # re-evaluated.
-        file = sys.stdout
-    print >>file, "LLMETRICS:", llsd.format_notation(metrics)
+        dest = sys.stdout
+    global _sequence_id
+    print >>dest, header, "(" + str(_sequence_id) + ")",
+    print >>dest, table, llsd.format_notation(data)
+    _sequence_id += 1
diff --git a/indra/lib/python/indra/util/llsubprocess.py b/indra/lib/python/indra/util/llsubprocess.py
new file mode 100644
index 0000000000000000000000000000000000000000..b6082de74a47b7a75d77cd225bf60795c0627a00
--- /dev/null
+++ b/indra/lib/python/indra/util/llsubprocess.py
@@ -0,0 +1,106 @@
+"""\
+@file llsubprocess.py
+@author Phoenix
+@date 2008-01-18
+@brief The simplest possible wrapper for a common sub-process paradigm.
+
+$LicenseInfo:firstyear=2007&license=mit$
+
+Copyright (c) 2007, Linden Research, Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+$/LicenseInfo$
+"""
+
+import os
+import popen2
+import time
+import select
+
+class Timeout(RuntimeError):
+    "Exception raised when a subprocess times out."
+    pass
+
+def run(command, args=None, data=None, timeout=None):
+    """\
+@brief Run command with arguments
+
+This is it. This is the function I want to run all the time when doing
+subprocces, but end up copying the code everywhere. none of the
+standard commands are secure and provide a way to specify input, get
+all the output, and get the result.
+@param command A string specifying a process to launch.
+@param args Arguments to be passed to command. Must be list, tuple or None.
+@param data input to feed to the command.
+@param timeout Maximum number of many seconds to run.
+@return Returns (result, stdout, stderr) from process.
+"""
+    cmd = [command]
+    if args:
+        cmd.extend([str(arg) for arg in args])
+    #print  "cmd: ","' '".join(cmd)
+    child = popen2.Popen3(cmd, True)
+    #print child.pid
+    out = []
+    err = []
+    result = -1
+    time_left = timeout
+    tochild = [child.tochild.fileno()]
+    while True:
+        time_start = time.time()
+        #print "time:",time_left
+        p_in, p_out, p_err = select.select(
+            [child.fromchild.fileno(), child.childerr.fileno()],
+            tochild,
+            [],
+            time_left)
+        if p_in:
+            new_line = os.read(child.fromchild.fileno(), 32 * 1024)
+            if new_line:
+                #print "line:",new_line
+                out.append(new_line)
+            new_line = os.read(child.childerr.fileno(), 32 * 1024)
+            if new_line:
+                #print "error:", new_line
+                err.append(new_line)
+        if p_out:
+            if data:
+                #print "p_out"
+                bytes = os.write(child.tochild.fileno(), data)
+                data = data[bytes:]
+                if len(data) == 0:
+                    data = None
+                    tochild = []
+                    child.tochild.close()
+        result = child.poll()
+        if result != -1:
+            child.tochild.close()
+            child.fromchild.close()
+            child.childerr.close()
+            break
+        if time_left is not None:
+            time_left -= (time.time() - time_start)
+            if time_left < 0:
+                raise Timeout
+    #print "result:",result
+    out = ''.join(out)
+    #print "stdout:", out
+    err = ''.join(err)
+    #print "stderr:", err
+    return result, out, err
diff --git a/indra/llmessage/llhost.cpp b/indra/llmessage/llhost.cpp
index b73becfa71767331794ce5398eb90b067c16884f..4d10f060515ee0da5f7ed52958e1db4f5fb87e1c 100644
--- a/indra/llmessage/llhost.cpp
+++ b/indra/llmessage/llhost.cpp
@@ -132,14 +132,13 @@ void LLHost::getHostName(char *buf, S32 len) const
 	}
 }
 
-LLString LLHost::getHostName() const
+std::string LLHost::getHostName() const
 {
-	hostent *he;
-
+	hostent* he;
 	if (INVALID_HOST_IP_ADDRESS == mIP)
 	{
 		llwarns << "LLHost::getHostName() : Invalid IP address" << llendl;
-		return "";
+		return std::string();
 	}
 	he = gethostbyaddr((char *)&mIP, sizeof(mIP), AF_INET);
 	if (!he)
@@ -151,12 +150,11 @@ LLString LLHost::getHostName() const
 		llwarns << "LLHost::getHostName() : Couldn't find host name for address " << mIP << ", Error: " 
 			<< h_errno << llendl;
 #endif
-		return "";
+		return std::string();
 	}
 	else
 	{
-		LLString hostname = he->h_name;
-		return hostname;
+		return ll_safe_string(he->h_name);
 	}
 }
 
diff --git a/indra/llmessage/llhost.h b/indra/llmessage/llhost.h
index e6f811ac087db9c4005d46679aacb51bdb29d690..a865ad616c45ed32aa3ec7fc89c5223dea6272d2 100644
--- a/indra/llmessage/llhost.h
+++ b/indra/llmessage/llhost.h
@@ -38,8 +38,6 @@
 
 #include "net.h"
 
-#include "llstring.h"
-
 const U32 INVALID_PORT = 0;
 const U32 INVALID_HOST_IP_ADDRESS = 0x0;
 
@@ -102,7 +100,7 @@ class LLHost {
 	void	getIPString(char* buffer, S32 length) const;	// writes IP into buffer
 	std::string getIPString() const;
 	void    getHostName(char *buf, S32 len) const;
-	LLString getHostName() const;
+	std::string getHostName() const;
 	std::string getIPandPort() const;
 
 	friend std::ostream& operator<< (std::ostream& os, const LLHost &hh);
diff --git a/indra/newview/llfloaterpostcard.cpp b/indra/newview/llfloaterpostcard.cpp
index 5306ce11b197c1c7bf1337a49b5faf6d51dd752e..1f5ebec6847c6b00ca15539a3b3a555c4272c33b 100644
--- a/indra/newview/llfloaterpostcard.cpp
+++ b/indra/newview/llfloaterpostcard.cpp
@@ -113,25 +113,12 @@ BOOL LLFloaterPostcard::postBuild()
 	childSetAction("send_btn", onClickSend, this);
 
 	childDisable("from_form");
-	childSetAction("publish_help_btn", onClickPublishHelp, this);
 
-	if (gAgent.isTeen())
-	{
-		// Disable these buttons if they are PG (Teen) users
-		childDisable("allow_publish_check");
-		childHide("allow_publish_check");
-		childDisable("publish_help_btn");
-		childHide("publish_help_btn");
-		childDisable("mature_check");
-		childHide("mature_check");
-	}
-	
-	LLString name_string;
+	std::string name_string;
 	gAgent.buildFullname(name_string);
-	
 	childSetValue("name_form", LLSD(name_string));
 
-	LLTextEditor *MsgField = LLUICtrlFactory::getTextEditorByName(this, "msg_form");
+	LLTextEditor* MsgField = LLUICtrlFactory::getTextEditorByName(this, "msg_form");
 	if (MsgField)
 	{
 		MsgField->setWordWrap(TRUE);
@@ -252,8 +239,8 @@ void LLFloaterPostcard::onClickSend(void* data)
 	{
 		LLFloaterPostcard *self = (LLFloaterPostcard *)data;
 
-		LLString from(self->childGetValue("from_form").asString().c_str());
-		LLString to(self->childGetValue("to_form").asString().c_str());
+		std::string from(self->childGetValue("from_form").asString());
+		std::string to(self->childGetValue("to_form").asString());
 
 		if (to.empty() || to.find('@') == std::string::npos)
 		{
@@ -267,7 +254,7 @@ void LLFloaterPostcard::onClickSend(void* data)
 			return;
 		}
 
-		LLString subject(self->childGetValue("subject_form").asString().c_str());
+		std::string subject(self->childGetValue("subject_form").asString());
 		if(subject.empty() || !self->mHasFirstMsgFocus)
 		{
 			gViewerWindow->alertXml("PromptMissingSubjMsg", missingSubjMsgAlertCallback, self);
@@ -285,12 +272,6 @@ void LLFloaterPostcard::onClickSend(void* data)
 	}
 }
 
-// static
-void LLFloaterPostcard::onClickPublishHelp(void* data)
-{
-	gViewerWindow->alertXml("ClickPublishHelpPostcard");
-}
-
 // static
 void LLFloaterPostcard::uploadCallback(const LLUUID& asset_id, void *user_data, S32 result, LLExtStat ext_status) // StoreAssetData callback (fixed)
 {
@@ -321,8 +302,8 @@ void LLFloaterPostcard::uploadCallback(const LLUUID& asset_id, void *user_data,
 		msg->addString("Name", self->childGetValue("name_form").asString());
 		msg->addString("Subject", self->childGetValue("subject_form").asString());
 		msg->addString("Msg", self->childGetValue("msg_form").asString());
-		msg->addBOOL("AllowPublish", self->childGetValue("allow_publish_check").asBoolean());
-		msg->addBOOL("MaturePublish", self->childGetValue("mature_check").asBoolean());
+		msg->addBOOL("AllowPublish", FALSE);
+		msg->addBOOL("MaturePublish", FALSE);
 		gAgent.sendReliableMessage();
 	}
 
@@ -405,8 +386,6 @@ void LLFloaterPostcard::sendPostcard()
 		body["name"] = childGetValue("name_form").asString();
 		body["subject"] = childGetValue("subject_form").asString();
 		body["msg"] = childGetValue("msg_form").asString();
-		body["allow-publish"] = childGetValue("allow_publish_check").asBoolean();
-		body["mature-publish"] = childGetValue("mature_check").asBoolean();
 		LLHTTPClient::post(url, body, new LLSendPostcardResponder(body, mAssetID, LLAssetType::AT_IMAGE_JPEG));
 	} 
 	else
diff --git a/indra/newview/llfloaterpostcard.h b/indra/newview/llfloaterpostcard.h
index 287d34c7061f4dcd4d232ac3af7bbfde3883603c..5e0efa0ccb1b642e410ae21e605d2affe8bffc59 100644
--- a/indra/newview/llfloaterpostcard.h
+++ b/indra/newview/llfloaterpostcard.h
@@ -57,7 +57,6 @@ class LLFloaterPostcard
 
 	static void onClickCancel(void* data);
 	static void onClickSend(void* data);
-	static void onClickPublishHelp(void *data);
 
 	static void uploadCallback(const LLUUID& asset_id,
 							   void *user_data,