Index: wp-includes/link-template.php
===================================================================
--- wp-includes/link-template.php	(revision 12938)
+++ wp-includes/link-template.php	(working copy)
@@ -1732,32 +1732,59 @@
 }
 
 /**
- * Retrieve the home url.
+ * Retrieve the home url for the current site.
  *
  * Returns the 'home' option with the appropriate protocol,  'https' if
  * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is
  * overridden.
  *
  * @package WordPress
- * @since 3.0
+ * @since 3.0.0
  *
+ * @uses get_home_url()
+ *
  * @param  string $path   (optional) Path relative to the home url.
  * @param  string $scheme (optional) Scheme to give the home url context. Currently 'http','https'
  * @return string Home url link with optional path appended.
 */
 function home_url( $path = '', $scheme = null ) {
+	return get_home_url(null, $path, $scheme);
+}
+
+/**
+ * Retrieve the home url for a given site.
+ *
+ * Returns the 'home' option with the appropriate protocol,  'https' if
+ * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is
+ * overridden.
+ *
+ * @package WordPress
+ * @since 3.0.0
+ *
+ * @param  int $blog_id   (optional) Blog ID. Defaults to current blog.
+ * @param  string $path   (optional) Path relative to the home url.
+ * @param  string $scheme (optional) Scheme to give the home url context. Currently 'http','https'
+ * @return string Home url link with optional path appended.
+*/
+function get_home_url( $blog_id = null, $path = '', $scheme = null ) {
 	$orig_scheme = $scheme;
 	$scheme      = is_ssl() && !is_admin() ? 'https' : 'http';
-	$url = str_replace( 'http://', "$scheme://", get_option('home') );
 
+	if ( empty($blog_id) || !is_multisite() )
+		$home = get_option('home');
+	else
+		$home = untrailingslashit(get_blogaddress_by_id($blog_id));
+
+	$url = str_replace( 'http://', "$scheme://", $home );
+
 	if ( !empty( $path ) && is_string( $path ) && strpos( $path, '..' ) === false )
 		$url .= '/' . ltrim( $path, '/' );
 
-	return apply_filters( 'home_url', $url, $path, $orig_scheme );
+	return apply_filters( 'home_url', $url, $path, $orig_scheme, $blog_id );
 }
 
 /**
- * Retrieve the site url.
+ * Retrieve the site url for the current site.
  *
  * Returns the 'site_url' option with the appropriate protocol,  'https' if
  * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is
@@ -1766,11 +1793,32 @@
  * @package WordPress
  * @since 2.6.0
  *
+ * @uses get_site_url()
+ *
  * @param string $path Optional. Path relative to the site url.
  * @param string $scheme Optional. Scheme to give the site url context. Currently 'http','https', 'login', 'login_post', or 'admin'.
  * @return string Site url link with optional path appended.
 */
-function site_url($path = '', $scheme = null) {
+function site_url( $path = '', $scheme = null ) {
+	return get_site_url(null, $path, $scheme);
+}
+
+/**
+ * Retrieve the site url for a given site.
+ *
+ * Returns the 'site_url' option with the appropriate protocol,  'https' if
+ * is_ssl() and 'http' otherwise. If $scheme is 'http' or 'https', is_ssl() is
+ * overridden.
+ *
+ * @package WordPress
+ * @since 3.0.0
+ *
+ * @param int $blog_id (optional) Blog ID. Defaults to current blog.
+ * @param string $path Optional. Path relative to the site url.
+ * @param string $scheme Optional. Scheme to give the site url context. Currently 'http','https', 'login', 'login_post', or 'admin'.
+ * @return string Site url link with optional path appended.
+*/
+function get_site_url( $blog_id = null, $path = '', $scheme = null ) {
 	// should the list of allowed schemes be maintained elsewhere?
 	$orig_scheme = $scheme;
 	if ( !in_array($scheme, array('http', 'https')) ) {
@@ -1784,16 +1832,21 @@
 			$scheme = ( is_ssl() ? 'https' : 'http' );
 	}
 
-	$url = str_replace( 'http://', "{$scheme}://", get_option('siteurl') );
+	if ( empty($blog_id) || !is_multisite() )
+		$url = get_option('siteurl');
+	else
+		$url = untrailingslashit(get_blogaddress_by_id($blog_id));
 
+	$url = str_replace( 'http://', "{$scheme}://", $url );
+
 	if ( !empty($path) && is_string($path) && strpos($path, '..') === false )
 		$url .= '/' . ltrim($path, '/');
 
-	return apply_filters('site_url', $url, $path, $orig_scheme);
+	return apply_filters('site_url', $url, $path, $orig_scheme, $blog_id);
 }
 
 /**
- * Retrieve the url to the admin area.
+ * Retrieve the url to the admin area for the current site.
  *
  * @package WordPress
  * @since 2.6.0
@@ -1801,13 +1854,27 @@
  * @param string $path Optional path relative to the admin url
  * @return string Admin url link with optional path appended
 */
-function admin_url($path = '') {
-	$url = site_url('wp-admin/', 'admin');
+function admin_url( $path = '' ) {
+	return get_admin_url(null, $path);
+}
 
+/**
+ * Retrieve the url to the admin area for a given site.
+ *
+ * @package WordPress
+ * @since 3.0.0
+ *
+ * @param int $blog_id (optional) Blog ID. Defaults to current blog.
+ * @param string $path Optional path relative to the admin url
+ * @return string Admin url link with optional path appended
+*/
+function get_admin_url( $blog_id = null, $path = '' ) {
+	$url = get_site_url($blog_id, 'wp-admin/', 'admin');
+
 	if ( !empty($path) && is_string($path) && strpos($path, '..') === false )
 		$url .= ltrim($path, '/');
 
-	return apply_filters('admin_url', $url, $path);
+	return apply_filters('admin_url', $url, $path, $blog_id);
 }
 
 /**
Index: wp-admin/ms-edit.php
===================================================================
--- wp-admin/ms-edit.php	(revision 12938)
+++ wp-admin/ms-edit.php	(working copy)
@@ -204,11 +204,12 @@
 		}
 
 		if ( $_POST['update_home_url'] == 'update' ) {
-			if ( get_option( 'siteurl' ) != 'http://' . $_POST['blog']['domain'] . $_POST['blog']['path'] )
-				update_option( 'siteurl', 'http://' . $_POST['blog']['domain'] . $_POST['blog']['path'] );
+			$blog_address = get_blogaddress_by_domain($_POST['blog']['domain'], $_POST['blog']['path']);
+			if ( get_option( 'siteurl' ) !=  $blog_address )
+				update_option( 'siteurl', $blog_address);
 
-			if ( get_option( 'home' ) != 'http://' . $_POST['blog']['domain'] . $_POST['blog']['path'] )
-				update_option( 'home', 'http://' . $_POST['blog']['domain'] . $_POST['blog']['path'] );
+			if ( get_option( 'home' ) != $blog_address )
+				update_option( 'home', $blog_address );
 		}
 
 		$wp_rewrite->flush_rules();
Index: wp-admin/ms-sites.php
===================================================================
--- wp-admin/ms-sites.php	(revision 12938)
+++ wp-admin/ms-sites.php	(working copy)
@@ -82,7 +82,7 @@
 		?>
 		<div class="wrap">
 		<?php screen_icon(); ?>
-		<h2><?php _e('Edit Site'); ?> - <a href='http://<?php echo $details->domain . $details->path; ?>'>http://<?php echo $details->domain . $details->path; ?></a></h2>
+		<h2><?php _e('Edit Site'); ?> - <a href='<?php echo get_home_url($id); ?>'><?php echo get_home_url($id); ?></a></h2>
 		<form method="post" action="ms-edit.php?action=updateblog">
 			<?php wp_nonce_field('editblog'); ?>
 			<input type="hidden" name="id" value="<?php echo esc_attr($id) ?>" />
@@ -93,12 +93,12 @@
 				<table class="form-table">
 							<tr class="form-field form-required">
 								<th scope="row"><?php _e('Domain') ?></th>
-								<td>http://<input name="blog[domain]" type="text" id="domain" value="<?php echo $details->domain ?>" size="33" /></td>
+								<td>http://<input name="blog[domain]" type="text" id="domain" value="<?php echo esc_attr($details->domain) ?>" size="33" /></td>
 							</tr>
 							<tr class="form-field form-required">
 								<th scope="row"><?php _e('Path') ?></th>
 								<td><input name="blog[path]" type="text" id="path" value="<?php echo esc_attr($details->path) ?>" size="40" style='margin-bottom:5px;' />
-								<br /><input type='checkbox' style='width:20px;' name='update_home_url' value='update' <?php if ( get_blog_option( $id, 'siteurl' ) == preg_replace('|/+$|', '', 'http://' . $details->domain . $details->path) || get_blog_option( $id, 'home' ) == preg_replace('|/+$|', '', 'http://' . $details->domain . $details->path) ) echo 'checked="checked"'; ?> /> <?php _e( "Update 'siteurl' and 'home' as well." ); ?></td>
+								<br /><input type='checkbox' style='width:20px;' name='update_home_url' value='update' <?php if ( get_blog_option( $id, 'siteurl' ) == untrailingslashit( get_blogaddress_by_id($id) ) || get_blog_option( $id, 'home' ) == untrailingslashit( get_blogaddress_by_id($id) ) ) echo 'checked="checked"'; ?> /> <?php _e( "Update 'siteurl' and 'home' as well." ); ?></td>
 							</tr>
 							<tr class="form-field">
 								<th scope="row"><?php _e('Registered') ?></th>
@@ -492,7 +492,7 @@
 									<?php
 									$actions	= array();
 									$actions[]	= '<a href="ms-sites.php?action=editblog&amp;id=' . $blog['blog_id'] . '" class="edit">' . __('Edit') . '</a>';
-									$actions[]	= "<a href='{$protocol}{$blog['domain']}{$blog['path']}wp-admin/' class='edit'>" . __('Backend') . '</a>';
+									$actions[]	= "<a href='" . get_admin_url($blog['blog_id']) . "' class='edit'>" . __('Backend') . '</a>';
 
 									if ( get_blog_status( $blog['blog_id'], "deleted" ) == '1' )
 										$actions[]	= '<a class="delete" href="ms-edit.php?action=confirm&amp;action2=activateblog&amp;ref=' . urlencode( $_SERVER['REQUEST_URI'] ) . '&amp;id=' . $blog['blog_id'] . '&amp;msg=' . urlencode( sprintf( __( "You are about to activate the blog %s" ), $blogname ) ) . '">' . __('Activate') . '</a>';
@@ -511,7 +511,7 @@
 
 									$actions[]	= '<a class="delete" href="ms-edit.php?action=confirm&amp;action2=deleteblog&amp;id=' . $blog['blog_id'] . '&amp;msg=' . urlencode( sprintf( __( "You are about to delete the blog %s" ), $blogname ) ) . '">' . __("Delete") . '</a>';
 
-									$actions[]	= "<a href='http://{$blog['domain']}{$blog['path']}' rel='permalink'>" . __('Visit') . '</a>';
+									$actions[]	= "<a href='" . get_home_url($blog['blog_id']) . "' rel='permalink'>" . __('Visit') . '</a>';
 									?>
 
 									<?php if ( count($actions) ) : ?>
@@ -544,7 +544,7 @@
 										$blogusers_warning = '';
 										if ( count( $blogusers ) > 5 ) {
 											$blogusers = array_slice( $blogusers, 0, 5 );
-											$blogusers_warning = __( 'Only showing first 5 users.' ) . ' <a href="' . $protocol . $blog[ 'domain' ] . $blog[ 'path' ] . 'wp-admin/users.php">' . __( 'More' ) . '</a>';
+											$blogusers_warning = __( 'Only showing first 5 users.' ) . ' <a href="' . get_admin_url($blog['blog_id'], 'users.php') . '">' . __( 'More' ) . '</a>';
 										}
 										foreach ( $blogusers as $key => $val )
 											echo '<a href="user-edit.php?user_id=' . $val->user_id . '">' . $val->user_login . '</a> ('.$val->user_email.')<br />';
Index: wp-admin/ms-options.php
===================================================================
--- wp-admin/ms-options.php	(revision 12938)
+++ wp-admin/ms-options.php	(working copy)
@@ -38,7 +38,7 @@
 			<tr valign="top">
 				<th scope="row"><?php _e('Site Admin Email') ?></th>
 				<td>
-					<input name="admin_email" type="text" id="admin_email" style="width: 95%" value="<?php echo esc_attr( stripslashes( get_site_option('admin_email') ) ) ?>" size="45" />
+					<input name="admin_email" type="text" id="admin_email" style="width: 95%" value="<?php echo esc_attr( get_site_option('admin_email') ) ?>" size="45" />
 					<br />
 					<?php printf( __( 'Registration and support mails will come from this address. Make it generic like "support@%s"' ), $current_site->domain ); ?>
 				</td>
