updates.
[silc.git] / apps / silc / client_ops.c
index c9a5743feb4af904c5bea1652819cf02ab8714a1..5be53ad958435f60b9e8498cf2d7db084ad25de6 100644 (file)
@@ -102,10 +102,11 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
     break;
 
   case SILC_NOTIFY_TYPE_INVITE:
+    (void)va_arg(vp, SilcChannelEntry);
+    tmp = va_arg(vp, char *);
     client_entry = va_arg(vp, SilcClientEntry);
-    channel_entry = va_arg(vp, SilcChannelEntry);
     snprintf(message, sizeof(message), "%s invites you to channel %s", 
-            client_entry->nickname, channel_entry->channel_name);
+            client_entry->nickname, tmp);
     break;
 
   case SILC_NOTIFY_TYPE_JOIN:
@@ -114,6 +115,20 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
     snprintf(message, sizeof(message), "%s (%s) has joined channel %s", 
             client_entry->nickname, client_entry->username, 
             channel_entry->channel_name);
+    if (client_entry == conn->local_entry) {
+      SilcChannelUser chu;
+
+      silc_list_start(channel_entry->clients);
+      while ((chu = silc_list_get(channel_entry->clients)) != SILC_LIST_END) {
+       if (chu->client == client_entry) {
+         if (app->screen->bottom_line->mode)
+           silc_free(app->screen->bottom_line->mode);
+         app->screen->bottom_line->mode = silc_client_chumode_char(chu->mode);
+         silc_screen_print_bottom_line(app->screen, 0);
+         break;
+       }
+      }
+    }
     break;
 
   case SILC_NOTIFY_TYPE_LEAVE:
@@ -168,10 +183,15 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
 
   case SILC_NOTIFY_TYPE_CMODE_CHANGE:
     client_entry = va_arg(vp, SilcClientEntry);
-    tmp = silc_client_chmode(va_arg(vp, unsigned int));
+    tmp_int = va_arg(vp, unsigned int);
+    (void)va_arg(vp, char *);
+    (void)va_arg(vp, char *);
     channel_entry = va_arg(vp, SilcChannelEntry);
+    
+    tmp = silc_client_chmode(tmp_int, channel_entry);
+    
     if (tmp)
-      snprintf(message, sizeof(message), "%s changed channel mode to +%s", 
+      snprintf(message, sizeof(message), "%s changed channel mode to +%s",
               client_entry->nickname, tmp);
     else
       snprintf(message, sizeof(message), "%s removed all channel modes", 
@@ -250,6 +270,25 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
     }
     break;
 
+  case SILC_NOTIFY_TYPE_KILLED:
+    client_entry = va_arg(vp, SilcClientEntry);
+    tmp = va_arg(vp, char *);
+    channel_entry = va_arg(vp, SilcChannelEntry);
+
+    if (client_entry == conn->local_entry) {
+      snprintf(message, sizeof(message), 
+              "You have been killed from the SILC Network %s%s%s", 
+              tmp ? "(" : "", tmp ? tmp : "", tmp ? ")" : "");
+    } else {
+      snprintf(message, sizeof(message), 
+              "%s%s%s has been killed from the SILC Network %s%s%s", 
+              client_entry->nickname, 
+              client_entry->server ? "@" : "",
+              client_entry->server ? client_entry->server : "",
+              tmp ? "(" : "", tmp ? tmp : "", tmp ? ")" : "");
+    }
+    break;
+
   default:
     break;
   }
@@ -277,6 +316,7 @@ void silc_command(SilcClient client, SilcClientConnection conn,
 
   switch(command)
     {
+       
     case SILC_COMMAND_QUIT:
       app->screen->bottom_line->channel = NULL;
       silc_screen_print_bottom_line(app->screen, 0);
@@ -314,6 +354,9 @@ void silc_client_show_users(SilcClient client,
   silc_list_start(channel->clients);
   while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
     char *m, *n = chu->client->nickname;
+    if (!n)
+      continue;
+
     len2 = strlen(n);
     len1 += len2;
     
@@ -365,13 +408,171 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn,
   SilcChannelUser chu;
   va_list vp;
 
-  if (!success)
-    return;
-
   va_start(vp, status);
 
   switch(command)
     {
+    case SILC_COMMAND_WHOIS:
+      {
+       char buf[1024], *nickname, *username, *realname;
+       int len;
+       unsigned int idle, mode;
+       SilcBuffer channels;
+
+       if (status == SILC_STATUS_ERR_NO_SUCH_NICK ||
+           status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
+         char *tmp;
+         tmp = silc_argument_get_arg_type(silc_command_get_args(cmd_payload),
+                                          3, NULL);
+         if (tmp)
+           client->ops->say(client, conn, "%s: %s", tmp,
+                            silc_client_command_status_message(status));
+         else
+           client->ops->say(client, conn, "%s",
+                            silc_client_command_status_message(status));
+         break;
+       }
+
+       if (!success)
+         return;
+
+       (void)va_arg(vp, SilcClientEntry);
+       nickname = va_arg(vp, char *);
+       username = va_arg(vp, char *);
+       realname = va_arg(vp, char *);
+       channels = va_arg(vp, SilcBuffer);
+       mode = va_arg(vp, unsigned int);
+       idle = va_arg(vp, unsigned int);
+
+       memset(buf, 0, sizeof(buf));
+
+       if (nickname) {
+         len = strlen(nickname);
+         strncat(buf, nickname, len);
+         strncat(buf, " is ", 4);
+       }
+       
+       if (username) {
+         strncat(buf, username, strlen(username));
+       }
+       
+       if (realname) {
+         strncat(buf, " (", 2);
+         strncat(buf, realname, strlen(realname));
+         strncat(buf, ")", 1);
+       }
+
+       client->ops->say(client, conn, "%s", buf);
+
+       if (channels) {
+         SilcDList list = silc_channel_payload_parse_list(channels);
+         if (list) {
+           SilcChannelPayload entry;
+
+           memset(buf, 0, sizeof(buf));
+           strcat(buf, "on channels: ");
+
+           silc_dlist_start(list);
+           while ((entry = silc_dlist_get(list)) != SILC_LIST_END) {
+             char *m = silc_client_chumode_char(silc_channel_get_mode(entry));
+             unsigned int name_len;
+             char *name = silc_channel_get_name(entry, &name_len);
+
+             if (m)
+               strncat(buf, m, strlen(m));
+             strncat(buf, name, name_len);
+             strncat(buf, " ", 1);
+             silc_free(m);
+           }
+
+           client->ops->say(client, conn, "%s", buf);
+           silc_channel_payload_list_free(list);
+         }
+       }
+
+       if (mode)
+         client->ops->say(client, conn, "%s is %s", nickname,
+                          (mode & SILC_UMODE_SERVER_OPERATOR) ?
+                          "Server Operator" :
+                          (mode & SILC_UMODE_ROUTER_OPERATOR) ?
+                          "SILC Operator" : "[Unknown mode]");
+
+       if (idle && nickname)
+         client->ops->say(client, conn, "%s has been idle %d %s",
+                          nickname,
+                          idle > 60 ? (idle / 60) : idle,
+                          idle > 60 ? "minutes" : "seconds");
+      }
+      break;
+
+    case SILC_COMMAND_WHOWAS:
+      {
+       char buf[1024], *nickname, *username, *realname;
+       int len;
+
+       if (status == SILC_STATUS_ERR_NO_SUCH_NICK ||
+           status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
+         char *tmp;
+         tmp = silc_argument_get_arg_type(silc_command_get_args(cmd_payload),
+                                          3, NULL);
+         if (tmp)
+           client->ops->say(client, conn, "%s: %s", tmp,
+                            silc_client_command_status_message(status));
+         else
+           client->ops->say(client, conn, "%s",
+                            silc_client_command_status_message(status));
+         break;
+       }
+
+       if (!success)
+         return;
+
+       (void)va_arg(vp, SilcClientEntry);
+       nickname = va_arg(vp, char *);
+       username = va_arg(vp, char *);
+       realname = va_arg(vp, char *);
+
+       memset(buf, 0, sizeof(buf));
+
+       if (nickname) {
+         len = strlen(nickname);
+         strncat(buf, nickname, len);
+         strncat(buf, " was ", 5);
+       }
+       
+       if (username) {
+         strncat(buf, username, strlen(nickname));
+       }
+       
+       if (realname) {
+         strncat(buf, " (", 2);
+         strncat(buf, realname, strlen(realname));
+         strncat(buf, ")", 1);
+       }
+
+       client->ops->say(client, conn, "%s", buf);
+      }
+      break;
+
+    case SILC_COMMAND_INVITE:
+      {
+       SilcChannelEntry channel;
+       char *invite_list;
+
+       if (!success)
+         return;
+       
+       channel = va_arg(vp, SilcChannelEntry);
+       invite_list = va_arg(vp, char *);
+
+       if (invite_list)
+         silc_say(client, conn, "%s invite list: %s", channel->channel_name,
+                  invite_list);
+       else
+         silc_say(client, conn, "%s invite list not set", 
+                  channel->channel_name);
+      }
+      break;
 
     case SILC_COMMAND_JOIN:
       {
@@ -381,6 +582,9 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn,
        unsigned int list_count;
        SilcChannelEntry channel;
 
+       if (!success)
+         return;
+
        app->screen->bottom_line->channel = va_arg(vp, char *);
        channel = va_arg(vp, SilcChannelEntry);
        mode = va_arg(vp, unsigned int);
@@ -397,7 +601,8 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn,
          client->ops->say(client, conn, "Topic for %s: %s", 
                           app->screen->bottom_line->channel, topic);
        
-       app->screen->bottom_line->channel_mode = silc_client_chmode(mode);
+       app->screen->bottom_line->channel_mode = 
+         silc_client_chmode(mode, channel);
        silc_screen_print_bottom_line(app->screen, 0);
 
        /* Resolve the client information */
@@ -411,6 +616,9 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn,
       {
        SilcClientEntry entry;
 
+       if (!success)
+         return;
+
        entry = va_arg(vp, SilcClientEntry);
        silc_say(client, conn, "Your current nickname is %s", entry->nickname);
        app->screen->bottom_line->nickname = entry->nickname;
@@ -418,20 +626,143 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn,
       }
       break;
 
+    case SILC_COMMAND_LIST:
+      {
+       char *topic, *name;
+       unsigned int usercount;
+       unsigned char buf[256], tmp[16];
+       int i, len;
+
+       if (!success)
+         return;
+
+       (void)va_arg(vp, SilcChannelEntry);
+       name = va_arg(vp, char *);
+       topic = va_arg(vp, char *);
+       usercount = va_arg(vp, unsigned int);
+
+       if (status == SILC_STATUS_LIST_START ||
+           status == SILC_STATUS_OK)
+         silc_say(client, conn, 
+         "  Channel                                  Users     Topic");
+
+       memset(buf, 0, sizeof(buf));
+       strncat(buf, "  ", 2);
+       len = strlen(name);
+       strncat(buf, name, len > 40 ? 40 : len);
+       if (len < 40)
+         for (i = 0; i < 40 - len; i++)
+           strcat(buf, " ");
+       strcat(buf, " ");
+
+       memset(tmp, 0, sizeof(tmp));
+       if (usercount) {
+         snprintf(tmp, sizeof(tmp), "%d", usercount);
+         strcat(buf, tmp);
+       }
+       len = strlen(tmp);
+       if (len < 10)
+         for (i = 0; i < 10 - len; i++)
+           strcat(buf, " ");
+       strcat(buf, " ");
+
+       if (topic) {
+         len = strlen(topic);
+         strncat(buf, topic, len);
+       }
+
+       silc_say(client, conn, "%s", buf);
+      }
+      break;
+
+    case SILC_COMMAND_UMODE:
+      {
+       unsigned int mode;
+
+       if (!success)
+         return;
+
+       mode = va_arg(vp, unsigned int);
+
+       if (!mode && app->screen->bottom_line->umode) {
+         silc_free(app->screen->bottom_line->umode);
+         app->screen->bottom_line->umode = NULL;
+       }
+
+       if (mode & SILC_UMODE_SERVER_OPERATOR) {
+         if (app->screen->bottom_line->umode)
+           silc_free(app->screen->bottom_line->umode);
+         app->screen->bottom_line->umode = strdup("Server Operator");;
+       }
+
+       if (mode & SILC_UMODE_ROUTER_OPERATOR) {
+         if (app->screen->bottom_line->umode)
+           silc_free(app->screen->bottom_line->umode);
+         app->screen->bottom_line->umode = strdup("SILC Operator");;
+       }
+
+       silc_screen_print_bottom_line(app->screen, 0);
+      }
+      break;
+
+    case SILC_COMMAND_OPER:
+      if (status == SILC_STATUS_OK) {
+       conn->local_entry->mode |= SILC_UMODE_SERVER_OPERATOR;
+       if (app->screen->bottom_line->umode)
+         silc_free(app->screen->bottom_line->umode);
+       app->screen->bottom_line->umode = strdup("Server Operator");;
+       silc_screen_print_bottom_line(app->screen, 0);
+      }
+      break;
+
+    case SILC_COMMAND_SILCOPER:
+      if (status == SILC_STATUS_OK) {
+       conn->local_entry->mode |= SILC_UMODE_ROUTER_OPERATOR;
+       if (app->screen->bottom_line->umode)
+         silc_free(app->screen->bottom_line->umode);
+       app->screen->bottom_line->umode = strdup("SILC Operator");;
+       silc_screen_print_bottom_line(app->screen, 0);
+      }
+      break;
+
     case SILC_COMMAND_USERS:
+      if (!success)
+       return;
+
       silc_list_start(conn->current_channel->clients);
       while ((chu = silc_list_get(conn->current_channel->clients)) 
             != SILC_LIST_END) {
        if (chu->client == conn->local_entry) {
          if (app->screen->bottom_line->mode)
            silc_free(app->screen->bottom_line->mode);
-         app->screen->bottom_line->mode = 
-           silc_client_chumode_char(chu->mode);
+         app->screen->bottom_line->mode = silc_client_chumode_char(chu->mode);
          silc_screen_print_bottom_line(app->screen, 0);
          break;
        }
+      }
       break;
+
+    case SILC_COMMAND_BAN:
+      {
+       SilcChannelEntry channel;
+       char *ban_list;
+
+       if (!success)
+         return;
+       
+       channel = va_arg(vp, SilcChannelEntry);
+       ban_list = va_arg(vp, char *);
+
+       if (ban_list)
+         silc_say(client, conn, "%s ban list: %s", channel->channel_name,
+                  ban_list);
+       else
+         silc_say(client, conn, "%s ban list not set", channel->channel_name);
       }
+      break;
+
+    default:
+      break;
     }
 }
 
@@ -684,7 +1015,11 @@ int silc_get_auth_method(SilcClient client, SilcClientConnection conn,
     }
   }
 
-  return FALSE;
+  *auth_meth = SILC_AUTH_NONE;
+  *auth_data = NULL;
+  *auth_data_len = 0;
+
+  return TRUE;
 }
 
 /* Notifies application that failure packet was received.  This is called