updates.
authorPekka Riikonen <priikone@silcnet.org>
Fri, 25 May 2001 14:45:10 +0000 (14:45 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Fri, 25 May 2001 14:45:10 +0000 (14:45 +0000)
12 files changed:
apps/irssi/configure.in
apps/irssi/src/silc/core/silc-core.c
apps/irssi/src/silc/core/silc-nicklist.c
apps/irssi/src/silc/core/silc-queries.c
apps/irssi/src/silc/core/silc-queries.h
apps/irssi/src/silc/core/silc-servers.c
apps/irssi/src/silc/core/silc-servers.h
apps/silc/client_ops.c
lib/silcclient/command.c
lib/silcclient/command_reply.c
lib/silcclient/idlist.c
lib/silcclient/idlist.h

index ee82fcedfaed25eb31fa6848b3199b31c0c981e7..a1076cd50759c5f6790d0182ee26f229bc6bb4d4 100644 (file)
@@ -411,6 +411,301 @@ dnl **
 dnl ** curses checks
 dnl **
 
+dnl Curses detection: Munged from Midnight Commander's configure.in
+dnl
+dnl What it does:
+dnl =============
+dnl
+dnl - Determine which version of curses is installed on your system
+dnl   and set the -I/-L/-l compiler entries and add a few preprocessor
+dnl   symbols 
+dnl - Do an AC_SUBST on the CURSES_INCLUDEDIR and CURSES_LIBS so that
+dnl   @CURSES_INCLUDEDIR@ and @CURSES_LIBS@ will be available in
+dnl   Makefile.in's
+dnl - Modify the following configure variables (these are the only
+dnl   curses.m4 variables you can access from within configure.in)
+dnl   CURSES_INCLUDEDIR - contains -I's and possibly -DRENAMED_CURSES if
+dnl                       an ncurses.h that's been renamed to curses.h
+dnl                       is found.
+dnl   CURSES_LIBS       - sets -L and -l's appropriately
+dnl   CFLAGS            - if --with-sco, add -D_SVID3 
+dnl   has_curses        - exports result of tests to rest of configure
+dnl
+dnl Usage:
+dnl ======
+dnl 1) Add lines indicated below to acconfig.h
+dnl 2) call AC_CHECK_CURSES after AC_PROG_CC in your configure.in
+dnl 3) Instead of #include <curses.h> you should use the following to
+dnl    properly locate ncurses or curses header file
+dnl
+dnl    #if defined(USE_NCURSES) && !defined(RENAMED_NCURSES)
+dnl    #include <ncurses.h>
+dnl    #else
+dnl    #include <curses.h>
+dnl    #endif
+dnl
+dnl 4) Make sure to add @CURSES_INCLUDEDIR@ to your preprocessor flags
+dnl 5) Make sure to add @CURSES_LIBS@ to your linker flags or LIBS
+dnl
+dnl Notes with automake:
+dnl - call AM_CONDITIONAL(HAS_CURSES, test "$has_curses" = true) from
+dnl   configure.in
+dnl - your Makefile.am can look something like this
+dnl   -----------------------------------------------
+dnl   INCLUDES= blah blah blah $(CURSES_INCLUDEDIR) 
+dnl   if HAS_CURSES
+dnl   CURSES_TARGETS=name_of_curses_prog
+dnl   endif
+dnl   bin_PROGRAMS = other_programs $(CURSES_TARGETS)
+dnl   other_programs_SOURCES = blah blah blah
+dnl   name_of_curses_prog_SOURCES = blah blah blah
+dnl   other_programs_LDADD = blah
+dnl   name_of_curses_prog_LDADD = blah $(CURSES_LIBS)
+dnl   -----------------------------------------------
+dnl
+dnl
+dnl The following lines should be added to acconfig.h:
+dnl ==================================================
+dnl
+dnl /*=== Curses version detection defines ===*/
+dnl /* Found some version of curses that we're going to use */
+dnl #undef HAS_CURSES
+dnl    
+dnl /* Use SunOS SysV curses? */
+dnl #undef USE_SUNOS_CURSES
+dnl 
+dnl /* Use old BSD curses - not used right now */
+dnl #undef USE_BSD_CURSES
+dnl 
+dnl /* Use SystemV curses? */
+dnl #undef USE_SYSV_CURSES
+dnl 
+dnl /* Use Ncurses? */
+dnl #undef USE_NCURSES
+dnl 
+dnl /* If you Curses does not have color define this one */
+dnl #undef NO_COLOR_CURSES
+dnl 
+dnl /* Define if you want to turn on SCO-specific code */
+dnl #undef SCO_FLAVOR
+dnl 
+dnl /* Set to reflect version of ncurses *
+dnl  *   0 = version 1.*
+dnl  *   1 = version 1.9.9g
+dnl  *   2 = version 4.0/4.1 */
+dnl #undef NCURSES_970530
+dnl
+dnl /*=== End new stuff for acconfig.h ===*/
+dnl 
+
+
+AC_DEFUN(AC_CHECK_CURSES,[
+       search_ncurses=true
+       screen_manager=""
+       has_curses=false
+
+       CFLAGS=${CFLAGS--O}
+
+       AC_SUBST(CURSES_LIBS)
+       AC_SUBST(CURSES_INCLUDEDIR)
+
+       AC_ARG_WITH(sco,
+         [  --with-sco              Use this to turn on SCO-specific code],[
+         if test x$withval = xyes; then
+               AC_DEFINE(SCO_FLAVOR)
+               CFLAGS="$CFLAGS -D_SVID3"
+         fi
+       ])
+
+       AC_ARG_WITH(sunos-curses,
+         [  --with-sunos-curses     Used to force SunOS 4.x curses],[
+         if test x$withval = xyes; then
+               AC_USE_SUNOS_CURSES
+         fi
+       ])
+
+       AC_ARG_WITH(osf1-curses,
+         [  --with-osf1-curses      Used to force OSF/1 curses],[
+         if test x$withval = xyes; then
+               AC_USE_OSF1_CURSES
+         fi
+       ])
+
+       AC_ARG_WITH(vcurses,
+         [  --with-vcurses[=incdir] Used to force SysV curses],
+         if test x$withval != xyes; then
+               CURSES_INCLUDEDIR="-I$withval"
+         fi
+         AC_USE_SYSV_CURSES
+       )
+
+       AC_ARG_WITH(ncurses,
+         [  --with-ncurses[=dir]    Compile with ncurses/locate base dir],
+         if test x$withval = xno ; then
+               search_ncurses=false
+         elif test x$withval != xyes ; then
+               AC_NCURSES($withval/include, ncurses.h, -L$withval/lib -lncurses, -I$withval/include, "ncurses on $withval/include")
+         fi
+       )
+
+       if $search_ncurses
+       then
+               AC_SEARCH_NCURSES()
+       fi
+])
+
+
+AC_DEFUN(AC_USE_SUNOS_CURSES, [
+       search_ncurses=false
+       screen_manager="SunOS 4.x /usr/5include curses"
+       AC_MSG_RESULT(Using SunOS 4.x /usr/5include curses)
+       AC_DEFINE(USE_SUNOS_CURSES)
+       AC_DEFINE(HAS_CURSES)
+       has_curses=true
+       AC_DEFINE(NO_COLOR_CURSES)
+       AC_DEFINE(USE_SYSV_CURSES)
+       CURSES_INCLUDEDIR="-I/usr/5include"
+       CURSES_LIBS="/usr/5lib/libcurses.a /usr/5lib/libtermcap.a"
+       AC_MSG_RESULT(Please note that some screen refreshs may fail)
+])
+
+AC_DEFUN(AC_USE_OSF1_CURSES, [
+       AC_MSG_RESULT(Using OSF1 curses)
+       search_ncurses=false
+       screen_manager="OSF1 curses"
+       AC_DEFINE(HAS_CURSES)
+       has_curses=true
+       AC_DEFINE(NO_COLOR_CURSES)
+       AC_DEFINE(USE_SYSV_CURSES)
+       CURSES_LIBS="-lcurses"
+])
+
+AC_DEFUN(AC_USE_SYSV_CURSES, [
+       AC_MSG_RESULT(Using SysV curses)
+       AC_DEFINE(HAS_CURSES)
+       has_curses=true
+       AC_DEFINE(USE_SYSV_CURSES)
+       search_ncurses=false
+       screen_manager="SysV/curses"
+       CURSES_LIBS="-lcurses"
+])
+
+dnl AC_ARG_WITH(bsd-curses,
+dnl [--with-bsd-curses         Used to compile with bsd curses, not very fancy],
+dnl    search_ncurses=false
+dnl    screen_manager="Ultrix/cursesX"
+dnl    if test $system = ULTRIX
+dnl    then
+dnl        THIS_CURSES=cursesX
+dnl        else
+dnl        THIS_CURSES=curses
+dnl    fi
+dnl
+dnl    CURSES_LIBS="-l$THIS_CURSES -ltermcap"
+dnl    AC_DEFINE(HAS_CURSES)
+dnl    has_curses=true
+dnl    AC_DEFINE(USE_BSD_CURSES)
+dnl    AC_MSG_RESULT(Please note that some screen refreshs may fail)
+dnl    AC_WARN(Use of the bsdcurses extension has some)
+dnl    AC_WARN(display/input problems.)
+dnl    AC_WARN(Reconsider using xcurses)
+dnl)
+
+       
+dnl
+dnl Parameters: directory filename cureses_LIBS curses_INCLUDEDIR nicename
+dnl
+AC_DEFUN(AC_NCURSES, [
+    if $search_ncurses
+    then
+        if test -f $1/$2
+       then
+           AC_MSG_RESULT(Found ncurses on $1/$2)
+
+           CURSES_LIBS="$3"
+           AC_CHECK_LIB(ncurses, initscr, [
+           ], [
+                CHECKLIBS=`echo "$3"|sed 's/-lncurses/-lcurses/g'`
+               AC_CHECK_LIB(curses, initscr, [
+                       CURSES_LIBS="$CHECKLIBS"
+               ],, $CHECKLIBS)
+           ], $CURSES_LIBS)
+           CURSES_INCLUDEDIR="$4"
+           search_ncurses=false
+           screen_manager=$5
+            AC_DEFINE(HAS_CURSES)
+            has_curses=true
+           has_ncurses=true
+           AC_DEFINE(USE_NCURSES)
+       fi
+    fi
+])
+
+AC_DEFUN(AC_SEARCH_NCURSES, [
+    AC_CHECKING("location of ncurses.h file")
+
+    AC_NCURSES(/usr/include, ncurses.h, -lncurses,, "ncurses on /usr/include")
+    AC_NCURSES(/usr/include/ncurses, ncurses.h, -lncurses, -I/usr/include/ncurses, "ncurses on /usr/include/ncurses")
+    AC_NCURSES(/usr/local/include, ncurses.h, -L/usr/local/lib -lncurses, -I/usr/local/include, "ncurses on /usr/local")
+    AC_NCURSES(/usr/pkg/include, ncurses.h, -L/usr/pkg/lib -lncurses, -I/usr/pkg/include, "ncurses on /usr/pkg")
+    AC_NCURSES(/usr/contrib/include, ncurses.h, -L/usr/contrib/lib -lncurses, -I/usr/contrib/include, "ncurses on /usr/contrib")
+    AC_NCURSES(/usr/local/include/ncurses, ncurses.h, -L/usr/local/lib -L/usr/local/lib/ncurses -lncurses, -I/usr/local/include/ncurses, "ncurses on /usr/local/include/ncurses")
+
+    AC_NCURSES(/usr/local/include/ncurses, curses.h, -L/usr/local/lib -lncurses, -I/usr/local/include/ncurses -DRENAMED_NCURSES, "renamed ncurses on /usr/local/.../ncurses")
+
+    AC_NCURSES(/usr/include/ncurses, curses.h, -lncurses, -I/usr/include/ncurses -DRENAMED_NCURSES, "renamed ncurses on /usr/include/ncurses")
+
+    dnl
+    dnl We couldn't find ncurses, try SysV curses
+    dnl
+    if $search_ncurses 
+    then
+        AC_EGREP_HEADER(init_color, /usr/include/curses.h,
+           AC_USE_SYSV_CURSES)
+       AC_EGREP_CPP(USE_NCURSES,[
+#include <curses.h>
+#ifdef __NCURSES_H
+#undef USE_NCURSES
+USE_NCURSES
+#endif
+],[
+       CURSES_INCLUDEDIR="$CURSES_INCLUDEDIR -DRENAMED_NCURSES"
+        AC_DEFINE(HAS_CURSES)
+       has_curses=true
+       has_ncurses=true
+        AC_DEFINE(USE_NCURSES)
+        search_ncurses=false
+        screen_manager="ncurses installed as curses"
+])
+    fi
+
+    dnl
+    dnl Try SunOS 4.x /usr/5{lib,include} ncurses
+    dnl The flags USE_SUNOS_CURSES, USE_BSD_CURSES and BUGGY_CURSES
+    dnl should be replaced by a more fine grained selection routine
+    dnl
+    if $search_ncurses
+    then
+       if test -f /usr/5include/curses.h
+       then
+           AC_USE_SUNOS_CURSES
+        fi
+    fi
+
+    dnl use whatever curses there happens to be
+    if $search_ncurses
+    then
+       if test -f /usr/include/curses.h
+       then
+         CURSES_LIBS="-lcurses"
+         AC_DEFINE(HAS_CURSES)
+         has_curses=true
+         search_ncurses=false
+         screen_manager="curses"
+       fi
+    fi
+])
+
 if test "x$want_textui" = "xyes"; then
        AC_CHECK_CURSES
 
index a2385c75c0661ce9a3a0f2e6cc442b5ab82cf180..3b13cb0b5e2912d9547f2fc6a95baf7f5808a74a 100644 (file)
@@ -65,6 +65,54 @@ SilcSimContext **sims = NULL;
 uint32 sims_count = 0;
 #endif
 
+static void silc_say(SilcClient client, SilcClientConnection conn,
+                    char *msg, ...);
+static void 
+silc_channel_message(SilcClient client, SilcClientConnection conn,
+                    SilcClientEntry sender, SilcChannelEntry channel,
+                    SilcMessageFlags flags, char *msg);
+static void 
+silc_private_message(SilcClient client, SilcClientConnection conn,
+                    SilcClientEntry sender, SilcMessageFlags flags,
+                    char *msg);
+static void silc_notify(SilcClient client, SilcClientConnection conn,
+                       SilcNotifyType type, ...);
+static void 
+silc_connect(SilcClient client, SilcClientConnection conn, int success);
+static void 
+silc_disconnect(SilcClient client, SilcClientConnection conn);
+static void 
+silc_command(SilcClient client, SilcClientConnection conn, 
+            SilcClientCommandContext cmd_context, int success,
+            SilcCommand command);
+static void 
+silc_command_reply(SilcClient client, SilcClientConnection conn,
+                  SilcCommandPayload cmd_payload, int success,
+                  SilcCommand command, SilcCommandStatus status, ...);
+
+static int silc_verify_public_key(SilcClient client,
+                                 SilcClientConnection conn, 
+                                 SilcSocketType conn_type,
+                                 unsigned char *pk, uint32 pk_len,
+                                 SilcSKEPKType pk_type);
+static unsigned char *silc_ask_passphrase(SilcClient client,
+                                         SilcClientConnection conn);
+static int 
+silc_get_auth_method(SilcClient client, SilcClientConnection conn,
+                    char *hostname, uint16 port,
+                    SilcProtocolAuthMeth *auth_meth,
+                    unsigned char **auth_data,
+                    uint32 *auth_data_len);
+static void 
+silc_failure(SilcClient client, SilcClientConnection conn, 
+            SilcProtocol protocol, void *failure);
+static int 
+silc_key_agreement(SilcClient client, SilcClientConnection conn,
+                  SilcClientEntry client_entry, char *hostname,
+                  int port,
+                  SilcKeyAgreementCallback *completion,
+                  void **context);
+
 static void silc_say(SilcClient client, SilcClientConnection conn,
                     char *msg, ...)
 {
@@ -81,6 +129,19 @@ static void silc_say(SilcClient client, SilcClientConnection conn,
   va_end(va);
 }
 
+static void silc_say_error(char *msg, ...)
+{
+  va_list va;
+  char *str;
+
+  va_start(va, msg);
+  str = g_strdup_vprintf(msg, va);
+  printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "%s", str);
+
+  g_free(str);
+  va_end(va);
+}
+
 /* Message for a channel. The `sender' is the nickname of the sender 
    received in the packet. The `channel_name' is the name of the channel. */
 
@@ -225,6 +286,38 @@ silc_command(SilcClient client, SilcClientConnection conn,
 {
 }
 
+/* Client info resolving callback when JOIN command reply is received.
+   This will cache all users on the channel. */
+
+void silc_client_join_get_users(SilcClient client,
+                               SilcClientConnection conn,
+                               SilcClientEntry *clients,
+                               uint32 clients_count,
+                               void *context)
+{
+  SilcChannelEntry channel = (SilcChannelEntry)context;
+  SilcChannelUser chu;
+  SILC_SERVER_REC *server = conn->context;
+  SILC_CHANNEL_REC *chanrec;
+  NICK_REC *ownnick;
+
+  if (!clients)
+    return;
+
+  chanrec = silc_channel_find_entry(server, channel);
+  if (chanrec == NULL)
+    return;
+
+  silc_list_start(channel->clients);
+  while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END)
+    silc_nicklist_insert(chanrec, chu, FALSE);
+
+  ownnick = NICK(silc_nicklist_find(chanrec, conn->local_entry));
+  nicklist_set_own(CHANNEL(chanrec), ownnick);
+  signal_emit("channel joined", 1, chanrec);
+  fe_channels_nicklist(CHANNEL(chanrec), CHANNEL_NICKLIST_FLAG_ALL);
+}
+
 /* Command reply handler. This function is called always in the command reply
    function. If error occurs it will be called as well. Normal scenario
    is that it will be called after the received command data has been parsed
@@ -261,6 +354,8 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
        uint32 idle, mode;
        SilcBuffer channels;
 
+       /* XXX should use irssi routines */
+
        if (status == SILC_STATUS_ERR_NO_SUCH_NICK ||
            status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
          char *tmp;
@@ -358,6 +453,8 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
        char buf[1024], *nickname, *username, *realname;
        int len;
 
+       /* XXX should use irssi routines */
+
        if (status == SILC_STATUS_ERR_NO_SUCH_NICK ||
            status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
          char *tmp;
@@ -410,6 +507,8 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
        if (!success)
          return;
        
+       /* XXX should use irssi routines */
+
        channel = va_arg(vp, SilcChannelEntry);
        invite_list = va_arg(vp, char *);
 
@@ -424,24 +523,44 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
 
   case SILC_COMMAND_JOIN: 
     {
-      char *channel, *mode;
+      char *channel, *mode, *topic;
       uint32 modei;
       SilcChannelEntry channel_entry;
-      
+      SilcBuffer client_id_list;
+      uint32 list_count;
+
       channel = va_arg(vp, char *);
       channel_entry = va_arg(vp, SilcChannelEntry);
       modei = va_arg(vp, uint32);
-      mode = silc_client_chmode(modei, channel_entry);
-      
+      (void)va_arg(vp, uint32);
+      (void)va_arg(vp, unsigned char *);
+      (void)va_arg(vp, unsigned char *);
+      (void)va_arg(vp, unsigned char *);
+      topic = va_arg(vp, char *);
+      (void)va_arg(vp, unsigned char *);
+      list_count = va_arg(vp, uint32);
+      client_id_list = va_arg(vp, SilcBuffer);
+
+      /* XXX what an earth do I do with the topic??? */
+
+      if (!success)
+       return;
+
       chanrec = silc_channel_find(server, channel);
       if (chanrec != NULL && !success)
        channel_destroy(CHANNEL(chanrec));
       else if (chanrec == NULL && success)
        chanrec = silc_channel_create(server, channel, TRUE);
       
+      mode = silc_client_chmode(modei, channel_entry);
       g_free_not_null(chanrec->mode);
       chanrec->mode = g_strdup(mode == NULL ? "" : mode);
       signal_emit("channel mode changed", 1, chanrec);
+
+      /* Resolve the client information */
+      silc_client_get_clients_by_list(client, conn, list_count, client_id_list,
+                                     silc_client_join_get_users, 
+                                     channel_entry);
       break;
     }
 
@@ -450,24 +569,117 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
       SilcClientEntry client = va_arg(vp, SilcClientEntry);
       char *old;
       
+      if (!success)
+       return;
+
       old = g_strdup(server->nick);
       server_change_nick(SERVER(server), client->nickname);
       nicklist_rename_unique(SERVER(server),
                             server->conn->local_entry, server->nick,
                             client, client->nickname);
       
-      signal_emit("message own_nick", 4,
-                 server, server->nick, old, "");
+      signal_emit("message own_nick", 4, server, server->nick, old, "");
       g_free(old);
       break;
     }
 
+    case SILC_COMMAND_LIST:
+      {
+       char *topic, *name;
+       int usercount;
+       unsigned char buf[256], tmp[16];
+       int i, len;
+
+       if (!success)
+         return;
+
+       /* XXX should use irssi routines */
+
+       (void)va_arg(vp, SilcChannelEntry);
+       name = va_arg(vp, char *);
+       topic = va_arg(vp, char *);
+       usercount = va_arg(vp, 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:
+      {
+       uint32 mode;
+
+       if (!success)
+         return;
+
+       mode = va_arg(vp, uint32);
+
+       /* XXX todo */
+      }
+      break;
+
+    case SILC_COMMAND_OPER:
+#if 0
+      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);
+      }
+#endif
+      break;
+
+    case SILC_COMMAND_SILCOPER:
+#if 0
+      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);
+      }
+#endif
+      break;
+
   case SILC_COMMAND_USERS: 
     {
       SilcChannelEntry channel;
       SilcChannelUser user;
       NICK_REC *ownnick;
       
+      if (!success)
+       return;
+
       channel = va_arg(vp, SilcChannelEntry);
       chanrec = silc_channel_find_entry(server, channel);
       if (chanrec == NULL)
@@ -484,6 +696,70 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
                           CHANNEL_NICKLIST_FLAG_ALL);
       break;
     }
+
+    case SILC_COMMAND_BAN:
+      {
+       SilcChannelEntry channel;
+       char *ban_list;
+
+       if (!success)
+         return;
+
+       /* XXX should use irssi routines */
+
+       
+       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;
+
+    case SILC_COMMAND_GETKEY:
+      {
+       SilcIdType id_type;
+       void *entry;
+       SilcPublicKey public_key;
+       unsigned char *pk;
+       uint32 pk_len;
+
+       id_type = va_arg(vp, uint32);
+       entry = va_arg(vp, void *);
+       public_key = va_arg(vp, SilcPublicKey);
+
+       pk = silc_pkcs_public_key_encode(public_key, &pk_len);
+
+       if (id_type == SILC_ID_CLIENT) {
+         silc_verify_public_key(client, conn, SILC_SOCKET_TYPE_CLIENT,
+                                pk, pk_len, SILC_SKE_PK_TYPE_SILC);
+       }
+
+       silc_free(pk);
+      }
+
+    case SILC_COMMAND_TOPIC:
+      {
+       SilcChannelEntry channel;
+       char *topic;
+
+       if (!success)
+         return;
+       
+       channel = va_arg(vp, SilcChannelEntry);
+       topic = va_arg(vp, char *);
+
+       /* XXX should use irssi routines */
+
+       if (topic)
+         silc_say(client, conn, 
+                  "Topic on channel %s: %s", channel->channel_name,
+                  topic);
+      }
+      break;
   }
   
   va_end(vp);
@@ -523,7 +799,15 @@ silc_get_auth_method(SilcClient client, SilcClientConnection conn,
                     unsigned char **auth_data,
                     uint32 *auth_data_len)
 {
-  return FALSE;
+
+  /* XXX must resolve from configuration whether this connection has
+     any specific authentication data */
+
+  *auth_meth = SILC_AUTH_NONE;
+  *auth_data = NULL;
+  *auth_data_len = 0;
+
+  return TRUE;
 }
 
 /* Notifies application that failure packet was received.  This is called
@@ -541,28 +825,23 @@ silc_failure(SilcClient client, SilcClientConnection conn,
     SilcSKEStatus status = (SilcSKEStatus)failure;
     
     if (status == SILC_SKE_STATUS_BAD_VERSION)
-      silc_say(client, conn, 
-              "You are running incompatible client version (it may be "
-              "too old or too new)");
+      silc_say_error("You are running incompatible client version (it may be "
+                    "too old or too new)");
     if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY)
-      silc_say(client, conn, "Server does not support your public key type");
+      silc_say_error("Server does not support your public key type");
     if (status == SILC_SKE_STATUS_UNKNOWN_GROUP)
-      silc_say(client, conn, 
-              "Server does not support one of your proposed KE group");
+      silc_say_error("Server does not support one of your proposed KE group");
     if (status == SILC_SKE_STATUS_UNKNOWN_CIPHER)
-      silc_say(client, conn, 
-              "Server does not support one of your proposed cipher");
+      silc_say_error("Server does not support one of your proposed cipher");
     if (status == SILC_SKE_STATUS_UNKNOWN_PKCS)
-      silc_say(client, conn, 
-              "Server does not support one of your proposed PKCS");
+      silc_say_error("Server does not support one of your proposed PKCS");
     if (status == SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION)
-      silc_say(client, conn, 
-              "Server does not support one of your proposed hash function");
+      silc_say_error("Server does not support one of your proposed "
+                   "hash function");
     if (status == SILC_SKE_STATUS_UNKNOWN_HMAC)
-      silc_say(client, conn, 
-              "Server does not support one of your proposed HMAC");
+      silc_say_error("Server does not support one of your proposed HMAC");
     if (status == SILC_SKE_STATUS_INCORRECT_SIGNATURE)
-      silc_say(client, conn, "Incorrect signature");
+      silc_say_error("Incorrect signature");
   }
 
   if (protocol->protocol->type == SILC_PROTOCOL_CLIENT_CONNECTION_AUTH) {
index bef2521cbc3a0a0684379cabb7c8970ed61dddd0..f84d1dd2e7746c6e358c5b3115bf56d35954d3d7 100644 (file)
@@ -40,8 +40,10 @@ SILC_NICK_REC *silc_nicklist_insert(SILC_CHANNEL_REC *channel,
        rec->silc_user = user;
        rec->unique_id = user->client;
 
-       if (user->mode & SILC_CHANNEL_UMODE_CHANOP) rec->op = TRUE;
-       if (user->mode & SILC_CHANNEL_UMODE_CHANFO) rec->founder = TRUE;
+       if (user->mode & SILC_CHANNEL_UMODE_CHANOP) 
+         rec->op = TRUE;
+       if (user->mode & SILC_CHANNEL_UMODE_CHANFO) 
+         rec->founder = TRUE;
        rec->send_massjoin = send_massjoin;
 
        nicklist_insert(CHANNEL(channel), (NICK_REC *) rec);
index 0d3bbe07fbf5537548414287aaa4b9626b6a31b7..ef0090e3215f8707207eb516444bde34ab97cc7e 100644 (file)
 #include "silc-queries.h"
 
 QUERY_REC *silc_query_create(SILC_SERVER_REC *server,
-                           const char *nick, int automatic)
+                            const char *nick, int automatic)
 {
-       QUERY_REC *rec;
+  QUERY_REC *rec;
 
-       g_return_val_if_fail(server == NULL || IS_SILC_SERVER(server), NULL);
-       g_return_val_if_fail(nick != NULL, NULL);
+  g_return_val_if_fail(server == NULL || IS_SILC_SERVER(server), NULL);
+  g_return_val_if_fail(nick != NULL, NULL);
 
-       rec = g_new0(QUERY_REC, 1);
-       rec->chat_type = SILC_PROTOCOL;
-       rec->name = g_strdup(nick);
-       rec->server = (SERVER_REC *) server;
-       query_init(rec, automatic);
-       return rec;
+  rec = g_new0(QUERY_REC, 1);
+  rec->chat_type = SILC_PROTOCOL;
+  rec->name = g_strdup(nick);
+  rec->server = (SERVER_REC *) server;
+  query_init(rec, automatic);
+  return rec;
 }
 
 void silc_queries_init(void)
index bd024f6eab73fd77d813ff5f37d7498c3064ec2c..2234054130499501055ceeb241fc2201cc2e3311 100644 (file)
@@ -8,17 +8,14 @@
 /* Returns SILC_QUERY_REC if it's SILC query, NULL if it isn't. */
 #define SILC_QUERY(query) \
        PROTO_CHECK_CAST(QUERY(query), QUERY_REC, chat_type, "SILC")
-
 #define IS_SILC_QUERY(query) \
        (SILC_QUERY(query) ? TRUE : FALSE)
-
-void silc_queries_init(void);
-void silc_queries_deinit(void);
-
 #define silc_query_find(server, name) \
        query_find(SERVER(server), name)
 
 QUERY_REC *silc_query_create(SILC_SERVER_REC *server,
-                           const char *nick, int automatic);
+                            const char *nick, int automatic);
+void silc_queries_init(void);
+void silc_queries_deinit(void);
 
 #endif
index 95de6a5d9ec08a2da4fa6e1cc0e70ab3161eb7d8..740c3b686ed20d4835a0b917a6ac62e6c5aa3d5c 100644 (file)
@@ -58,8 +58,8 @@ static void silc_send_channel(SILC_SERVER_REC *server,
 }
 
 typedef struct {
-       char *nick;
-        char *msg;
+  char *nick;
+  char *msg;
 } PRIVMSG_REC;
 
 static void silc_send_msg_clients(SilcClient client,
@@ -270,8 +270,10 @@ static void command_users(const char *data, SILC_SERVER_REC *server,
 
 static void command_self(const char *data, SILC_SERVER_REC *server)
 {
-  if (!IS_SILC_SERVER(server) || !server->connected)
+  if (!IS_SILC_SERVER(server) || !server->connected) {
+    printtext(NULL, NULL, MSGLEVEL_CLIENTERROR, "Not connected to server");
     return;
+  }
 
   silc_command_exec(server, current_command, data);
   signal_stop();
@@ -302,11 +304,26 @@ void silc_server_init(void)
   signal_add("server disconnected", (SIGNAL_FUNC) sig_disconnected);
   signal_add("send text", (SIGNAL_FUNC) event_text);
   command_bind("whois", MODULE_NAME, (SIGNAL_FUNC) command_self);
+  command_bind("whowas", MODULE_NAME, (SIGNAL_FUNC) command_self);
   command_bind("nick", MODULE_NAME, (SIGNAL_FUNC) command_self);
   command_bind("topic", MODULE_NAME, (SIGNAL_FUNC) command_self);
   command_bind("cmode", MODULE_NAME, (SIGNAL_FUNC) command_self);
   command_bind("cumode", MODULE_NAME, (SIGNAL_FUNC) command_self);
   command_bind("users", MODULE_NAME, (SIGNAL_FUNC) command_users);
+  command_bind("list", MODULE_NAME, (SIGNAL_FUNC) command_self);
+  command_bind("ban", MODULE_NAME, (SIGNAL_FUNC) command_self);
+  command_bind("silcoper", MODULE_NAME, (SIGNAL_FUNC) command_self);
+  command_bind("umode", MODULE_NAME, (SIGNAL_FUNC) command_self);
+  command_bind("invite", MODULE_NAME, (SIGNAL_FUNC) command_self);
+  command_bind("kill", MODULE_NAME, (SIGNAL_FUNC) command_self);
+  command_bind("kick", MODULE_NAME, (SIGNAL_FUNC) command_self);
+  command_bind("info", MODULE_NAME, (SIGNAL_FUNC) command_self);
+  command_bind("connect", MODULE_NAME, (SIGNAL_FUNC) command_self);
+  command_bind("ping", MODULE_NAME, (SIGNAL_FUNC) command_self);
+  command_bind("motd", MODULE_NAME, (SIGNAL_FUNC) command_self);
+  command_bind("close", MODULE_NAME, (SIGNAL_FUNC) command_self);
+  command_bind("shutdown", MODULE_NAME, (SIGNAL_FUNC) command_self);
+  command_bind("getkey", MODULE_NAME, (SIGNAL_FUNC) command_self);
 
   command_set_options("connect", "+silcnet");
 }
@@ -319,9 +336,24 @@ void silc_server_deinit(void)
   signal_remove("server disconnected", (SIGNAL_FUNC) sig_disconnected);
   signal_remove("send text", (SIGNAL_FUNC) event_text);
   command_unbind("whois", (SIGNAL_FUNC) command_self);
+  command_unbind("whowas", (SIGNAL_FUNC) command_self);
   command_unbind("nick", (SIGNAL_FUNC) command_self);
   command_unbind("topic", (SIGNAL_FUNC) command_self);
   command_unbind("cmode", (SIGNAL_FUNC) command_self);
   command_unbind("cumode", (SIGNAL_FUNC) command_self);
   command_unbind("users", (SIGNAL_FUNC) command_users);
+  command_unbind("list", (SIGNAL_FUNC) command_self);
+  command_unbind("silcoper", (SIGNAL_FUNC) command_self);
+  command_unbind("umode", (SIGNAL_FUNC) command_self);
+  command_unbind("invite", (SIGNAL_FUNC) command_self);
+  command_unbind("kill", (SIGNAL_FUNC) command_self);
+  command_unbind("kick", (SIGNAL_FUNC) command_self);
+  command_unbind("info", (SIGNAL_FUNC) command_self);
+  command_unbind("connect", (SIGNAL_FUNC) command_self);
+  command_unbind("ping", (SIGNAL_FUNC) command_self);
+  command_unbind("motd", (SIGNAL_FUNC) command_self);
+  command_unbind("ban", (SIGNAL_FUNC) command_self);
+  command_unbind("close", (SIGNAL_FUNC) command_self);
+  command_unbind("shutdown", (SIGNAL_FUNC) command_self);
+  command_unbind("getkey", (SIGNAL_FUNC) command_self);
 }
index 1f9dd7f172821b26e8ee6a07fad012a9ccd77ccf..eb0edc6dfd9144bb3005d0bf89e330ac4f3ff116 100644 (file)
@@ -7,14 +7,11 @@
 /* returns SILC_SERVER_REC if it's SILC server, NULL if it isn't */
 #define SILC_SERVER(server) \
        PROTO_CHECK_CAST(SERVER(server), SILC_SERVER_REC, chat_type, "SILC")
-
 #define SILC_SERVER_CONNECT(conn) \
        PROTO_CHECK_CAST(SERVER_CONNECT(conn), SILC_SERVER_CONNECT_REC, \
                         chat_type, "SILC")
-
 #define IS_SILC_SERVER(server) \
        (SILC_SERVER(server) ? TRUE : FALSE)
-
 #define IS_SILC_SERVER_CONNECT(conn) \
        (SILC_SERVER_CONNECT(conn) ? TRUE : FALSE)
 
index d715e5d9379837eda476f41529d67e6ed1917839..62849ce157b41ebd90cb87ecd378759ac01506b9 100644 (file)
@@ -380,12 +380,9 @@ void silc_command(SilcClient client, SilcClientConnection conn,
       break;
 
     case SILC_COMMAND_LEAVE:
-#if 0
-      if (!strncmp(conn->current_channel->channel_name, name, strlen(name))) {
-       app->screen->bottom_line->channel = NULL;
-       silc_screen_print_bottom_line(app->screen, 0);
-      }
-#endif
+      /* We won't talk anymore on this channel */
+      silc_say(client, conn, "You have left channel %s", 
+              conn->current_channel->channel_name);
       break;
 
     }
@@ -800,8 +797,8 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn,
        channel = va_arg(vp, SilcChannelEntry);
 
        /* There are two ways to do this, either parse the list (that
-          the command_reply sends (just take it with va_arg())) or just
-          traverse the channel'c client list.  I'll do the latter.  See
+          the command_reply sends (just take it with va_arg()) or just
+          traverse the channel's client list.  I'll do the latter.  See
           JOIN command reply for example for the list. */
 
        silc_say(client, conn, "Users on %s", channel->channel_name);
@@ -915,6 +912,24 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn,
        silc_free(pk);
       }
 
+    case SILC_COMMAND_TOPIC:
+      {
+       SilcChannelEntry channel;
+       char *topic;
+
+       if (!success)
+         return;
+       
+       channel = va_arg(vp, SilcChannelEntry);
+       topic = va_arg(vp, char *);
+
+       if (topic)
+         silc_say(client, conn, 
+                  "Topic on channel %s: %s", channel->channel_name,
+                  topic);
+      }
+      break;
+
     default:
       break;
     }
index 607ff9fc8151b8ad01a5e38efe8ee3b9a795582a..7d66a101c0c73eed1cc01a64d58abf12b9237c82 100644 (file)
@@ -509,14 +509,15 @@ SILC_CLIENT_CMD_FUNC(topic)
   /* Send TOPIC command to the server */
   idp = silc_id_payload_encode(id_cache->id, SILC_ID_CHANNEL);
   if (cmd->argc > 2)
-    buffer = silc_command_payload_encode_va(SILC_COMMAND_TOPIC, 0, 2, 
+    buffer = silc_command_payload_encode_va(SILC_COMMAND_TOPIC, 
+                                           ++conn->cmd_ident, 2, 
                                            1, idp->data, idp->len,
                                            2, cmd->argv[2], 
                                            strlen(cmd->argv[2]));
   else
-    buffer = silc_command_payload_encode_va(SILC_COMMAND_TOPIC, 1, 
-                                           1, idp->data, idp->len,
-                                           0);
+    buffer = silc_command_payload_encode_va(SILC_COMMAND_TOPIC, 
+                                           ++conn->cmd_ident, 1,
+                                           1, idp->data, idp->len);
   silc_client_packet_send(cmd->client, conn->sock, SILC_PACKET_COMMAND, NULL, 
                          0, NULL, NULL, buffer->data, buffer->len, TRUE);
   silc_buffer_free(buffer);
@@ -930,10 +931,10 @@ SILC_CLIENT_CMD_FUNC(join)
   /* See if we have joined to the requested channel already */
   if (silc_idcache_find_by_name_one(conn->channel_cache, cmd->argv[1],
                                    &id_cache)) {
+#if 0
     cmd->client->ops->say(cmd->client, conn, 
                          "You are talking to channel %s", cmd->argv[1]);
     conn->current_channel = (SilcChannelEntry)id_cache->context;
-#if 0
     cmd->client->screen->bottom_line->channel = cmd->argv[1];
     silc_screen_print_bottom_line(cmd->client->screen, 0);
 #endif
@@ -1951,8 +1952,8 @@ SILC_CLIENT_CMD_FUNC(leave)
   silc_buffer_free(buffer);
   silc_buffer_free(idp);
 
-  /* We won't talk anymore on this channel */
-  cmd->client->ops->say(cmd->client, conn, "You have left channel %s", name);
+  /* Notify application */
+  COMMAND;
 
   conn->current_channel = NULL;
 
@@ -1963,9 +1964,6 @@ SILC_CLIENT_CMD_FUNC(leave)
   silc_cipher_free(channel->channel_key);
   silc_free(channel);
 
-  /* Notify application */
-  COMMAND;
-
  out:
   silc_client_command_free(cmd);
 }
index 03f13c9879b805b47f68f049871a859d689f6d58..b6c57b4ce48b7d732b89bbcf56c8e1ca387ead6b 100644 (file)
@@ -695,10 +695,6 @@ SILC_CLIENT_CMD_REPLY_FUNC(topic)
   
   channel = (SilcChannelEntry)id_cache->context;
 
-  cmd->client->ops->say(cmd->client, conn, 
-                       "Topic on channel %s: %s", channel->channel_name,
-                       topic);
-
   /* Notify application */
   COMMAND_REPLY((ARGS, channel, topic));
 
index e03b89df7015313146b9cbe43fbd2b7667067e4d..671b7797eba515c18c2072c8be08cee3f4a3e9fb 100644 (file)
@@ -93,17 +93,19 @@ void silc_client_get_clients(SilcClient client,
   snprintf(ident, sizeof(ident), "IDENTIFY %s", nickname);
   silc_parse_command_line(ident, &ctx->argv, &ctx->argv_lens, 
                          &ctx->argv_types, &ctx->argc, 2);
-  ctx->command->cb(ctx);
-      
-  i->cmd = ctx;
+
+  i->cmd = silc_client_command_dup(ctx);
   i->nickname = nickname ? strdup(nickname) : NULL;
   i->server = server ? strdup(server) : NULL;
   i->completion = completion;
   i->context = context;
 
+  /* Call the command */
+  ctx->command->cb(ctx);
+
   /* Add pending callback */
   silc_client_command_pending(conn, SILC_COMMAND_IDENTIFY, 
-                             ++conn->cmd_ident, 
+                             conn->cmd_ident, 
                              silc_client_get_client_destructor,
                              silc_client_command_get_client_callback, 
                              (void *)i);
index 2a8c6a538bea020e432e34891c85c689cfa37b02..b0de770077cc677af7f82e4db0b48d142da180e2 100644 (file)
@@ -31,7 +31,7 @@ typedef struct SilcClientEntryStruct {
   char *server;                        /* SILC server name */
   char *realname;              /* Realname (userinfo) */
   uint32 num;
-  uint32 mode;         /* User mode in SILC */
+  uint32 mode;                 /* User mode in SILC */
   SilcClientID *id;            /* The Client ID */
   SilcCipher send_key;         /* Private message key for sending */
   SilcCipher receive_key;      /* Private message key for receiving */