PageRenderTime 71ms CodeModel.GetById 12ms app.highlight 53ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/newview/llviewernetwork.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 642 lines | 471 code | 65 blank | 106 comment | 56 complexity | 38d109fceb0845566376ff975a67f25f MD5 | raw file
  1/** 
  2 * @file llviewernetwork.cpp
  3 * @author James Cook, Richard Nelson
  4 * @brief Networking constants and globals for viewer.
  5 *
  6 * $LicenseInfo:firstyear=2006&license=viewerlgpl$
  7 * Second Life Viewer Source Code
  8 * Copyright (C) 2010, Linden Research, Inc.
  9 * 
 10 * This library is free software; you can redistribute it and/or
 11 * modify it under the terms of the GNU Lesser General Public
 12 * License as published by the Free Software Foundation;
 13 * version 2.1 of the License only.
 14 * 
 15 * This library is distributed in the hope that it will be useful,
 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 18 * Lesser General Public License for more details.
 19 * 
 20 * You should have received a copy of the GNU Lesser General Public
 21 * License along with this library; if not, write to the Free Software
 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 23 * 
 24 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 25 * $/LicenseInfo$
 26 */
 27
 28#include "llviewerprecompiledheaders.h"
 29
 30#include "llviewernetwork.h"
 31#include "llviewercontrol.h"
 32#include "llsdserialize.h"
 33#include "llsecapi.h"
 34#include "lltrans.h"
 35#include "llweb.h"
 36
 37                                                            
 38const char* DEFAULT_LOGIN_PAGE = "http://viewer-login.agni.lindenlab.com/";
 39
 40const char* SYSTEM_GRID_SLURL_BASE = "secondlife://%s/secondlife/";
 41const char* MAIN_GRID_SLURL_BASE = "http://maps.secondlife.com/secondlife/";
 42const char* SYSTEM_GRID_APP_SLURL_BASE = "secondlife:///app";
 43
 44const char* DEFAULT_SLURL_BASE = "https://%s/region/";
 45const char* DEFAULT_APP_SLURL_BASE = "x-grid-location-info://%s/app";
 46
 47LLGridManager::LLGridManager()
 48:	mIsInProductionGrid(false)
 49{
 50	// by default, we use the 'grids.xml' file in the user settings directory
 51	// this file is an LLSD file containing multiple grid definitions.
 52	// This file does not contain definitions for secondlife.com grids,
 53	// as that would be a security issue when they are overwritten by
 54	// an attacker.  Don't want someone snagging a password.
 55	std::string grid_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,
 56														   "grids.xml");
 57	initialize(grid_file);
 58	
 59}
 60
 61
 62LLGridManager::LLGridManager(const std::string& grid_file)
 63{
 64	// initialize with an explicity grid file for testing.
 65	initialize(grid_file);
 66}
 67
 68//
 69// LLGridManager - class for managing the list of known grids, and the current
 70// selection
 71//
 72
 73
 74//
 75// LLGridManager::initialze - initialize the list of known grids based
 76// on the fixed list of linden grids (fixed for security reasons)
 77// the grids.xml file
 78// and the command line.
 79void LLGridManager::initialize(const std::string& grid_file)
 80{
 81	// default grid list.
 82	// Don't move to a modifiable file for security reasons,
 83	mGrid.clear() ;
 84	// set to undefined
 85	mGridList = LLSD();
 86	mGridFile = grid_file;
 87	// as we don't want an attacker to override our grid list
 88	// to point the default grid to an invalid grid
 89	addSystemGrid("None", "", "", "", DEFAULT_LOGIN_PAGE);
 90	
 91
 92
 93  	addSystemGrid("Agni",                                                                                             
 94				  MAINGRID,                                               
 95				  "https://login.agni.lindenlab.com/cgi-bin/login.cgi",                    
 96				  "https://secondlife.com/helpers/",     
 97				  DEFAULT_LOGIN_PAGE);
 98	addSystemGrid("Aditi",                                                                                             
 99				  "util.aditi.lindenlab.com",                                              
100				  "https://login.aditi.lindenlab.com/cgi-bin/login.cgi",                   
101				  "http://aditi-secondlife.webdev.lindenlab.com/helpers/",
102				  DEFAULT_LOGIN_PAGE);
103	addSystemGrid("Aruna",                                                                                            
104				  "util.aruna.lindenlab.com",                                              
105				  "https://login.aruna.lindenlab.com/cgi-bin/login.cgi",                   
106				  "http://aruna-secondlife.webdev.lindenlab.com/helpers/",
107				  DEFAULT_LOGIN_PAGE);
108	addSystemGrid("Bharati",                                                                                            
109				  "util.bharati.lindenlab.com",                                              
110				  "https://login.bharati.lindenlab.com/cgi-bin/login.cgi",                   
111				  "http://bharati-secondlife.webdev.lindenlab.com/helpers/",
112				  DEFAULT_LOGIN_PAGE);
113	addSystemGrid("Chandra",                                                                                            
114				  "util.chandra.lindenlab.com",                                              
115				  "https://login.chandra.lindenlab.com/cgi-bin/login.cgi",                   
116				  "http://chandra-secondlife.webdev.lindenlab.com/helpers/",
117				  DEFAULT_LOGIN_PAGE);
118	addSystemGrid("Damballah",                                                                                            
119				  "util.damballah.lindenlab.com",                                              
120				  "https://login.damballah.lindenlab.com/cgi-bin/login.cgi",                   
121				  "http://damballah-secondlife.webdev.lindenlab.com/helpers/",
122				  DEFAULT_LOGIN_PAGE);
123	addSystemGrid("Danu",                                                                                            
124				  "util.danu.lindenlab.com",                                              
125				  "https://login.danu.lindenlab.com/cgi-bin/login.cgi",                   
126				  "http://danu-secondlife.webdev.lindenlab.com/helpers/",
127				  DEFAULT_LOGIN_PAGE);
128	addSystemGrid("Durga",                                                                                            
129				  "util.durga.lindenlab.com",                                              
130				  "https://login.durga.lindenlab.com/cgi-bin/login.cgi",                   
131				  "http://durga-secondlife.webdev.lindenlab.com/helpers/",
132				  DEFAULT_LOGIN_PAGE);
133	addSystemGrid("Ganga",                                                                                            
134				  "util.ganga.lindenlab.com",                                              
135				  "https://login.ganga.lindenlab.com/cgi-bin/login.cgi",                   
136				  "http://ganga-secondlife.webdev.lindenlab.com/helpers/",
137				  DEFAULT_LOGIN_PAGE);
138	addSystemGrid("Mitra",                                                                                            
139				  "util.mitra.lindenlab.com",                                              
140				  "https://login.mitra.lindenlab.com/cgi-bin/login.cgi",                   
141				  "http://mitra-secondlife.webdev.lindenlab.com/helpers/",
142				  DEFAULT_LOGIN_PAGE);
143	addSystemGrid("Mohini",                                                                                           
144				  "util.mohini.lindenlab.com",                                             
145				  "https://login.mohini.lindenlab.com/cgi-bin/login.cgi",                  
146				  "http://mohini-secondlife.webdev.lindenlab.com/helpers/",
147				  DEFAULT_LOGIN_PAGE);
148	addSystemGrid("Nandi",                                                                                            
149				  "util.nandi.lindenlab.com",                                              
150				  "https://login.nandi.lindenlab.com/cgi-bin/login.cgi",                   
151				  "http://nandi-secondlife.webdev.lindenlab.com/helpers/",
152				  DEFAULT_LOGIN_PAGE);
153	addSystemGrid("Parvati",                                                                                            
154				  "util.parvati.lindenlab.com",                                              
155				  "https://login.parvati.lindenlab.com/cgi-bin/login.cgi",                   
156				  "http://parvati-secondlife.webdev.lindenlab.com/helpers/",
157				  DEFAULT_LOGIN_PAGE);
158	addSystemGrid("Radha",                                                                                            
159				  "util.radha.lindenlab.com",                                              
160				  "https://login.radha.lindenlab.com/cgi-bin/login.cgi",                   
161				  "http://radha-secondlife.webdev.lindenlab.com/helpers/",
162				  DEFAULT_LOGIN_PAGE);
163	addSystemGrid("Ravi",                                                                                             
164				  "util.ravi.lindenlab.com",                                               
165				  "https://login.ravi.lindenlab.com/cgi-bin/login.cgi",                    
166				  "http://ravi-secondlife.webdev.lindenlab.com/helpers/",
167				  DEFAULT_LOGIN_PAGE);
168	addSystemGrid("Siva",                                                                                             
169				  "util.siva.lindenlab.com",                                               
170				  "https://login.siva.lindenlab.com/cgi-bin/login.cgi",                    
171				  "http://siva-secondlife.webdev.lindenlab.com/helpers/",
172				  DEFAULT_LOGIN_PAGE);
173	addSystemGrid("Shakti",                                                                                           
174				  "util.shakti.lindenlab.com",                                             
175				  "https://login.shakti.lindenlab.com/cgi-bin/login.cgi",                  
176				  "http://shakti-secondlife.webdev.lindenlab.com/helpers/",
177				  DEFAULT_LOGIN_PAGE);
178	addSystemGrid("Soma",                                                                                             
179				  "util.soma.lindenlab.com",                                               
180				  "https://login.soma.lindenlab.com/cgi-bin/login.cgi",                    
181				  "http://soma-secondlife.webdev.lindenlab.com/helpers/",
182				  DEFAULT_LOGIN_PAGE);
183	addSystemGrid("Uma",                                                                                              
184				  "util.uma.lindenlab.com",                                                
185				  "https://login.uma.lindenlab.com/cgi-bin/login.cgi",                     
186				  "http://uma-secondlife.webdev.lindenlab.com/helpers/",
187				  DEFAULT_LOGIN_PAGE);
188	addSystemGrid("Vaak",                                                                                             
189				  "util.vaak.lindenlab.com",                                               
190				  "https://login.vaak.lindenlab.com/cgi-bin/login.cgi",                    
191				  "http://vaak-secondlife.webdev.lindenlab.com/helpers/",
192				  DEFAULT_LOGIN_PAGE);
193	addSystemGrid("Yami",                                                                                             
194				  "util.yami.lindenlab.com",                                               
195				  "https://login.yami.lindenlab.com/cgi-bin/login.cgi",                    
196				  "http://yami-secondlife.webdev.lindenlab.com/helpers/",
197				  DEFAULT_LOGIN_PAGE);
198	addSystemGrid("Local (Linden)",                                                                                    
199				  "localhost",                                                             
200				  "https://login.dmz.lindenlab.com/cgi-bin/login.cgi",                     
201				  "",
202				  DEFAULT_LOGIN_PAGE); 
203
204	
205	LLSD other_grids;
206	llifstream llsd_xml;
207	if (!grid_file.empty())
208	{
209		llsd_xml.open( grid_file.c_str(), std::ios::in | std::ios::binary );
210
211		// parse through the gridfile, inserting grids into the list unless
212		// they overwrite a linden grid.
213		if( llsd_xml.is_open()) 
214		{
215			LLSDSerialize::fromXMLDocument( other_grids, llsd_xml );
216			if(other_grids.isMap())
217			{
218				for(LLSD::map_iterator grid_itr = other_grids.beginMap(); 
219					grid_itr != other_grids.endMap();
220					++grid_itr)
221				{
222					LLSD::String key_name = grid_itr->first;
223					LLSD grid = grid_itr->second;
224					// TODO:  Make sure gridfile specified label is not 
225					// a system grid label
226					LL_DEBUGS("GridManager") << "reading: " << key_name << LL_ENDL;
227					if (mGridList.has(key_name) &&
228						mGridList[key_name].has(GRID_IS_SYSTEM_GRID_VALUE))
229					{
230						LL_DEBUGS("GridManager") << "Cannot override grid " << key_name << " as it's a system grid" << LL_ENDL;
231						// If the system grid does exist in the grids file, and it's marked as a favorite, set it as a favorite.
232						if(grid_itr->second.has(GRID_IS_FAVORITE_VALUE) && grid_itr->second[GRID_IS_FAVORITE_VALUE].asBoolean() )
233						{
234							mGridList[key_name][GRID_IS_FAVORITE_VALUE] = TRUE;
235						}
236					}
237					else
238					{
239						try
240						{
241							addGrid(grid);
242							LL_DEBUGS("GridManager") << "Added grid: " << key_name << LL_ENDL;
243						}
244						catch (...)
245						{
246						}
247					}
248				}
249				llsd_xml.close();
250			}	
251		}     
252	}
253	
254	// load a grid from the command line.
255	// if the actual grid name is specified from the command line,
256	// set it as the 'selected' grid.
257	std::string cmd_line_grid = gSavedSettings.getString("CmdLineGridChoice");
258	if(!cmd_line_grid.empty())
259	{
260		// try to find the grid assuming the command line parameter is
261		// the case-insensitive 'label' of the grid.  ie 'Agni'
262		mGrid = getGridByLabel(cmd_line_grid);
263		if(mGrid.empty())
264		{
265			// if we couldn't find it, assume the
266			// requested grid is the actual grid 'name' or index,
267			// which would be the dns name of the grid (for non
268			// linden hosted grids)
269			// If the grid isn't there, that's ok, as it will be
270			// automatically added later.
271			mGrid = cmd_line_grid;
272		}
273		
274	}
275	else
276	{
277		// if a grid was not passed in via the command line, grab it from the CurrentGrid setting.
278		// if there's no current grid, that's ok as it'll be either set by the value passed
279		// in via the login uri if that's specified, or will default to maingrid
280		mGrid = gSavedSettings.getString("CurrentGrid");
281	}
282	
283	if(mGrid.empty())
284	{
285		// no grid was specified so default to maingrid
286		LL_DEBUGS("GridManager") << "Setting grid to MAINGRID as no grid has been specified " << LL_ENDL;
287		mGrid = MAINGRID;
288		
289	}
290	
291	// generate a 'grid list' entry for any command line parameter overrides
292	// or setting overides that we'll add to the grid list or override
293	// any grid list entries with.
294	LLSD grid = LLSD::emptyMap();	
295	
296	if(mGridList.has(mGrid))
297	{
298		grid = mGridList[mGrid];
299	}
300	else
301	{
302		grid[GRID_VALUE] = mGrid;
303		// add the grid with the additional values, or update the
304		// existing grid if it exists with the given values
305		addGrid(grid);		
306	}
307
308	LLControlVariablePtr grid_control = gSavedSettings.getControl("CurrentGrid");
309	if (grid_control.notNull())
310	{
311		grid_control->getSignal()->connect(boost::bind(&LLGridManager::updateIsInProductionGrid, this));
312	}
313
314	// since above only triggers on changes, trigger the callback manually to initialize state
315	updateIsInProductionGrid();
316
317	LL_DEBUGS("GridManager") << "Selected grid is " << mGrid << LL_ENDL;		
318	setGridChoice(mGrid);
319	if(mGridList[mGrid][GRID_LOGIN_URI_VALUE].isArray())
320	{
321		llinfos << "is array" << llendl;
322	}
323}
324
325LLGridManager::~LLGridManager()
326{
327	saveFavorites();
328}
329
330void LLGridManager::getGridInfo(const std::string &grid, LLSD& grid_info)
331{
332	
333	grid_info = mGridList[grid]; 
334	
335	// override any grid data with the command line info.
336	
337	LLSD cmd_line_login_uri = gSavedSettings.getLLSD("CmdLineLoginURI");
338	if (cmd_line_login_uri.isString())
339	{	
340		grid_info[GRID_LOGIN_URI_VALUE] = LLSD::emptyArray();
341		grid_info[GRID_LOGIN_URI_VALUE].append(cmd_line_login_uri);
342	}
343	
344	// override the helper uri if it was passed in
345	std::string cmd_line_helper_uri = gSavedSettings.getString("CmdLineHelperURI");
346	if(!cmd_line_helper_uri.empty())
347	{
348		grid_info[GRID_HELPER_URI_VALUE] = cmd_line_helper_uri;	
349	}
350	
351	// override the login page if it was passed in
352	std::string cmd_line_login_page = gSavedSettings.getString("LoginPage");
353	if(!cmd_line_login_page.empty())
354	{
355		grid_info[GRID_LOGIN_PAGE_VALUE] = cmd_line_login_page;
356	}	
357}
358
359
360//
361// LLGridManager::addGrid - add a grid to the grid list, populating the needed values
362// if they're not populated yet.
363//
364
365void LLGridManager::addGrid(LLSD& grid_data)
366{
367	if (grid_data.isMap() && grid_data.has(GRID_VALUE))
368	{
369		std::string grid = utf8str_tolower(grid_data[GRID_VALUE]);
370
371		// grid should be in the form of a dns address
372		if (!grid.empty() &&
373			grid.find_first_not_of("abcdefghijklmnopqrstuvwxyz1234567890-_. ") != std::string::npos)
374		{
375			printf("grid name: %s", grid.c_str());
376			throw LLInvalidGridName(grid);
377		}
378		
379		// populate the other values if they don't exist
380		if (!grid_data.has(GRID_LABEL_VALUE)) 
381		{
382			grid_data[GRID_LABEL_VALUE] = grid;
383		}
384		if (!grid_data.has(GRID_ID_VALUE))
385		{
386			grid_data[GRID_ID_VALUE] = grid;
387		}
388		
389		// if the grid data doesn't include any of the URIs, then 
390		// generate them from the grid, which should be a dns address
391		if (!grid_data.has(GRID_LOGIN_URI_VALUE)) 
392		{
393			grid_data[GRID_LOGIN_URI_VALUE] = LLSD::emptyArray();
394			grid_data[GRID_LOGIN_URI_VALUE].append(std::string("https://") + 
395													grid + "/cgi-bin/login.cgi");
396		}
397		// Populate to the default values
398		if (!grid_data.has(GRID_LOGIN_PAGE_VALUE)) 
399		{
400			grid_data[GRID_LOGIN_PAGE_VALUE] = std::string("http://") + grid + "/app/login/";
401		}		
402		if (!grid_data.has(GRID_HELPER_URI_VALUE)) 
403		{
404			grid_data[GRID_HELPER_URI_VALUE] = std::string("https://") + grid + "/helpers/";
405		}
406		
407		if (!grid_data.has(GRID_LOGIN_IDENTIFIER_TYPES))
408		{
409			// non system grids and grids that haven't already been configured with values
410			// get both types of credentials.
411			grid_data[GRID_LOGIN_IDENTIFIER_TYPES] = LLSD::emptyArray();
412			grid_data[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_AGENT);
413			grid_data[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_ACCOUNT);
414		}
415		
416		LL_DEBUGS("GridManager") << "ADDING: " << grid << LL_ENDL;
417		mGridList[grid] = grid_data;		
418	}
419}
420
421//
422// LLGridManager::addSystemGrid - helper for adding a system grid.
423void LLGridManager::addSystemGrid(const std::string& label, 
424								  const std::string& name, 
425								  const std::string& login, 
426								  const std::string& helper,
427								  const std::string& login_page,
428								  const std::string& login_id)
429{
430	LLSD grid = LLSD::emptyMap();
431	grid[GRID_VALUE] = name;
432	grid[GRID_LABEL_VALUE] = label;
433	grid[GRID_HELPER_URI_VALUE] = helper;
434	grid[GRID_LOGIN_URI_VALUE] = LLSD::emptyArray();
435	grid[GRID_LOGIN_URI_VALUE].append(login);
436	grid[GRID_LOGIN_PAGE_VALUE] = login_page;
437	grid[GRID_IS_SYSTEM_GRID_VALUE] = TRUE;
438	grid[GRID_LOGIN_IDENTIFIER_TYPES] = LLSD::emptyArray();
439	grid[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_AGENT);
440	
441	grid[GRID_APP_SLURL_BASE] = SYSTEM_GRID_APP_SLURL_BASE;
442	if (login_id.empty())
443	{
444		grid[GRID_ID_VALUE] = name;
445	}
446	else
447	{
448		grid[GRID_ID_VALUE] = login_id;
449	}
450	
451	// only add the system grids beyond agni to the visible list
452	// if we're building a debug version.
453	if (name == std::string(MAINGRID))
454	{
455		grid[GRID_SLURL_BASE] = MAIN_GRID_SLURL_BASE;		
456		grid[GRID_IS_FAVORITE_VALUE] = TRUE;		
457	}
458	else
459	{
460		grid[GRID_SLURL_BASE] = llformat(SYSTEM_GRID_SLURL_BASE, label.c_str());
461	}
462	addGrid(grid);
463}
464
465// return a list of grid name -> grid label mappings for UI purposes
466std::map<std::string, std::string> LLGridManager::getKnownGrids(bool favorite_only)
467{
468	std::map<std::string, std::string> result;
469	for(LLSD::map_iterator grid_iter = mGridList.beginMap();
470		grid_iter != mGridList.endMap();
471		grid_iter++) 
472	{
473		if(!favorite_only || grid_iter->second.has(GRID_IS_FAVORITE_VALUE))
474		{
475			result[grid_iter->first] = grid_iter->second[GRID_LABEL_VALUE].asString();
476		}
477	}
478
479	return result;
480}
481
482
483void LLGridManager::setGridChoice(const std::string& grid)
484{
485	// Set the grid choice based on a string.
486	// The string can be:
487	// - a grid label from the gGridInfo table 
488	// - a hostname
489	// - an ip address
490
491	// loop through.  We could do just a hash lookup but we also want to match
492	// on label
493	std::string grid_name = grid;
494	if(!mGridList.has(grid_name))
495	{
496		// case insensitive
497		grid_name = getGridByLabel(grid);
498	}
499	
500	if(grid_name.empty())
501	{
502		// the grid was not in the list of grids.
503		LLSD grid_data = LLSD::emptyMap();
504		grid_data[GRID_VALUE] = grid;
505		addGrid(grid_data);		
506	}
507	mGrid = grid;
508	gSavedSettings.setString("CurrentGrid", grid);
509
510	updateIsInProductionGrid();
511}
512
513std::string LLGridManager::getGridByLabel( const std::string &grid_label, bool case_sensitive)
514{
515	for(LLSD::map_iterator grid_iter = mGridList.beginMap();
516		grid_iter != mGridList.endMap();
517		grid_iter++) 
518	{
519		if (grid_iter->second.has(GRID_LABEL_VALUE))
520		{
521			if (0 == (case_sensitive?LLStringUtil::compareStrings(grid_label, grid_iter->second[GRID_LABEL_VALUE].asString()):
522				LLStringUtil::compareInsensitive(grid_label, grid_iter->second[GRID_LABEL_VALUE].asString())))
523			{
524				return grid_iter->first;
525			}
526		}
527	}
528	return std::string();
529}
530
531void LLGridManager::getLoginURIs(std::vector<std::string>& uris)
532{
533	uris.clear();
534	LLSD cmd_line_login_uri = gSavedSettings.getLLSD("CmdLineLoginURI");
535	if (cmd_line_login_uri.isString())
536	{	
537		uris.push_back(cmd_line_login_uri);
538		return;
539	}
540	for (LLSD::array_iterator llsd_uri = mGridList[mGrid][GRID_LOGIN_URI_VALUE].beginArray();
541		 llsd_uri != mGridList[mGrid][GRID_LOGIN_URI_VALUE].endArray();
542		 llsd_uri++)
543	{
544		uris.push_back(llsd_uri->asString());
545	}
546}
547
548std::string LLGridManager::getHelperURI() 
549{
550	std::string cmd_line_helper_uri = gSavedSettings.getString("CmdLineHelperURI");
551	if(!cmd_line_helper_uri.empty())
552	{
553		return cmd_line_helper_uri;	
554	}
555	return mGridList[mGrid][GRID_HELPER_URI_VALUE];
556}
557
558std::string LLGridManager::getLoginPage() 
559{
560	// override the login page if it was passed in
561	std::string cmd_line_login_page = gSavedSettings.getString("LoginPage");
562	if(!cmd_line_login_page.empty())
563	{
564		return cmd_line_login_page;
565	}	
566	
567	return mGridList[mGrid][GRID_LOGIN_PAGE_VALUE];
568}
569
570void LLGridManager::updateIsInProductionGrid()
571{
572	mIsInProductionGrid = false;
573
574	// *NOTE:Mani This used to compare GRID_INFO_AGNI to gGridChoice,
575	// but it seems that loginURI trumps that.
576	std::vector<std::string> uris;
577	getLoginURIs(uris);
578	if (uris.empty())
579	{
580		mIsInProductionGrid = true;
581		return;
582	}
583	LLStringUtil::toLower(uris[0]);
584	if((uris[0].find("agni") != std::string::npos))
585	{
586		mIsInProductionGrid = true;
587		return;
588	}
589}
590
591bool LLGridManager::isInProductionGrid()
592{
593	return mIsInProductionGrid;
594}
595
596void LLGridManager::saveFavorites()
597{
598	// filter out just those marked as favorites
599	LLSD output_grid_list = LLSD::emptyMap();
600	for(LLSD::map_iterator grid_iter = mGridList.beginMap();
601		grid_iter != mGridList.endMap();
602		grid_iter++)
603	{
604		if(grid_iter->second.has(GRID_IS_FAVORITE_VALUE))
605		{
606			output_grid_list[grid_iter->first] = grid_iter->second;
607		}
608	}       
609	llofstream llsd_xml;
610	llsd_xml.open( mGridFile.c_str(), std::ios::out | std::ios::binary);	
611	LLSDSerialize::toPrettyXML(output_grid_list, llsd_xml);
612	llsd_xml.close();
613}
614
615
616// build a slurl for the given region within the selected grid
617std::string LLGridManager::getSLURLBase(const std::string& grid)
618{
619	std::string grid_base;
620	if(mGridList.has(grid) && mGridList[grid].has(GRID_SLURL_BASE))
621	{
622		return mGridList[grid][GRID_SLURL_BASE].asString();
623	}
624	else
625	{
626		return  llformat(DEFAULT_SLURL_BASE, grid.c_str());
627	}
628}
629
630// build a slurl for the given region within the selected grid
631std::string LLGridManager::getAppSLURLBase(const std::string& grid)
632{
633	std::string grid_base;
634	if(mGridList.has(grid) && mGridList[grid].has(GRID_APP_SLURL_BASE))
635	{
636	  return mGridList[grid][GRID_APP_SLURL_BASE].asString();
637	}
638	else
639	{
640	  return  llformat(DEFAULT_APP_SLURL_BASE, grid.c_str());
641	}
642}