Index: drupal-6.x-dev/install.php
===================================================================
RCS file: /cvs/drupal/drupal/install.php,v
retrieving revision 1.85
diff -u -p -r1.85 install.php
--- drupal-6.x-dev/install.php	31 Oct 2007 16:14:15 -0000	1.85
+++ drupal-6.x-dev/install.php	3 Nov 2007 04:18:17 -0000
@@ -887,7 +887,14 @@ function install_configure_form() {
   $form['admin_account']['account']['name'] = array('#type' => 'textfield',
     '#title' => st('Username'),
     '#maxlength' => USERNAME_MAX_LENGTH,
-    '#description' => st('Spaces are allowed; punctuation is not allowed except for periods, hyphens, and underscores.'),
+    '#description' => st('Lower case characters only. Only syntax with vaild e-mail local-part or complete e-mail address are allowed. See <a href="@rfc">RFC 2822</a> for details.', array('@rfc' => 'http://tools.ietf.org/html/rfc2822')),
+    '#required' => TRUE,
+    '#weight' => -15,
+  );
+  $form['admin_account']['account']['fullname'] = array('#type' => 'textfield',
+    '#title' => st('Full name'),
+    '#maxlength' => FULLNAME_MAX_LENGTH,
+    '#description' => st('Specify your first and last name.'),
     '#required' => TRUE,
     '#weight' => -10,
   );
@@ -961,6 +968,9 @@ function install_configure_form_validate
   if ($error = user_validate_name($form_state['values']['account']['name'])) {
     form_error($form['admin_account']['account']['name'], $error);
   }
+  if ($error = user_validate_fullname($form_state['values']['account']['fullname'])) {
+    form_error($form['admin_account']['account']['fullname'], $error);
+  }
   if ($error = user_validate_mail($form_state['values']['account']['mail'])) {
     form_error($form['admin_account']['account']['mail'], $error);
   }
Index: drupal-6.x-dev/modules/comment/comment.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v
retrieving revision 1.597
diff -u -p -r1.597 comment.module
--- drupal-6.x-dev/modules/comment/comment.module	31 Oct 2007 17:50:47 -0000	1.597
+++ drupal-6.x-dev/modules/comment/comment.module	3 Nov 2007 04:18:17 -0000
@@ -1132,7 +1132,7 @@ function comment_validate($edit) {
     $node = node_load($edit['nid']);
     if (variable_get('comment_anonymous_'. $node->type, COMMENT_ANONYMOUS_MAYNOT_CONTACT) > COMMENT_ANONYMOUS_MAYNOT_CONTACT) {
       if ($edit['name']) {
-        $taken = db_result(db_query("SELECT COUNT(uid) FROM {users} WHERE LOWER(name) = '%s'", $edit['name']));
+        $taken = db_result(db_query("SELECT COUNT(uid) FROM {users} WHERE name = '%s'", strtolower($edit['name'])));
 
         if ($taken != 0) {
           form_set_error('name', t('The name you used belongs to a registered user.'));
Index: drupal-6.x-dev/modules/system/system.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.install,v
retrieving revision 1.167
diff -u -p -r1.167 system.install
--- drupal-6.x-dev/modules/system/system.install	25 Oct 2007 20:41:16 -0000	1.167
+++ drupal-6.x-dev/modules/system/system.install	3 Nov 2007 04:18:19 -0000
@@ -251,7 +251,7 @@ function system_install() {
   // presumed to be a serialized array. Install will change uid 1 immediately
   // anyways. So we insert the superuser here, the uid is 2 here for now, but
   // very soon it will be changed to 1.
-  db_query("INSERT INTO {users} (name, mail, created, data) VALUES('%s', '%s', %d, '%s')", 'placeholder-for-uid-1', 'placeholder-for-uid-1', time(), serialize(array()));
+  db_query("INSERT INTO {users} (name, fullname, mail, created, data) VALUES('%s', '%s', '%s', %d, '%s')", 'placeholder-for-uid-1', 'placeholder-for-uid-1', 'placeholder-for-uid-1', time(), serialize(array()));
   // This sets the above two users to 1 -1 = 0 (anonymous) and
   // 2- 1 = 1 (superuser). We skip uid 2 but that's not a big problem.
   db_query('UPDATE {users} SET uid = uid - 1');
Index: drupal-6.x-dev/modules/user/user.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.install,v
retrieving revision 1.2
diff -u -p -r1.2 user.install
--- drupal-6.x-dev/modules/user/user.install	10 Oct 2007 11:39:35 -0000	1.2
+++ drupal-6.x-dev/modules/user/user.install	3 Nov 2007 04:18:19 -0000
@@ -142,6 +142,13 @@ function user_schema() {
         'default' => '',
         'description' => t('Unique user name.'),
       ),
+      'fullname' => array(
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+        'description' => t('User full name.'),
+      ),
       'pass' => array(
         'type' => 'varchar',
         'length' => 32,
@@ -282,3 +289,18 @@ function user_schema() {
   return $schema;
 }
 
+/**
+ * Add a fullname field to users table, folk from name, and convert all stored
+ * name to lower case.
+ *
+ * NOTE: We ONLY convert name to lower during update, but not handle the
+ *       convert of invalid characters, or else user will not able to login
+ *       again.
+ */
+function user_update_6000() {
+  $ret = array();
+  db_add_field($ret, 'users', 'fullname', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', 'description' => t('User full name.')));
+  $ret[] = update_sql('UPDATE {users} SET fullname = name');
+  $ret[] = update_sql('UPDATE {users} SET name = LOWER(name)');
+  return $ret;
+}
Index: drupal-6.x-dev/modules/user/user.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.module,v
retrieving revision 1.857
diff -u -p -r1.857 user.module
--- drupal-6.x-dev/modules/user/user.module	27 Oct 2007 14:01:12 -0000	1.857
+++ drupal-6.x-dev/modules/user/user.module	3 Nov 2007 04:18:19 -0000
@@ -7,6 +7,7 @@
  */
 
 define('USERNAME_MAX_LENGTH', 60);
+define('FULLNAME_MAX_LENGTH', 255);
 define('EMAIL_MAX_LENGTH', 64);
 
 /**
@@ -144,17 +145,23 @@ function user_load($array = array()) {
   }
 
   foreach ($array as $key => $value) {
-    if ($key == 'uid' || $key == 'status') {
-      $query[] = "$key = %d";
-      $params[] = $value;
-    }
-    else if ($key == 'pass') {
-      $query[] = "pass = '%s'";
-      $params[] = md5($value);
-    }
-    else {
-      $query[]= "LOWER($key) = LOWER('%s')";
-      $params[] = $value;
+    switch ($key) {
+      case 'uid':
+      case 'status':
+        $query[] = "$key = %d";
+        $params[] = $value;
+        break;
+      case 'pass':
+        $query[] = "pass = '%s'";
+        $params[] = md5($value);
+        break;
+      case 'name':
+        $query[]= "$key = '%s'";
+        $params[] = strtolower($value);
+        break;
+      default:
+        $query[]= "LOWER($key) = LOWER('%s')";
+        $params[] = $value;
     }
   }
   $result = db_query('SELECT * FROM {users} u WHERE '. implode(' AND ', $query), $params);
@@ -204,6 +211,10 @@ function user_save($account, $array = ar
     $query = '';
     $data = unserialize(db_result(db_query('SELECT data FROM {users} WHERE uid = %d', $account->uid)));
     foreach ($array as $key => $value) {
+      // Always format username as lower case.
+      if ($key == 'name') {
+        $value = strtolower($value);
+      }
       if ($key == 'pass' && !empty($value)) {
         $query .= "$key = '%s', ";
         $v[] = md5($value);
@@ -287,6 +298,11 @@ function user_save($account, $array = ar
           $values[] = $value;
           $s[] = "%d";
           break;
+        case 'name':
+          $fields[] = $key;
+          $values[] = strtolower($value);
+          $s[] = "'%s'";
+          break;
         default:
           if (substr($key, 0, 4) !== 'auth' && in_array($key, $user_fields)) {
             $fields[] = $key;
@@ -345,27 +361,21 @@ function user_save($account, $array = ar
  * Verify the syntax of the given name.
  */
 function user_validate_name($name) {
+  $user = '[a-zA-Z0-9_\-\.\+\^!#\$%&*+\/\=\?\`\|\{\}~\']+';
+  $domain = '(?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.?)+';
   if (!strlen($name)) return t('You must enter a username.');
-  if (substr($name, 0, 1) == ' ') return t('The username cannot begin with a space.');
-  if (substr($name, -1) == ' ') return t('The username cannot end with a space.');
-  if (strpos($name, '  ') !== FALSE) return t('The username cannot contain multiple spaces in a row.');
-  if (ereg("[^\x80-\xF7 [:alnum:]@_.-]", $name)) return t('The username contains an illegal character.');
-  if (preg_match('/[\x{80}-\x{A0}'.          // Non-printable ISO-8859-1 + NBSP
-                   '\x{AD}'.                 // Soft-hyphen
-                   '\x{2000}-\x{200F}'.      // Various space characters
-                   '\x{2028}-\x{202F}'.      // Bidirectional text overrides
-                   '\x{205F}-\x{206F}'.      // Various text hinting characters
-                   '\x{FEFF}'.               // Byte order mark
-                   '\x{FF01}-\x{FF60}'.      // Full-width latin
-                   '\x{FFF9}-\x{FFFD}'.      // Replacement characters
-                   '\x{0}]/u',               // NULL byte
-                   $name)) {
-    return t('The username contains an illegal character.');
-  }
-  if (strpos($name, '@') !== FALSE && !eregi('@([0-9a-z](-?[0-9a-z])*.)+[a-z]{2}([zmuvtg]|fo|me)?$', $name)) return t('The username is not a valid authentication ID.');
+  if (!preg_match("/^($user|$user@$domain)$/", $name)) return t('The username %name contains an illegal character.', array('%name' => $name));
   if (strlen($name) > USERNAME_MAX_LENGTH) return t('The username %name is too long: it must be %max characters or less.', array('%name' => $name, '%max' => USERNAME_MAX_LENGTH));
 }
 
+/**
+ * Verify the syntax of the given full name.
+ */
+function user_validate_fullname($fullname) {
+  if (!strlen($fullname)) return t('You must enter a full name.');
+  if (strlen($fullname) > FULLNAME_MAX_LENGTH) return t('The full name %fullname is too long: it must be %max characters or less.', array('%fullname' => $name, '%max' => FULLNAME_MAX_LENGTH));
+}
+
 function user_validate_mail($mail) {
   if (!$mail) return t('You must enter an e-mail address.');
   if (!valid_email_address($mail)) {
@@ -471,7 +481,7 @@ function user_access($string, $account =
  * @return boolean TRUE for blocked users, FALSE for active
  */
 function user_is_blocked($name) {
-  $deny  = db_fetch_object(db_query("SELECT name FROM {users} WHERE status = 0 AND name = LOWER('%s')", $name));
+  $deny  = db_fetch_object(db_query("SELECT name FROM {users} WHERE status = 0 AND name = '%s'", $name));
 
   return $deny;
 }
@@ -528,13 +538,13 @@ function user_search($op = 'search', $ke
         $keys = preg_replace('!\*+!', '%', $keys);
         if (user_access('administer users')) {
           // Administrators can also search in the otherwise private email field.
-          $result = pager_query("SELECT name, uid, mail FROM {users} WHERE LOWER(name) LIKE LOWER('%%%s%%') OR LOWER(mail) LIKE LOWER('%%%s%%')", 15, 0, NULL, $keys, $keys);
+          $result = pager_query("SELECT name, uid, mail FROM {users} WHERE name LIKE '%%%s%%' OR mail LIKE '%%%s%%'", 15, 0, NULL, strtolower($keys), strtolower($keys));
           while ($account = db_fetch_object($result)) {
             $find[] = array('title' => $account->name .' ('. $account->mail .')', 'link' => url('user/'. $account->uid, array('absolute' => TRUE)));
           }
         }
         else {
-          $result = pager_query("SELECT name, uid FROM {users} WHERE LOWER(name) LIKE LOWER('%%%s%%')", 15, 0, NULL, $keys);
+          $result = pager_query("SELECT name, uid FROM {users} WHERE name LIKE '%%%s%%'", 15, 0, NULL, strtolower($keys));
           while ($account = db_fetch_object($result)) {
             $find[] = array('title' => $account->name, 'link' => url('user/'. $account->uid, array('absolute' => TRUE)));
           }
@@ -688,7 +698,7 @@ function user_block($op = 'list', $delta
 
       case 1:
         if ($menu = menu_tree()) {
-           $block['subject'] = $user->uid ? check_plain($user->name) : t('Navigation');
+           $block['subject'] = $user->uid ? check_plain($user->fullname) : t('Navigation');
            $block['content'] = $menu;
         }
         return $block;
@@ -1283,10 +1293,17 @@ function user_edit_form(&$form_state, $u
       '#title' => t('Username'),
       '#default_value' => $edit['name'],
       '#maxlength' => USERNAME_MAX_LENGTH,
-      '#description' => t('Your preferred username; punctuation is not allowed except for periods, hyphens, and underscores.'),
+      '#description' => t('Your preferred username. Lower case characters only. Only syntax with vaild e-mail local-part or complete e-mail address are allowed. See <a href="@rfc">RFC 2822</a> for details.', array('@rfc' => 'http://tools.ietf.org/html/rfc2822')),
       '#required' => TRUE,
     );
   }
+  $form['account']['fullname'] = array('#type' => 'textfield',
+    '#title' => t('Full name'),
+    '#default_value' => $edit['fullname'],
+    '#maxlength' => USERNAME_MAX_LENGTH,
+    '#description' => t('Specify your first and last name.'),
+    '#required' => TRUE,
+  );
   $form['account']['mail'] = array('#type' => 'textfield',
     '#title' => t('E-mail address'),
     '#default_value' => $edit['mail'],
@@ -1361,7 +1378,7 @@ function _user_edit_validate($uid, &$edi
     if ($error = user_validate_name($edit['name'])) {
       form_set_error('name', $error);
     }
-    else if (db_result(db_query("SELECT COUNT(*) FROM {users} WHERE uid != %d AND LOWER(name) = LOWER('%s')", $uid, $edit['name'])) > 0) {
+    else if (db_result(db_query("SELECT COUNT(*) FROM {users} WHERE uid != %d AND name = '%s'", $uid, strtolower($edit['name']))) > 0) {
       form_set_error('name', t('The name %name is already taken.', array('%name' => $edit['name'])));
     }
     else if (drupal_is_denied('user', $edit['name'])) {
@@ -1369,11 +1386,16 @@ function _user_edit_validate($uid, &$edi
     }
   }
 
+  // Validate the full name:
+  if ($error = user_validate_fullname($edit['fullname'])) {
+    form_set_error('fullname', $error);
+  }
+
   // Validate the e-mail address:
   if ($error = user_validate_mail($edit['mail'])) {
     form_set_error('mail', $error);
   }
-  else if (db_result(db_query("SELECT COUNT(*) FROM {users} WHERE uid != %d AND LOWER(mail) = LOWER('%s')", $uid, $edit['mail'])) > 0) {
+  else if (db_result(db_query("SELECT COUNT(*) FROM {users} WHERE uid != %d AND mail = '%s'", $uid, strtolower($edit['mail']))) > 0) {
     form_set_error('mail', t('The e-mail address %email is already registered. <a href="@password">Have you forgotten your password?</a>', array('%email' => $edit['mail'], '@password' => url('user/password'))));
   }
   else if (drupal_is_denied('mail', $edit['mail'])) {
@@ -2196,7 +2218,7 @@ function user_register() {
 
   // Remove form_group around default fields if there are no other groups.
   if (!$extra) {
-    foreach (array('name', 'mail', 'pass', 'status', 'roles', 'notify') as $key) {
+    foreach (array('name', 'fullname', 'mail', 'pass', 'status', 'roles', 'notify') as $key) {
       if (isset($form['account'][$key])) {
         $form[$key] = $form['account'][$key];
       }
Index: drupal-6.x-dev/modules/user/user.pages.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.pages.inc,v
retrieving revision 1.3
diff -u -p -r1.3 user.pages.inc
--- drupal-6.x-dev/modules/user/user.pages.inc	27 Oct 2007 14:01:12 -0000	1.3
+++ drupal-6.x-dev/modules/user/user.pages.inc	3 Nov 2007 04:18:20 -0000
@@ -12,7 +12,7 @@
 function user_autocomplete($string = '') {
   $matches = array();
   if ($string) {
-    $result = db_query_range("SELECT name FROM {users} WHERE LOWER(name) LIKE LOWER('%s%%')", $string, 0, 10);
+    $result = db_query_range("SELECT name FROM {users} WHERE name LIKE '%s%%'", strtolower($string), 0, 10);
     while ($user = db_fetch_object($result)) {
       $matches[$user->name] = check_plain($user->name);
     }
@@ -150,7 +150,7 @@ function user_logout() {
  * Menu callback; Displays a user or user profile page.
  */
 function user_view($account) {
-  drupal_set_title(check_plain($account->name));
+  drupal_set_title(check_plain($account->fullname));
   // Retrieve all profile fields and attach to $account->content.
   user_build_content($account);
   /**
@@ -222,7 +222,7 @@ function template_preprocess_user_profil
  * @see user_edit_submit().
  */
 function user_edit($account, $category = 'account') {
-  drupal_set_title(check_plain($account->name));
+  drupal_set_title(check_plain($account->fullname));
   return drupal_get_form('user_profile_form', $account, $category);
 }
 
