Example #1
0
	void configure(const LLSD& config)
	{
		Globals& g = Globals::get();
		Settings& s = Settings::get();
		
		g.invalidateCallSites();
		s.functionLevelMap.clear();
		s.classLevelMap.clear();
		s.fileLevelMap.clear();
		
		setPrintLocation(config["print-location"]);
		setDefaultLevel(decodeLevel(config["default-level"]));
		
		LLSD sets = config["settings"];
		LLSD::array_const_iterator a, end;
		for (a = sets.beginArray(), end = sets.endArray(); a != end; ++a)
		{
			const LLSD& entry = *a;
			
			ELevel level = decodeLevel(entry["level"]);
			
			setLevels(s.functionLevelMap,	entry["functions"],	level);
			setLevels(s.classLevelMap,		entry["classes"],	level);
			setLevels(s.fileLevelMap,		entry["files"],		level);
		}
	}
Example #2
0
// static
bool LLGiveInventory::handleCopyProtectedItem(const LLSD& notification, const LLSD& response)
{
	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
	LLSD itmes = notification["payload"]["items"];
	LLInventoryItem* item = NULL;
	switch(option)
	{
	case 0:  // "Yes"
		for (LLSD::array_iterator it = itmes.beginArray(); it != itmes.endArray(); it++)
		{
			item = gInventory.getItem((*it).asUUID());
			if (item)
			{
				LLGiveInventory::commitGiveInventoryItem(notification["payload"]["agent_id"].asUUID(),
					item);
				// delete it for now - it will be deleted on the server
				// quickly enough.
				gInventory.deleteObject(item->getUUID());
				gInventory.notifyObservers();
			}
			else
			{
				LLNotificationsUtil::add("CannotGiveItem");
			}
		}
		break;

	default: // no, cancel, whatever, who cares, not yes.
		LLNotificationsUtil::add("TransactionCancelled");
		break;
	}
	return false;
}
bool LLNotificationsListener::Forwarder::matchType(const LLSD& filter, const std::string& type) const
{
    // Decide whether this notification matches filter:
    // undefined: forward all notifications
    if (filter.isUndefined())
    {
        return true;
    }
    // array of string: forward any notification matching any named type
    if (filter.isArray())
    {
        for (LLSD::array_const_iterator ti(filter.beginArray()), tend(filter.endArray());
             ti != tend; ++ti)
        {
            if (ti->asString() == type)
            {
                return true;
            }
        }
        // Didn't match any entry in the array
        return false;
    }
    // string: forward only the specific named type
    return (filter.asString() == type);
}
Example #4
0
void LLNotificationForm::append(const LLSD& sub_form)
{
	if (sub_form.isArray())
	{
		for (LLSD::array_const_iterator it = sub_form.beginArray();
			it != sub_form.endArray();
			++it)
		{
			mFormData.append(*it);
		}
	}
}
void LLFloaterAvatarPicker::processResponse(const LLUUID& query_id, const LLSD& content)
{
	// Check for out-of-date query
	if (query_id != mQueryID) return;

	LLScrollListCtrl* search_results = getChild<LLScrollListCtrl>("SearchResults");

	LLSD agents = content["agents"];
	if (agents.size() == 0)
	{
		LLStringUtil::format_map_t map;
		map["[TEXT]"] = childGetText("Edit");
		LLSD item;
		item["id"] = LLUUID::null;
		item["columns"][0]["column"] = "name";
		item["columns"][0]["value"] = getString("not_found", map);
		search_results->addElement(item);
		search_results->setEnabled(false);
		getChildView("Select")->setEnabled(false);
		return;
	}

	// clear "Searching" label on first results
	search_results->deleteAllItems();

	LLSD item;
	LLSD::array_const_iterator it = agents.beginArray();
	for ( ; it != agents.endArray(); ++it)
	{
		const LLSD& row = *it;
		item["id"] = row["id"];
		LLSD& columns = item["columns"];
		columns[0]["column"] = "name";
		columns[0]["value"] = row["display_name"];
		columns[1]["column"] = "username";
		columns[1]["value"] = row["username"];
		search_results->addElement(item);

		// add the avatar name to our list
		LLAvatarName avatar_name;
		avatar_name.fromLLSD(row);
		sAvatarNameMap[row["id"].asUUID()] = avatar_name;
	}

	getChildView("Select")->setEnabled(true);
	search_results->setEnabled(true);
	search_results->selectFirstItem();
	onList();
	search_results->setFocus(TRUE);
}
Example #6
0
// static
LLURI LLURI::buildHTTP(const std::string& prefix,
					   const LLSD& path)
{
	LLURI result;
	
	// TODO: deal with '/' '?' '#' in host_port
	if (prefix.find("://") != prefix.npos)
	{
		// it is a prefix
		result = LLURI(prefix);
	}
	else
	{
		// it is just a host and optional port
		result.mScheme = "http";
		result.mEscapedAuthority = escapeHostAndPort(prefix);
	}

	if (path.isArray())
	{
		// break out and escape each path component
		for (LLSD::array_const_iterator it = path.beginArray();
			 it != path.endArray();
			 ++it)
		{
			lldebugs << "PATH: inserting " << it->asString() << llendl;
			result.mEscapedPath += "/" + escapePathComponent(it->asString());
		}
	}
	else if(path.isString())
	{
		result.mEscapedPath += "/" + escapePathComponent(path.asString());
	} 
	else if(path.isUndefined())
	{
	  // do nothing
	}
    else
	{
	  llwarns << "Valid path arguments to buildHTTP are array, string, or undef, you passed type" 
			  << path.type() << llendl;
	}
	result.mEscapedOpaque = "//" + result.mEscapedAuthority +
		result.mEscapedPath;
	return result;
}
Example #7
0
void HippoGridManager::parseData(LLSD &gridInfo, bool mergeIfNewer)
{
	LLSD::array_const_iterator it, end = gridInfo.endArray();
	for (it = gridInfo.beginArray(); it != end; ++it) {
		LLSD gridMap = *it;
		if (gridMap.has("gridnick") && gridMap.has("loginuri")) {
			std::string gridnick = gridMap["gridnick"];
			HippoGridInfo *grid;
			GridIterator it = mGridInfo.find(gridnick);
			bool newGrid = (it == mGridInfo.end());
			if (gridMap.has("version")) {
				int version = gridMap["version"];
				if (version == -1) {
					// delete grid
					if (!newGrid) mGridInfo.erase(it);
					continue;
				} else if (mergeIfNewer && !newGrid && (version <= it->second->getVersion())) {
					// don't update if version is not newer
					continue;
				}
			}
			if (newGrid) {
				// create new grid info
				grid = new HippoGridInfo(gridnick);
			} else {
				// update existing grid info
				grid = it->second;
			}
			grid->setLoginUri(gridMap["loginuri"]);
			if (gridMap.has("platform")) grid->setPlatform(gridMap["platform"]);
			if (gridMap.has("gridname")) grid->setGridName(gridMap["gridname"]);
			if (gridMap.has("lastlogin_fname")) grid->setLastFName(gridMap["lastlogin_fname"]);
			if (gridMap.has("lastlogin_lname")) grid->setLastLName(gridMap["lastlogin_lname"]);
			if (gridMap.has("loginpage")) grid->setLoginPage(gridMap["loginpage"]);
			if (gridMap.has("helperuri")) grid->setHelperUri(gridMap["helperuri"]);
			if (gridMap.has("website")) grid->setWebSite(gridMap["website"]);
			if (gridMap.has("support")) grid->setSupportUrl(gridMap["support"]);
			if (gridMap.has("register")) grid->setRegisterUrl(gridMap["register"]);
			if (gridMap.has("password")) grid->setPasswordUrl(gridMap["password"]);
			//if (gridMap.has("search")) grid->setSearchUrl(gridMap["search"]);
			if (gridMap.has("render_compat")) grid->setRenderCompat(gridMap["render_compat"]);
			if (gridMap.has("version")) grid->setVersion(gridMap["version"]);
			if (newGrid) addGrid(grid);
		}
	}
}
void LLLogin::Impl::login_(LLCoros::self& self, std::string uri, LLSD login_params)
{
	try
	{
	LLSD printable_params = login_params;
	//if(printable_params.has("params") 
	//	&& printable_params["params"].has("passwd")) 
	//{
	//	printable_params["params"]["passwd"] = "*******";
	//}
    LL_DEBUGS("LLLogin") << "Entering coroutine " << LLCoros::instance().getName(self)
                        << " with uri '" << uri << "', parameters " << printable_params << LL_ENDL;

	// Arriving in SRVRequest state
    LLEventStream replyPump("SRVreply", true);
    // Should be an array of one or more uri strings.

    LLSD rewrittenURIs;
    {
        LLEventTimeout filter(replyPump);
        sendProgressEvent("offline", "srvrequest");

        // Request SRV record.
        LL_DEBUGS("LLLogin") << "Requesting SRV record from " << uri << LL_ENDL;

        // *NOTE:Mani - Completely arbitrary default timeout value for SRV request.
		F32 seconds_to_timeout = 5.0f;
		if(login_params.has("cfg_srv_timeout"))
		{
			seconds_to_timeout = login_params["cfg_srv_timeout"].asReal();
		}

        // If the SRV request times out (e.g. EXT-3934), simulate response: an
        // array containing our original URI.
        LLSD fakeResponse(LLSD::emptyArray());
        fakeResponse.append(uri);
		filter.eventAfter(seconds_to_timeout, fakeResponse);

		std::string srv_pump_name = "LLAres";
		if(login_params.has("cfg_srv_pump"))
		{
			srv_pump_name = login_params["cfg_srv_pump"].asString();
		}

		// Make request
        LLSD request;
        request["op"] = "rewriteURI";
        request["uri"] = uri;
        request["reply"] = replyPump.getName();
        rewrittenURIs = postAndWait(self, request, srv_pump_name, filter);
    } // we no longer need the filter

    LLEventPump& xmlrpcPump(LLEventPumps::instance().obtain("LLXMLRPCTransaction"));
    // EXT-4193: use a DIFFERENT reply pump than for the SRV request. We used
    // to share them -- but the EXT-3934 fix made it possible for an abandoned
    // SRV response to arrive just as we were expecting the XMLRPC response.
    LLEventStream loginReplyPump("loginreply", true);

    // Loop through the rewrittenURIs, counting attempts along the way.
    // Because of possible redirect responses, we may make more than one
    // attempt per rewrittenURIs entry.
    LLSD::Integer attempts = 0;
    for (LLSD::array_const_iterator urit(rewrittenURIs.beginArray()),
             urend(rewrittenURIs.endArray());
         urit != urend; ++urit)
    {
        LLSD request(login_params);
        request["reply"] = loginReplyPump.getName();
        request["uri"] = *urit;
        std::string status;

        // Loop back to here if login attempt redirects to a different
        // request["uri"]
        for (;;)
        {
            ++attempts;
            LLSD progress_data;
            progress_data["attempt"] = attempts;
            progress_data["request"] = request;
			if(progress_data["request"].has("params")
				&& progress_data["request"]["params"].has("passwd"))
			{
				progress_data["request"]["params"]["passwd"] = "*******";
			}
            sendProgressEvent("offline", "authenticating", progress_data);

            // We expect zero or more "Downloading" status events, followed by
            // exactly one event with some other status. Use postAndWait() the
            // first time, because -- at least in unit-test land -- it's
            // possible for the reply to arrive before the post() call
            // returns. Subsequent responses, of course, must be awaited
            // without posting again.
            for (mAuthResponse = validateResponse(loginReplyPump.getName(),
                                 postAndWait(self, request, xmlrpcPump, loginReplyPump, "reply"));
                 mAuthResponse["status"].asString() == "Downloading";
                 mAuthResponse = validateResponse(loginReplyPump.getName(),
                                     waitForEventOn(self, loginReplyPump)))
            {
                // Still Downloading -- send progress update.
                sendProgressEvent("offline", "downloading");
            }
				 
			LL_DEBUGS("LLLogin") << "Auth Response: " << mAuthResponse << LL_ENDL;
            status = mAuthResponse["status"].asString();

            // Okay, we've received our final status event for this
            // request. Unless we got a redirect response, break the retry
            // loop for the current rewrittenURIs entry.
            if (!(status == "Complete" &&
                  mAuthResponse["responses"]["login"].asString() == "indeterminate"))
            {
                break;
            }

			sendProgressEvent("offline", "indeterminate", mAuthResponse["responses"]);

            // Here the login service at the current URI is redirecting us
            // to some other URI ("indeterminate" -- why not "redirect"?).
            // The response should contain another uri to try, with its
            // own auth method.
            request["uri"] = mAuthResponse["responses"]["next_url"].asString();
            request["method"] = mAuthResponse["responses"]["next_method"].asString();
        } // loop back to try the redirected URI

        // Here we're done with redirects for the current rewrittenURIs
        // entry.
        if (status == "Complete")
        {
            // StatusComplete does not imply auth success. Check the
            // actual outcome of the request. We've already handled the
            // "indeterminate" case in the loop above.
            if (mAuthResponse["responses"]["login"].asString() == "true")
            {
                sendProgressEvent("online", "connect", mAuthResponse["responses"]);
            }
            else
            {
                sendProgressEvent("offline", "fail.login", mAuthResponse["responses"]);
            }
            return;             // Done!
        }
        // If we don't recognize status at all, trouble
        if (! (status == "CURLError"
               || status == "XMLRPCError"
               || status == "OtherError"))
        {
            LL_ERRS("LLLogin") << "Unexpected status from " << xmlrpcPump.getName() << " pump: "
                               << mAuthResponse << LL_ENDL;
            return;
        }

        // Here status IS one of the errors tested above.
    } // Retry if there are any more rewrittenURIs.

    // Here we got through all the rewrittenURIs without succeeding. Tell
    // caller this didn't work out so well. Of course, the only failure data
    // we can reasonably show are from the last of the rewrittenURIs.

	// *NOTE: The response from LLXMLRPCListener's Poller::poll method returns an
	// llsd with no "responses" node. To make the output from an incomplete login symmetrical 
	// to success, add a data/message and data/reason fields.
	LLSD error_response;
	error_response["reason"] = mAuthResponse["status"];
	error_response["errorcode"] = mAuthResponse["errorcode"];
	error_response["message"] = mAuthResponse["error"];
	if(mAuthResponse.has("certificate"))
	{
		error_response["certificate"] = mAuthResponse["certificate"];
	}
	sendProgressEvent("offline", "fail.login", error_response);
	}
	catch (...) {
		llerrs << "login exception caught" << llendl; 
	}
}
Example #9
0
void LLFilterSD2XMLRPC::streamOut(std::ostream& ostr, const LLSD& sd)
{
    ostr << "<value>";
    switch(sd.type())
    {
    case LLSD::TypeMap:
    {
#if LL_SPEW_STREAM_OUT_DEBUGGING
        llinfos << "streamOut(map) BEGIN" << llendl;
#endif
        ostr << "<struct>";
        if(ostr.fail())
        {
            llinfos << "STREAM FAILURE writing struct" << llendl;
        }
        LLSD::map_const_iterator it = sd.beginMap();
        LLSD::map_const_iterator end = sd.endMap();
        for(; it != end; ++it)
        {
            ostr << "<member><name>" << xml_escape_string((*it).first)
                 << "</name>";
            streamOut(ostr, (*it).second);
            if(ostr.fail())
            {
                llinfos << "STREAM FAILURE writing '" << (*it).first
                        << "' with sd type " << (*it).second.type() << llendl;
            }
            ostr << "</member>";
        }
        ostr << "</struct>";
#if LL_SPEW_STREAM_OUT_DEBUGGING
        llinfos << "streamOut(map) END" << llendl;
#endif
        break;
    }
    case LLSD::TypeArray:
    {
#if LL_SPEW_STREAM_OUT_DEBUGGING
        llinfos << "streamOut(array) BEGIN" << llendl;
#endif
        ostr << "<array><data>";
        LLSD::array_const_iterator it = sd.beginArray();
        LLSD::array_const_iterator end = sd.endArray();
        for(; it != end; ++it)
        {
            streamOut(ostr, *it);
            if(ostr.fail())
            {
                llinfos << "STREAM FAILURE writing array element sd type "
                        << (*it).type() << llendl;
            }
        }
#if LL_SPEW_STREAM_OUT_DEBUGGING
        llinfos << "streamOut(array) END" << llendl;
#endif
        ostr << "</data></array>";
        break;
    }
    case LLSD::TypeUndefined:
    // treat undefined as a bool with a false value.
    case LLSD::TypeBoolean:
#if LL_SPEW_STREAM_OUT_DEBUGGING
        llinfos << "streamOut(bool)" << llendl;
#endif
        ostr << "<boolean>" << (sd.asBoolean() ? "1" : "0") << "</boolean>";
        break;
    case LLSD::TypeInteger:
#if LL_SPEW_STREAM_OUT_DEBUGGING
        llinfos << "streamOut(int)" << llendl;
#endif
        ostr << "<i4>" << sd.asInteger() << "</i4>";
        break;
    case LLSD::TypeReal:
#if LL_SPEW_STREAM_OUT_DEBUGGING
        llinfos << "streamOut(real)" << llendl;
#endif
        ostr << "<double>" << sd.asReal() << "</double>";
        break;
    case LLSD::TypeString:
#if LL_SPEW_STREAM_OUT_DEBUGGING
        llinfos << "streamOut(string)" << llendl;
#endif
        ostr << "<string>" << xml_escape_string(sd.asString()) << "</string>";
        break;
    case LLSD::TypeUUID:
#if LL_SPEW_STREAM_OUT_DEBUGGING
        llinfos << "streamOut(uuid)" << llendl;
#endif
        // serialize it as a string
        ostr << "<string>" << sd.asString() << "</string>";
        break;
    case LLSD::TypeURI:
    {
#if LL_SPEW_STREAM_OUT_DEBUGGING
        llinfos << "streamOut(uri)" << llendl;
#endif
        // serialize it as a string
        ostr << "<string>" << xml_escape_string(sd.asString()) << "</string>";
        break;
    }
    case LLSD::TypeBinary:
    {
#if LL_SPEW_STREAM_OUT_DEBUGGING
        llinfos << "streamOut(binary)" << llendl;
#endif
        // this is pretty inefficient, but we'll deal with that
        // problem when it becomes one.
        ostr << "<base64>";
        LLSD::Binary buffer = sd.asBinary();
        if(!buffer.empty())
        {
            // *TODO: convert to LLBase64
            int b64_buffer_length = apr_base64_encode_len(buffer.size());
            char* b64_buffer = new char[b64_buffer_length];
            b64_buffer_length = apr_base64_encode_binary(
                                    b64_buffer,
                                    &buffer[0],
                                    buffer.size());
            ostr.write(b64_buffer, b64_buffer_length - 1);
            delete[] b64_buffer;
        }
        ostr << "</base64>";
        break;
    }
    case LLSD::TypeDate:
#if LL_SPEW_STREAM_OUT_DEBUGGING
        llinfos << "streamOut(date)" << llendl;
#endif
        // no need to escape this since it will be alpha-numeric.
        ostr << "<dateTime.iso8601>" << sd.asString() << "</dateTime.iso8601>";
        break;
    default:
        // unhandled type
        llwarns << "Unhandled structured data type: " << sd.type()
                << llendl;
        break;
    }
    ostr << "</value>";
}
S32 LLSDXMLFormatter::format_impl(const LLSD& data, std::ostream& ostr, U32 options, U32 level) const
{
	S32 format_count = 1;
	std::string pre;
	std::string post;

	if (options & LLSDFormatter::OPTIONS_PRETTY)
	{
		for (U32 i = 0; i < level; i++)
		{
			pre += "    ";
		}
		post = "\n";
	}

	switch(data.type())
	{
	case LLSD::TypeMap:
		if(0 == data.size())
		{
			ostr << pre << "<map />" << post;
		}
		else
		{
			ostr << pre << "<map>" << post;
			LLSD::map_const_iterator iter = data.beginMap();
			LLSD::map_const_iterator end = data.endMap();
			for(; iter != end; ++iter)
			{
				ostr << pre << "<key>" << escapeString((*iter).first) << "</key>" << post;
				format_count += format_impl((*iter).second, ostr, options, level + 1);
			}
			ostr << pre <<  "</map>" << post;
		}
		break;

	case LLSD::TypeArray:
		if(0 == data.size())
		{
			ostr << pre << "<array />" << post;
		}
		else
		{
			ostr << pre << "<array>" << post;
			LLSD::array_const_iterator iter = data.beginArray();
			LLSD::array_const_iterator end = data.endArray();
			for(; iter != end; ++iter)
			{
				format_count += format_impl(*iter, ostr, options, level + 1);
			}
			ostr << pre << "</array>" << post;
		}
		break;

	case LLSD::TypeUndefined:
		ostr << pre << "<undef />" << post;
		break;

	case LLSD::TypeBoolean:
		ostr << pre << "<boolean>";
		if(mBoolAlpha ||
#if( LL_WINDOWS || __GNUC__ > 2)
		   (ostr.flags() & std::ios::boolalpha)
#else
		   (ostr.flags() & 0x0100)
#endif
			)
		{
			ostr << (data.asBoolean() ? "true" : "false");
		}
		else
		{
			ostr << (data.asBoolean() ? 1 : 0);
		}
		ostr << "</boolean>" << post;
		break;

	case LLSD::TypeInteger:
		ostr << pre << "<integer>" << data.asInteger() << "</integer>" << post;
		break;

	case LLSD::TypeReal:
		ostr << pre << "<real>";
		if(mRealFormat.empty())
		{
			ostr << data.asReal();
		}
		else
		{
			formatReal(data.asReal(), ostr);
		}
		ostr << "</real>" << post;
		break;

	case LLSD::TypeUUID:
		if(data.asUUID().isNull()) ostr << pre << "<uuid />" << post;
		else ostr << pre << "<uuid>" << data.asUUID() << "</uuid>" << post;
		break;

	case LLSD::TypeString:
		if(data.asString().empty()) ostr << pre << "<string />" << post;
		else ostr << pre << "<string>" << escapeString(data.asString()) <<"</string>" << post;
		break;

	case LLSD::TypeDate:
		ostr << pre << "<date>" << data.asDate() << "</date>" << post;
		break;

	case LLSD::TypeURI:
		ostr << pre << "<uri>" << escapeString(data.asString()) << "</uri>" << post;
		break;

	case LLSD::TypeBinary:
	{
		LLSD::Binary buffer = data.asBinary();
		if(buffer.empty())
		{
			ostr << pre << "<binary />" << post;
		}
		else
		{
			// *FIX: memory inefficient.
			// *TODO: convert to use LLBase64
			ostr << pre << "<binary encoding=\"base64\">";
			int b64_buffer_length = apr_base64_encode_len(buffer.size());
			char* b64_buffer = new char[b64_buffer_length];
			b64_buffer_length = apr_base64_encode_binary(
				b64_buffer,
				&buffer[0],
				buffer.size());
			ostr.write(b64_buffer, b64_buffer_length - 1);
			delete[] b64_buffer;
			ostr << "</binary>" << post;
		}
		break;
	}
	default:
		// *NOTE: This should never happen.
		ostr << pre << "<undef />" << post;
		break;
	}
	return format_count;
}
void ImportTracker::send_inventory(LLSD& prim)
{
	U32 local_id = prim["LocalID"].asInteger();
	if (prim.has("inventory"))
	{
		std::string assetpre = asset_dir + gDirUtilp->getDirDelimiter();
		LLSD inventory = prim["inventory"];
		for (LLSD::array_iterator inv = inventory.beginArray(); inv != inventory.endArray(); ++inv)
		{
			LLSD item = (*inv);
			InventoryImportInfo* data = new InventoryImportInfo;
			data->localid = local_id;
			LLTransactionID tid;
			tid.generate();
			LLUUID assetid = tid.makeAssetID(gAgent.getSecureSessionID());
			data->tid = tid;
			data->assetid = assetid;
			data->type = LLAssetType::lookup(item["type"].asString());////LLAssetType::EType(U32(item["type"].asInteger()));
			data->name = item["name"].asString();
			data->description = item["desc"].asString();
			if(item.has("item_id"))
			{
				//cmdline_printchat("item id found");
				std::string filename = assetpre + item["item_id"].asString() + "." + item["type"].asString();
				//S32 file_size;
				//LLAPRFile infile ;
				//infile.open(filename, LL_APR_RB, NULL, &file_size);
				//apr_file_t* fp = infile.getFileHandle();
				//if(fp)
				if(LLFile::isfile(filename))
				{
					//cmdline_printchat("file "+filename+" exists");
					data->filename = filename;
					//infile.close();
				}else
				{
					//cmdline_printchat("file "+filename+" does not exist");
					delete data;
					continue;
				}
			}else
			{
				//cmdline_printchat("item id not found");
				delete data;
				continue;
			}

			data->wear_type = NOT_WEARABLE;

			//if(data->type == LLAssetType::AT_LSL_TEXT)
			{
				data->inv_type = LLInventoryType::defaultForAssetType(data->type);
				//printchat("is script");
				data->compiled = false;
				//
				switch(data->type)
				{
				case LLAssetType::AT_TEXTURE:
				case LLAssetType::AT_TEXTURE_TGA:
					//cmdline_printchat("case textures");
					{
						std::string url = gAgent.getRegion()->getCapability("NewFileAgentInventory");
						S32 file_size;
						LLAPRFile infile ;
						infile.open(data->filename, LL_APR_RB, NULL, &file_size);
						if (infile.getFileHandle())
						{
							//cmdline_printchat("got file handle");
							LLVFile file(gVFS, data->assetid, data->type, LLVFile::WRITE);
							file.setMaxSize(file_size);
							const S32 buf_size = 65536;
							U8 copy_buf[buf_size];
							while ((file_size = infile.read(copy_buf, buf_size)))
							{
								file.write(copy_buf, file_size);
							}
							LLSD body;
							body["folder_id"] = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
							body["asset_type"] = LLAssetType::lookup(data->type);
							body["inventory_type"] = LLInventoryType::lookup(data->inv_type);
							body["name"] = data->name;
							body["description"] = data->description;
							body["next_owner_mask"] = LLSD::Integer(U32_MAX);
							body["group_mask"] = LLSD::Integer(U32_MAX);
							body["everyone_mask"] = LLSD::Integer(U32_MAX);
							body["expected_upload_cost"] = LLSD::Integer(LLGlobalEconomy::Singleton::getInstance()->getPriceUpload());
							//cmdline_printchat("posting "+ data->assetid.asString());
							LLHTTPClient::post(url, body, new JCImportInventoryResponder(body, data->assetid, data->type,data));
							//error = TRUE;
						}
					}
					break;
				case LLAssetType::AT_CLOTHING:
				case LLAssetType::AT_BODYPART:
					//cmdline_printchat("case cloth/bodypart");
					{
						S32 file_size;
						LLAPRFile infile ;
						infile.open(data->filename, LL_APR_RB, NULL, &file_size);
						if (infile.getFileHandle())
						{
							//cmdline_printchat("got file handle @ cloth");
							LLVFile file(gVFS, data->assetid, data->type, LLVFile::WRITE);
							file.setMaxSize(file_size);
							const S32 buf_size = 65536;
							U8 copy_buf[buf_size];
							while ((file_size = infile.read(copy_buf, buf_size)))
							{
								file.write(copy_buf, file_size);
							}

							LLFILE* fp = LLFile::fopen(data->filename, "rb");
							if(fp)//HACK LOL LOL LOL
							{
								LLWearable* wearable = new LLWearable(LLUUID::null);
								wearable->importFile( fp );
								//if (!res)
								{
									data->wear_type = wearable->getType();
								}
								delete wearable;
							}
							//cmdline_printchat("storing "+data->assetid.asString());
							gAssetStorage->storeAssetData(data->tid, data->type,
												JCImportInventorycallback,
												(void*)data,
												FALSE,
												TRUE,
												FALSE);
						}
					}
					break;
				case LLAssetType::AT_NOTECARD:
					//cmdline_printchat("case notecard");
					{
						//std::string agent_url = gAgent.getRegion()->getCapability("UpdateNotecardAgentInventory");
						LLPointer<LLInventoryCallback> cb = new JCPostInvCallback(data);
						LLPermissions perm;
						LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
						create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
							gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH), data->tid, data->name,
							data->description, data->type, LLInventoryType::defaultForAssetType(data->type), data->wear_type,
							LLFloaterPerms::getNextOwnerPerms(),
							cb);
					}
					break;
				case LLAssetType::AT_LSL_TEXT:
					{
						LLPointer<LLInventoryCallback> cb = new JCPostInvCallback(data);
						LLPermissions perm;
						LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
						create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
							gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH), data->tid, data->name,
							data->description, data->type, LLInventoryType::defaultForAssetType(data->type), data->wear_type,
							LLFloaterPerms::getNextOwnerPerms(),
							cb);
					}
					break;
				case LLAssetType::AT_SCRIPT://this shouldn't happen as this is legacy shit
				case LLAssetType::AT_GESTURE://we don't import you atm...
				default:
					break;
				}
				asset_insertions += 1;
			}
		}
	}
}
	virtual void post(
		ResponsePtr responder,
		const LLSD& context,
		const LLSD& input) const
	{
		LLHost host(input["sender"].asString());
		LLViewerRegion* region = LLWorld::getInstance()->getRegion(host);
		if( !region )
		{
			return;
		}

		S32 target_index = input["body"]["Index"][0]["Prey"].asInteger();
		S32 you_index    = input["body"]["Index"][0]["You" ].asInteger();

		LLDynamicArray<U32>* avatar_locs = &region->mMapAvatars;
		LLDynamicArray<LLUUID>* avatar_ids = &region->mMapAvatarIDs;
		avatar_locs->reset();
		avatar_ids->reset();

		//llinfos << "coarse locations agent[0] " << input["body"]["AgentData"][0]["AgentID"].asUUID() << llendl;
		//llinfos << "my agent id = " << gAgent.getID() << llendl;
		//llinfos << ll_pretty_print_sd(input) << llendl;

		LLSD 
			locs   = input["body"]["Location"],
			agents = input["body"]["AgentData"];
		LLSD::array_iterator 
			locs_it = locs.beginArray(), 
			agents_it = agents.beginArray();
		BOOL has_agent_data = input["body"].has("AgentData");

		for(int i=0; 
			locs_it != locs.endArray(); 
			i++, locs_it++)
		{
			U8 
				x = locs_it->get("X").asInteger(),
				y = locs_it->get("Y").asInteger(),
				z = locs_it->get("Z").asInteger();
			// treat the target specially for the map, and don't add you or the target
			if(i == target_index)
			{
				LLVector3d global_pos(region->getOriginGlobal());
				global_pos.mdV[VX] += (F64)x;
				global_pos.mdV[VY] += (F64)y;
				global_pos.mdV[VZ] += (F64)z * 4.0;
				LLAvatarTracker::instance().setTrackedCoarseLocation(global_pos);
			}
			else if( i != you_index)
			{
				U32 loc = x << 16 | y << 8 | z; loc = loc;
				U32 pos = 0x0;
				pos |= x;
				pos <<= 8;
				pos |= y;
				pos <<= 8;
				pos |= z;
				avatar_locs->put(pos);
				//llinfos << "next pos: " << x << "," << y << "," << z << ": " << pos << llendl;
				if(has_agent_data) // for backwards compatibility with old message format
				{
					LLUUID agent_id(agents_it->get("AgentID").asUUID());
					//llinfos << "next agent: " << agent_id.asString() << llendl;
					avatar_ids->put(agent_id);
				}
			}
			if (has_agent_data)
			{
				agents_it++;
			}
		}
	}
void MediaPluginWebKit::receiveMessage(const char *message_string)
{
//	std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl;
    LLPluginMessage message_in;

    if(message_in.parse(message_string) >= 0)
    {
        std::string message_class = message_in.getClass();
        std::string message_name = message_in.getName();
        if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE)
        {
            if(message_name == "init")
            {
                LLPluginMessage message("base", "init_response");
                LLSD versions = LLSD::emptyMap();
                versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
                versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION;
                versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION;
                message.setValueLLSD("versions", versions);

                std::string plugin_version = "Webkit media plugin, Webkit version ";
                plugin_version += LLQtWebKit::getInstance()->getVersion();
                message.setValue("plugin_version", plugin_version);
                sendMessage(message);
            }
            else if(message_name == "idle")
            {
                // no response is necessary here.
                F64 time = message_in.getValueReal("time");

                // Convert time to milliseconds for update()
                update((int)(time * 1000.0f));
            }
            else if(message_name == "cleanup")
            {
                // DTOR most likely won't be called but the recent change to the way this process
                // is (not) killed means we see this message and can do what we need to here.
                // Note: this cleanup is ultimately what writes cookies to the disk
                LLQtWebKit::getInstance()->remObserver( mBrowserWindowId, this );
                LLQtWebKit::getInstance()->reset();
            }
            else if(message_name == "shm_added")
            {
                SharedSegmentInfo info;
                info.mAddress = message_in.getValuePointer("address");
                info.mSize = (size_t)message_in.getValueS32("size");
                std::string name = message_in.getValue("name");

//				std::cerr << "MediaPluginWebKit::receiveMessage: shared memory added, name: " << name
//					<< ", size: " << info.mSize
//					<< ", address: " << info.mAddress
//					<< std::endl;

                mSharedSegments.insert(SharedSegmentMap::value_type(name, info));

            }
            else if(message_name == "shm_remove")
            {
                std::string name = message_in.getValue("name");

//				std::cerr << "MediaPluginWebKit::receiveMessage: shared memory remove, name = " << name << std::endl;

                SharedSegmentMap::iterator iter = mSharedSegments.find(name);
                if(iter != mSharedSegments.end())
                {
                    if(mPixels == iter->second.mAddress)
                    {
                        // This is the currently active pixel buffer.  Make sure we stop drawing to it.
                        mPixels = NULL;
                        mTextureSegmentName.clear();
                    }
                    mSharedSegments.erase(iter);
                }
                else
                {
//					std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl;
                }

                // Send the response so it can be cleaned up.
                LLPluginMessage message("base", "shm_remove_response");
                message.setValue("name", name);
                sendMessage(message);
            }
            else
            {
//				std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl;
            }
        }
        else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
        {
            if(message_name == "set_volume")
            {
                F32 volume = message_in.getValueReal("volume");
                setVolume(volume);
            }
        }
        else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
        {
            if(message_name == "init")
            {
                mTarget = message_in.getValue("target");

                // This is the media init message -- all necessary data for initialization should have been received.
                if(initBrowser())
                {

                    // Plugin gets to decide the texture parameters to use.
                    mDepth = 4;

                    LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
                    message.setValueS32("default_width", 1024);
                    message.setValueS32("default_height", 1024);
                    message.setValueS32("depth", mDepth);
                    message.setValueU32("internalformat", GL_RGBA);
#if LL_QTWEBKIT_USES_PIXMAPS
                    message.setValueU32("format", GL_BGRA_EXT); // I hope this isn't system-dependant... is it?  If so, we'll have to check the root window's pixel layout or something... yuck.
#else
                    message.setValueU32("format", GL_RGBA);
#endif // LL_QTWEBKIT_USES_PIXMAPS
                    message.setValueU32("type", GL_UNSIGNED_BYTE);
                    message.setValueBoolean("coords_opengl", true);
                    sendMessage(message);
                }
                else
                {
                    // if initialization failed, we're done.
                    mDeleteMe = true;
                }

            }
            else if(message_name == "set_user_data_path")
            {
                std::string user_data_path = message_in.getValue("path"); // n.b. always has trailing platform-specific dir-delimiter
                mProfileDir = user_data_path + "browser_profile";

                // FIXME: Should we do anything with this if it comes in after the browser has been initialized?
            }
            else if(message_name == "set_language_code")
            {
                mHostLanguage = message_in.getValue("language");

                // FIXME: Should we do anything with this if it comes in after the browser has been initialized?
            }
            else if(message_name == "plugins_enabled")
            {
                mPluginsEnabled = message_in.getValueBoolean("enable");
            }
            else if(message_name == "javascript_enabled")
            {
                mJavascriptEnabled = message_in.getValueBoolean("enable");
            }
            else if(message_name == "size_change")
            {
                std::string name = message_in.getValue("name");
                S32 width = message_in.getValueS32("width");
                S32 height = message_in.getValueS32("height");
                S32 texture_width = message_in.getValueS32("texture_width");
                S32 texture_height = message_in.getValueS32("texture_height");
                mBackgroundR = message_in.getValueReal("background_r");
                mBackgroundG = message_in.getValueReal("background_g");
                mBackgroundB = message_in.getValueReal("background_b");
//				mBackgroundA = message_in.setValueReal("background_a");		// Ignore any alpha

                if(!name.empty())
                {
                    // Find the shared memory region with this name
                    SharedSegmentMap::iterator iter = mSharedSegments.find(name);
                    if(iter != mSharedSegments.end())
                    {
                        mPixels = (unsigned char*)iter->second.mAddress;
                        mWidth = width;
                        mHeight = height;

                        if(initBrowserWindow())
                        {

                            // size changed so tell the browser
                            LLQtWebKit::getInstance()->setSize( mBrowserWindowId, mWidth, mHeight );

                            //						std::cerr << "webkit plugin: set size to " << mWidth << " x " << mHeight
                            //								<< ", rowspan is " << LLQtWebKit::getInstance()->getBrowserRowSpan(mBrowserWindowId) << std::endl;

                            S32 real_width = LLQtWebKit::getInstance()->getBrowserRowSpan(mBrowserWindowId) / LLQtWebKit::getInstance()->getBrowserDepth(mBrowserWindowId);

                            // The actual width the browser will be drawing to is probably smaller... let the host know by modifying texture_width in the response.
                            if(real_width <= texture_width)
                            {
                                texture_width = real_width;
                            }
                            else
                            {
                                // This won't work -- it'll be bigger than the allocated memory.  This is a fatal error.
                                //							std::cerr << "Fatal error: browser rowbytes greater than texture width" << std::endl;
                                mDeleteMe = true;
                                return;
                            }
                        }
                        else
                        {
                            // Setting up the browser window failed.  This is a fatal error.
                            mDeleteMe = true;
                        }


                        mTextureWidth = texture_width;
                        mTextureHeight = texture_height;

                    };
                };

                LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
                message.setValue("name", name);
                message.setValueS32("width", width);
                message.setValueS32("height", height);
                message.setValueS32("texture_width", texture_width);
                message.setValueS32("texture_height", texture_height);
                sendMessage(message);

            }
            else if(message_name == "load_uri")
            {
                std::string uri = message_in.getValue("uri");

//				std::cout << "loading URI: " << uri << std::endl;

                if(!uri.empty())
                {
                    if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE)
                    {
                        LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, uri );
                    }
                    else
                    {
                        mInitialNavigateURL = uri;
                    }
                }
            }
            else if(message_name == "mouse_event")
            {
                std::string event = message_in.getValue("event");
                S32 button = message_in.getValueS32("button");
                mLastMouseX = message_in.getValueS32("x");
                mLastMouseY = message_in.getValueS32("y");
                std::string modifiers = message_in.getValue("modifiers");

                // Treat unknown mouse events as mouse-moves.
                LLQtWebKit::EMouseEvent mouse_event = LLQtWebKit::ME_MOUSE_MOVE;
                if(event == "down")
                {
                    mouse_event = LLQtWebKit::ME_MOUSE_DOWN;
                }
                else if(event == "up")
                {
                    mouse_event = LLQtWebKit::ME_MOUSE_UP;
                }
                else if(event == "double_click")
                {
                    mouse_event = LLQtWebKit::ME_MOUSE_DOUBLE_CLICK;
                }

                LLQtWebKit::getInstance()->mouseEvent( mBrowserWindowId, mouse_event, button, mLastMouseX, mLastMouseY, decodeModifiers(modifiers));
                checkEditState();
            }
            else if(message_name == "scroll_event")
            {
                S32 x = message_in.getValueS32("x");
                S32 y = message_in.getValueS32("y");
                std::string modifiers = message_in.getValue("modifiers");

                // Incoming scroll events are adjusted so that 1 detent is approximately 1 unit.
                // Qt expects 1 detent to be 120 units.
                // It also seems that our y scroll direction is inverted vs. what Qt expects.

                x *= 120;
                y *= -120;

                LLQtWebKit::getInstance()->scrollWheelEvent(mBrowserWindowId, mLastMouseX, mLastMouseY, x, y, decodeModifiers(modifiers));
            }
            else if(message_name == "key_event")
            {
                std::string event = message_in.getValue("event");
                S32 key = message_in.getValueS32("key");
                std::string modifiers = message_in.getValue("modifiers");
                LLSD native_key_data = message_in.getValueLLSD("native_key_data");

                // Treat unknown events as key-up for safety.
                LLQtWebKit::EKeyEvent key_event = LLQtWebKit::KE_KEY_UP;
                if(event == "down")
                {
                    key_event = LLQtWebKit::KE_KEY_DOWN;
                }
                else if(event == "repeat")
                {
                    key_event = LLQtWebKit::KE_KEY_REPEAT;
                }

                keyEvent(key_event, key, decodeModifiers(modifiers), native_key_data);
            }
            else if(message_name == "text_event")
            {
                std::string text = message_in.getValue("text");
                std::string modifiers = message_in.getValue("modifiers");
                LLSD native_key_data = message_in.getValueLLSD("native_key_data");

                unicodeInput(text, decodeModifiers(modifiers), native_key_data);
            }
            if(message_name == "edit_cut")
            {
                LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_CUT );
                checkEditState();
            }
            if(message_name == "edit_copy")
            {
                LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_COPY );
                checkEditState();
            }
            if(message_name == "edit_paste")
            {
                LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_EDIT_PASTE );
                checkEditState();
            }
            if(message_name == "pick_file_response")
            {
                onPickFileResponse(message_in.getValue("file"));
            }
            else
            {
//				std::cerr << "MediaPluginWebKit::receiveMessage: unknown media message: " << message_string << std::endl;
            }
        }
        else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER)
        {
            if(message_name == "focus")
            {
                bool val = message_in.getValueBoolean("focused");
                LLQtWebKit::getInstance()->focusBrowser( mBrowserWindowId, val );

                if(mFirstFocus && val)
                {
                    // On the first focus, post a tab key event.  This fixes a problem with initial focus.
                    std::string empty;
                    keyEvent(LLQtWebKit::KE_KEY_DOWN, KEY_TAB, decodeModifiers(empty));
                    keyEvent(LLQtWebKit::KE_KEY_UP, KEY_TAB, decodeModifiers(empty));
                    mFirstFocus = false;
                }
            }
            else if(message_name == "clear_cache")
            {
                LLQtWebKit::getInstance()->clearCache();
            }
            else if(message_name == "clear_cookies")
            {
                LLQtWebKit::getInstance()->clearAllCookies();
            }
            else if(message_name == "enable_cookies")
            {
                mCookiesEnabled = message_in.getValueBoolean("enable");
                LLQtWebKit::getInstance()->enableCookies( mCookiesEnabled );
            }
            else if(message_name == "enable_plugins")
            {
                mPluginsEnabled = message_in.getValueBoolean("enable");
                LLQtWebKit::getInstance()->enablePlugins( mPluginsEnabled );
            }
            else if(message_name == "enable_javascript")
            {
                mJavascriptEnabled = message_in.getValueBoolean("enable");
                //LLQtWebKit::getInstance()->enableJavascript( mJavascriptEnabled );
            }
            else if(message_name == "set_cookies")
            {
                LLQtWebKit::getInstance()->setCookies(message_in.getValue("cookies"));
            }
            else if(message_name == "proxy_setup")
            {
                bool val = message_in.getValueBoolean("enable");
                std::string host = message_in.getValue("host");
                int port = message_in.getValueS32("port");
                LLQtWebKit::getInstance()->enableProxy( val, host, port );
            }
            else if(message_name == "browse_stop")
            {
                LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_STOP );
            }
            else if(message_name == "browse_reload")
            {
                // foo = message_in.getValueBoolean("ignore_cache");
                LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_RELOAD );
            }
            else if(message_name == "browse_forward")
            {
                LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_FORWARD );
            }
            else if(message_name == "browse_back")
            {
                LLQtWebKit::getInstance()->userAction( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_BACK );
            }
            else if(message_name == "set_status_redirect")
            {
                int code = message_in.getValueS32("code");
                std::string url = message_in.getValue("url");
                if ( 404 == code )	// browser lib only supports 404 right now
                {
                    LLQtWebKit::getInstance()->set404RedirectUrl( mBrowserWindowId, url );
                };
            }
            else if(message_name == "set_user_agent")
            {
                mUserAgent = message_in.getValue("user_agent");
                LLQtWebKit::getInstance()->setBrowserAgentId( mUserAgent );
            }
            else if(message_name == "init_history")
            {
                // Initialize browser history
                LLSD history = message_in.getValueLLSD("history");
                // First, clear the URL history
                LLQtWebKit::getInstance()->clearHistory(mBrowserWindowId);
                // Then, add the history items in order
                LLSD::array_iterator iter_history = history.beginArray();
                LLSD::array_iterator end_history = history.endArray();
                for(; iter_history != end_history; ++iter_history)
                {
                    std::string url = (*iter_history).asString();
                    if(! url.empty()) {
                        LLQtWebKit::getInstance()->prependHistoryUrl(mBrowserWindowId, url);
                    }
                }
            }
            else if(message_name == "proxy_window_opened")
            {
                std::string target = message_in.getValue("target");
                std::string uuid = message_in.getValue("uuid");
                LLQtWebKit::getInstance()->proxyWindowOpened(mBrowserWindowId, target, uuid);
            }
            else if(message_name == "proxy_window_closed")
            {
                std::string uuid = message_in.getValue("uuid");
                LLQtWebKit::getInstance()->proxyWindowClosed(mBrowserWindowId, uuid);
            }
            else
            {
//				std::cerr << "MediaPluginWebKit::receiveMessage: unknown media_browser message: " << message_string << std::endl;
            };
        }
        else
        {
//			std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl;
        };
    }
}