Nickname formatting/parsing rewrite.
[silc.git] / lib / silcclient / client_notify.c
index fd8deeb074a571383960dd9470e7d83595ccb663..a8bdf31a69d67776ac394ddc961ab31464f94e89 100644 (file)
@@ -95,21 +95,21 @@ SILC_FSM_STATE(silc_client_notify)
   if (!payload) {
     SILC_LOG_DEBUG(("Malformed notify payload"));
     silc_packet_free(packet);
-    return SILC_FSM_FINISH;
+    SILC_FSM_FINISH;
   }
 
   if (!silc_notify_get_args(payload)) {
-    SILC_LOG_DEBUG(("Malformed notify"));
+    SILC_LOG_DEBUG(("Malformed notify %d", silc_notify_get_type(payload)));
     silc_notify_payload_free(payload);
     silc_packet_free(packet);
-    return SILC_FSM_FINISH;
+    SILC_FSM_FINISH;
   }
 
   notify = silc_calloc(1, sizeof(*notify));
   if (!notify) {
     silc_notify_payload_free(payload);
     silc_packet_free(packet);
-    return SILC_FSM_FINISH;
+    SILC_FSM_FINISH;
   }
 
   /* Save notify payload to packet context during processing */
@@ -206,11 +206,11 @@ SILC_FSM_STATE(silc_client_notify)
     silc_notify_payload_free(payload);
     silc_packet_free(packet);
     silc_free(notify);
-    return SILC_FSM_FINISH;
+    SILC_FSM_FINISH;
     break;
   }
 
-  return SILC_FSM_YIELD;
+  SILC_FSM_YIELD;
 }
 
 /* Notify processed, finish the packet processing thread */
@@ -224,7 +224,7 @@ SILC_FSM_STATE(silc_client_notify_processed)
   silc_notify_payload_free(payload);
   silc_packet_free(packet);
   silc_free(notify);
-  return SILC_FSM_FINISH;
+  SILC_FSM_FINISH;
 }
 
 /********************************** NONE ************************************/
@@ -245,7 +245,7 @@ SILC_FSM_STATE(silc_client_notify_none)
 
   /** Notify processed */
   silc_fsm_next(fsm, silc_client_notify_processed);
-  return SILC_FSM_CONTINUE;
+  SILC_FSM_CONTINUE;
 }
 
 /********************************* INVITE ***********************************/
@@ -318,7 +318,7 @@ SILC_FSM_STATE(silc_client_notify_invite)
   /** Notify processed */
   silc_client_unref_channel(client, conn, channel);
   silc_fsm_next(fsm, silc_client_notify_processed);
-  return SILC_FSM_CONTINUE;
+  SILC_FSM_CONTINUE;
 }
 
 /********************************** JOIN ************************************/
@@ -379,7 +379,7 @@ SILC_FSM_STATE(silc_client_notify_join)
   }
 
   if (client_entry != conn->local_entry)
-    silc_client_nickname_format(client, conn, client_entry);
+    silc_client_nickname_format(client, conn, client_entry, FALSE);
 
   /* Join the client to channel */
   if (!silc_client_add_to_channel(client, conn, channel, client_entry, 0))
@@ -394,7 +394,7 @@ SILC_FSM_STATE(silc_client_notify_join)
   /** Notify processed */
   silc_client_unref_channel(client, conn, channel);
   silc_fsm_next(fsm, silc_client_notify_processed);
-  return SILC_FSM_CONTINUE;
+  SILC_FSM_CONTINUE;
 }
 
 /********************************** LEAVE ***********************************/
@@ -456,7 +456,7 @@ SILC_FSM_STATE(silc_client_notify_leave)
   /** Notify processed */
   silc_client_unref_channel(client, conn, channel);
   silc_fsm_next(fsm, silc_client_notify_processed);
-  return SILC_FSM_CONTINUE;
+  SILC_FSM_CONTINUE;
 }
 
 /********************************* SIGNOFF **********************************/
@@ -489,20 +489,21 @@ SILC_FSM_STATE(silc_client_notify_signoff)
 
   /* Get signoff message */
   tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
-  if (tmp_len > 128)
+  if (tmp && tmp_len > 128)
     tmp[128] = '\0';
 
   /* Notify application */
   NOTIFY(client, conn, type, client_entry, tmp);
 
   /* Delete client */
+  silc_client_remove_from_channels(client, conn, client_entry);
   silc_client_del_client(client, conn, client_entry);
   silc_client_unref_client(client, conn, client_entry);
 
  out:
   /** Notify processed */
   silc_fsm_next(fsm, silc_client_notify_processed);
-  return SILC_FSM_CONTINUE;
+  SILC_FSM_CONTINUE;
 }
 
 /******************************** TOPIC_SET *********************************/
@@ -619,7 +620,7 @@ SILC_FSM_STATE(silc_client_notify_topic_set)
   /** Notify processed */
   silc_client_unref_channel(client, conn, channel);
   silc_fsm_next(fsm, silc_client_notify_processed);
-  return SILC_FSM_CONTINUE;
+  SILC_FSM_CONTINUE;
 }
 
 /****************************** NICK_CHANGE *********************************/
@@ -635,7 +636,7 @@ SILC_FSM_STATE(silc_client_notify_nick_change)
   SilcNotifyType type = silc_notify_get_type(payload);
   SilcArgumentPayload args = silc_notify_get_args(payload);
   SilcClientEntry client_entry = NULL;
-  unsigned char *tmp, *nick, oldnick[128 + 1];
+  unsigned char *tmp, oldnick[128 + 1];
   SilcUInt32 tmp_len;
   SilcID id, id2;
 
@@ -690,24 +691,11 @@ SILC_FSM_STATE(silc_client_notify_nick_change)
     goto out;
   }
 
-  /* Normalize nickname */
-  nick = silc_identifier_check(tmp, tmp_len, SILC_STRING_UTF8, 128, NULL);
-  if (!nick)
-    goto out;
-
-  /* Update nickname */
-  silc_mutex_lock(conn->internal->lock);
-  if (!silc_idcache_update_by_context(conn->internal->client_cache,
-                                     client_entry, NULL, nick, TRUE)) {
-    silc_free(nick);
-    silc_mutex_unlock(conn->internal->lock);
-    goto out;
-  }
-  silc_mutex_unlock(conn->internal->lock);
+  /* Change the nickname */
   memcpy(oldnick, client_entry->nickname, sizeof(client_entry->nickname));
-  memcpy(client_entry->nickname, tmp, tmp_len);
-  client_entry->nickname_normalized = nick;
-  silc_client_nickname_format(client, conn, client_entry);
+  if (!silc_client_change_nickname(client, conn, client_entry, tmp,
+                                  &id2.u.client_id, NULL, 0))
+    goto out;
 
   /* Notify application */
   NOTIFY(client, conn, type, client_entry, client_entry->nickname, oldnick);
@@ -716,7 +704,7 @@ SILC_FSM_STATE(silc_client_notify_nick_change)
   /** Notify processed */
   silc_client_unref_client(client, conn, client_entry);
   silc_fsm_next(fsm, silc_client_notify_processed);
-  return SILC_FSM_CONTINUE;
+  SILC_FSM_CONTINUE;
 }
 
 /****************************** CMODE_CHANGE ********************************/
@@ -875,6 +863,8 @@ SILC_FSM_STATE(silc_client_notify_cmode_change)
     chpks = silc_argument_list_parse_decoded(tmp, tmp_len,
                                             SILC_ARGUMENT_PUBLIC_KEY);
 
+  /* XXX add to/remove from channel pubkeys channel->channel_pubkeys */
+
   /* Notify application. */
   NOTIFY(client, conn, type, id.type, entry, mode, cipher, hmac,
         passphrase, channel->founder_key, chpks, channel);
@@ -894,7 +884,7 @@ SILC_FSM_STATE(silc_client_notify_cmode_change)
 
   /** Notify processed */
   silc_fsm_next(fsm, silc_client_notify_processed);
-  return SILC_FSM_CONTINUE;
+  SILC_FSM_CONTINUE;
 }
 
 /***************************** CUMODE_CHANGE ********************************/
@@ -1032,7 +1022,7 @@ SILC_FSM_STATE(silc_client_notify_cumode_change)
 
   /** Notify processed */
   silc_fsm_next(fsm, silc_client_notify_processed);
-  return SILC_FSM_CONTINUE;
+  SILC_FSM_CONTINUE;
 }
 
 /********************************* MOTD *************************************/
@@ -1063,7 +1053,7 @@ SILC_FSM_STATE(silc_client_notify_motd)
  out:
   /** Notify processed */
   silc_fsm_next(fsm, silc_client_notify_processed);
-  return SILC_FSM_CONTINUE;
+  SILC_FSM_CONTINUE;
 }
 
 /**************************** CHANNEL CHANGE ********************************/
@@ -1118,7 +1108,7 @@ SILC_FSM_STATE(silc_client_notify_channel_change)
   /** Notify processed */
   silc_client_unref_channel(client, conn, channel);
   silc_fsm_next(fsm, silc_client_notify_processed);
-  return SILC_FSM_CONTINUE;
+  SILC_FSM_CONTINUE;
 }
 
 /******************************** KICKED ************************************/
@@ -1136,7 +1126,6 @@ SILC_FSM_STATE(silc_client_notify_kicked)
   SilcArgumentPayload args = silc_notify_get_args(payload);
   SilcClientEntry client_entry, client_entry2;
   SilcChannelEntry channel = NULL;
-  SilcChannelUser chu;
   unsigned char *tmp;
   SilcUInt32 tmp_len;
   SilcID id;
@@ -1194,14 +1183,8 @@ SILC_FSM_STATE(silc_client_notify_kicked)
   tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
 
   /* Remove kicked client from channel */
-  if (client_entry != conn->local_entry) {
-    chu = silc_client_on_channel(channel, client_entry);
-    if (chu) {
-      silc_hash_table_del(client_entry->channels, channel);
-      silc_hash_table_del(channel->user_list, client_entry);
-      silc_free(chu);
-    }
-  }
+  if (client_entry != conn->local_entry)
+    silc_client_remove_from_channel(client, conn, channel, client_entry);
 
   /* Notify application. */
   NOTIFY(client, conn, type, client_entry, tmp, client_entry2, channel);
@@ -1210,6 +1193,7 @@ SILC_FSM_STATE(silc_client_notify_kicked)
   if (client_entry == conn->local_entry) {
     if (conn->current_channel == channel)
       conn->current_channel = NULL;
+    silc_client_empty_channel(client, conn, channel);
     silc_client_del_channel(client, conn, channel);
   }
 
@@ -1220,7 +1204,7 @@ SILC_FSM_STATE(silc_client_notify_kicked)
   /** Notify processed */
   silc_client_unref_channel(client, conn, channel);
   silc_fsm_next(fsm, silc_client_notify_processed);
-  return SILC_FSM_CONTINUE;
+  SILC_FSM_CONTINUE;
 }
 
 /******************************** KILLED ************************************/
@@ -1307,8 +1291,10 @@ SILC_FSM_STATE(silc_client_notify_killed)
   NOTIFY(client, conn, type, client_entry, comment, id.type, entry);
 
   /* Delete the killed client */
-  if (client_entry != conn->local_entry)
+  if (client_entry != conn->local_entry) {
+    silc_client_remove_from_channels(client, conn, client_entry);
     silc_client_del_client(client, conn, client_entry);
+  }
 
  out:
   silc_client_unref_client(client, conn, client_entry);
@@ -1321,7 +1307,7 @@ SILC_FSM_STATE(silc_client_notify_killed)
 
   /** Notify processed */
   silc_fsm_next(fsm, silc_client_notify_processed);
-  return SILC_FSM_CONTINUE;
+  SILC_FSM_CONTINUE;
 }
 
 /**************************** SERVER SIGNOFF ********************************/
@@ -1341,7 +1327,7 @@ SILC_FSM_STATE(silc_client_notify_server_signoff)
   SilcID id;
   int i;
 
-  SILC_LOG_DEBUG(("Notify: SIGNOFF"));
+  SILC_LOG_DEBUG(("Notify: SERVER_SIGNOFF"));
 
   clients = silc_dlist_init();
   if (!clients)
@@ -1364,14 +1350,16 @@ SILC_FSM_STATE(silc_client_notify_server_signoff)
 
   /* Delete the clients */
   silc_dlist_start(clients);
-  while ((client_entry = silc_dlist_get(clients)))
+  while ((client_entry = silc_dlist_get(clients))) {
+    silc_client_remove_from_channels(client, conn, client_entry);
     silc_client_del_client(client, conn, client_entry);
+  }
 
  out:
   /** Notify processed */
   silc_client_list_free(client, conn, clients);
   silc_fsm_next(fsm, silc_client_notify_processed);
-  return SILC_FSM_CONTINUE;
+  SILC_FSM_CONTINUE;
 }
 
 /******************************** ERROR *************************************/
@@ -1406,6 +1394,7 @@ SILC_FSM_STATE(silc_client_notify_error)
       goto out;
     client_entry = silc_client_get_client_by_id(client, conn, &id.u.client_id);
     if (client_entry) {
+      silc_client_remove_from_channels(client, conn, client_entry);
       silc_client_del_client(client, conn, client_entry);
       silc_client_unref_client(client, conn, client_entry);
     }
@@ -1417,7 +1406,7 @@ SILC_FSM_STATE(silc_client_notify_error)
  out:
   /** Notify processed */
   silc_fsm_next(fsm, silc_client_notify_processed);
-  return SILC_FSM_CONTINUE;
+  SILC_FSM_CONTINUE;
 }
 
 /******************************** WATCH *************************************/
@@ -1476,11 +1465,8 @@ SILC_FSM_STATE(silc_client_notify_watch)
   if (tmp) {
     char *tmp_nick = NULL;
 
-    if (client->internal->params->nickname_parse)
-      client->internal->params->nickname_parse(client_entry->nickname,
-                                              &tmp_nick);
-    else
-      tmp_nick = strdup(tmp);
+    silc_client_nickname_parse(client, conn, client_entry->nickname,
+                              &tmp_nick);
 
     /* If same nick, the client was new to us and has become "present"
        to network.  Send NULL as nick to application. */
@@ -1516,8 +1502,10 @@ SILC_FSM_STATE(silc_client_notify_watch)
           ntype == SILC_NOTIFY_TYPE_KILLED)
     del_client = TRUE;
 
-  if (del_client)
+  if (del_client) {
+    silc_client_remove_from_channels(client, conn, client_entry);
     silc_client_del_client(client, conn, client_entry);
+  }
 
   if (public_key)
     silc_pkcs_public_key_free(public_key);
@@ -1526,5 +1514,5 @@ SILC_FSM_STATE(silc_client_notify_watch)
   /** Notify processed */
   silc_client_unref_client(client, conn, client_entry);
   silc_fsm_next(fsm, silc_client_notify_processed);
-  return SILC_FSM_CONTINUE;
+  SILC_FSM_CONTINUE;
 }