ii-1.8-usernames.diff - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       ii-1.8-usernames.diff (6438B)
       ---
            1 diff --git a/ii.c b/ii.c
            2 index 6583792..f5ed614 100644
            3 --- a/ii.c
            4 +++ b/ii.c
            5 @@ -33,15 +33,23 @@ size_t strlcpy(char *, const char *, size_t);
            6  
            7  enum { TOK_NICKSRV = 0, TOK_USER, TOK_CMD, TOK_CHAN, TOK_ARG, TOK_TEXT, TOK_LAST };
            8  
            9 +typedef struct Nick Nick;
           10 +struct Nick {
           11 +        char name[32];
           12 +        Nick *next;
           13 +};
           14 +
           15  typedef struct Channel Channel;
           16  struct Channel {
           17          int fdin;
           18          char name[IRC_CHANNEL_MAX]; /* channel name (normalized) */
           19          char inpath[PATH_MAX];      /* input path */
           20          char outpath[PATH_MAX];     /* output path */
           21 +        Nick *nicks;
           22          Channel *next;
           23  };
           24  
           25 +static void      add_name(Channel *, const char *);
           26  static Channel * channel_add(const char *);
           27  static Channel * channel_find(const char *);
           28  static Channel * channel_join(const char *);
           29 @@ -61,10 +69,14 @@ static void      handle_server_output(int);
           30  static int       isnumeric(const char *);
           31  static void      loginkey(int, const char *);
           32  static void      loginuser(int, const char *, const char *);
           33 +static void      nick_name(const char *, const char *);
           34  static void      proc_channels_input(int, Channel *, char *);
           35  static void      proc_channels_privmsg(int, Channel *, char *);
           36 +static void      proc_names(Channel *, char *);
           37  static void      proc_server_cmd(int, char *);
           38 +static void      quit_name(const char *, const char *, const char *);
           39  static int       read_line(int, char *, size_t);
           40 +static int       rm_name(Channel *, const char *);
           41  static void      run(int, const char *);
           42  static void      setup(void);
           43  static void      sighandler(int);
           44 @@ -236,6 +248,7 @@ channel_new(const char *name)
           45          c->next = NULL;
           46          strlcpy(c->name, name, sizeof(c->name));
           47          channel_normalize_name(c->name);
           48 +        c->nicks = NULL;
           49  
           50          create_filepath(c->inpath, sizeof(c->inpath), ircpath,
           51                          channelpath, "in");
           52 @@ -294,6 +307,7 @@ static void
           53  channel_rm(Channel *c)
           54  {
           55          Channel *p;
           56 +        Nick *n, *nn;
           57  
           58          if (channels == c) {
           59                  channels = channels->next;
           60 @@ -303,6 +317,10 @@ channel_rm(Channel *c)
           61                  if (p && p->next == c)
           62                          p->next = c->next;
           63          }
           64 +        for (n = c->nicks; n; n = nn) {
           65 +                nn = n->next;
           66 +                free(n);
           67 +        }
           68          free(c);
           69  }
           70  
           71 @@ -318,6 +336,70 @@ channel_leave(Channel *c)
           72          channel_rm(c);
           73  }
           74  
           75 +static void
           76 +add_name(Channel *c, const char *name) {
           77 +        Nick *n;
           78 +        for (n = c->nicks; n; n = n->next)
           79 +                if (!strcmp(name, n->name)) return;
           80 +        if (!(n = calloc(1, sizeof(Nick)))) {
           81 +                fprintf(stderr, "%s: calloc: %s\n", argv0, strerror(errno));
           82 +                exit(1);
           83 +        }
           84 +        strlcpy(n->name, name, sizeof(n->name));
           85 +        n->next = c->nicks;
           86 +        c->nicks = n;
           87 +}
           88 +
           89 +static int
           90 +rm_name(Channel *c, const char *name) {
           91 +        Nick *n, *pn = NULL;
           92 +        for (n = c->nicks; n; pn = n, n = n->next) {
           93 +                if (!strcmp(name, n->name)) {
           94 +                        if (pn)
           95 +                                pn->next = n->next;
           96 +                        else
           97 +                                c->nicks = n->next;
           98 +                        free(n);
           99 +                        return 1;
          100 +                }
          101 +        }
          102 +        return 0;
          103 +}
          104 +
          105 +static void
          106 +proc_names(Channel *c, char *names) {
          107 +        char *p;
          108 +        if (!(p = strtok(names," "))) return;
          109 +        do {
          110 +                if (*p == '@' || *p == '+')
          111 +                        p++;
          112 +                add_name(c,p);
          113 +        } while ((p = strtok(NULL," ")));
          114 +}
          115 +
          116 +static void
          117 +quit_name(const char *name, const char *user, const char *text) {
          118 +        Channel *c;
          119 +        for (c = channels; c; c = c->next) {
          120 +                if (rm_name(c, name)) {
          121 +                        snprintf(msg, PIPE_BUF, "-!- %s(%s) has quit \"%s\"", name, user, text ? text : "");
          122 +                        channel_print(c, msg);
          123 +                }
          124 +        }
          125 +}
          126 +
          127 +static void
          128 +nick_name(const char *old, const char *new) {
          129 +        Channel *c;
          130 +        for (c = channels; c; c = c->next) {
          131 +                if (rm_name(c, old)) {
          132 +                        add_name(c, new);
          133 +                        snprintf(msg, PIPE_BUF, "-!- %s changed nick to \"%s\"", old, new);
          134 +                        channel_print(c, msg);
          135 +                }
          136 +        }
          137 +}
          138 +
          139  static void
          140  loginkey(int ircfd, const char *key)
          141  {
          142 @@ -590,6 +672,15 @@ proc_server_cmd(int fd, char *buf)
          143                  snprintf(msg, sizeof(msg), "PONG %s\r\n", argv[TOK_TEXT]);
          144                  ewritestr(fd, msg);
          145                  return;
          146 +        } else if (!strcmp("353", argv[TOK_CMD])) {
          147 +                p = strtok(argv[TOK_ARG]," ");
          148 +                if (!(p = strtok(NULL," ")))
          149 +                        return;
          150 +                snprintf(msg, PIPE_BUF, "%s%s", argv[TOK_ARG] ? argv[TOK_ARG] : "", argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
          151 +                channel_print(channelmaster, msg);
          152 +                if ((c = channel_find(p)))
          153 +                        proc_names(c, argv[TOK_TEXT]);
          154 +                return;
          155          } else if (!argv[TOK_NICKSRV] || !argv[TOK_USER]) {
          156                  /* server command */
          157                  snprintf(msg, sizeof(msg), "%s%s",
          158 @@ -605,9 +696,13 @@ proc_server_cmd(int fd, char *buf)
          159                          argv[TOK_CHAN] = argv[TOK_TEXT];
          160                  snprintf(msg, sizeof(msg), "-!- %s(%s) has joined %s",
          161                                  argv[TOK_NICKSRV], argv[TOK_USER], argv[TOK_CHAN]);
          162 +                if ((c = channel_find(argv[TOK_CHAN])))
          163 +                        add_name(c, argv[TOK_NICKSRV]);
          164          } else if (!strcmp("PART", argv[TOK_CMD]) && argv[TOK_CHAN]) {
          165                  snprintf(msg, sizeof(msg), "-!- %s(%s) has left %s",
          166                                  argv[TOK_NICKSRV], argv[TOK_USER], argv[TOK_CHAN]);
          167 +                if ((c = channel_find(argv[TOK_CHAN])))
          168 +                        rm_name(c, argv[TOK_NICKSRV]);
          169                  /* if user itself leaves, don't write to channel (don't reopen channel). */
          170                  if (!strcmp(argv[TOK_NICKSRV], nick))
          171                          return;
          172 @@ -618,17 +713,18 @@ proc_server_cmd(int fd, char *buf)
          173                                  argv[TOK_ARG]  ? argv[TOK_ARG] : "",
          174                                  argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
          175          } else if (!strcmp("QUIT", argv[TOK_CMD])) {
          176 -                snprintf(msg, sizeof(msg), "-!- %s(%s) has quit \"%s\"",
          177 -                                argv[TOK_NICKSRV], argv[TOK_USER],
          178 -                                argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
          179 +                quit_name(argv[TOK_NICKSRV], argv[TOK_USER], argv[TOK_TEXT]);
          180 +                return;
          181          } else if (!strncmp("NICK", argv[TOK_CMD], 5) && argv[TOK_TEXT] &&
          182                    !strcmp(_nick, argv[TOK_TEXT])) {
          183                  strlcpy(nick, _nick, sizeof(nick));
          184                  snprintf(msg, sizeof(msg), "-!- changed nick to \"%s\"", nick);
          185                  channel_print(channelmaster, msg);
          186 +                nick_name(argv[TOK_NICKSRV], argv[TOK_TEXT]);
          187 +                return;
          188          } else if (!strcmp("NICK", argv[TOK_CMD]) && argv[TOK_TEXT]) {
          189 -                snprintf(msg, sizeof(msg), "-!- %s changed nick to %s",
          190 -                                argv[TOK_NICKSRV], argv[TOK_TEXT]);
          191 +                nick_name(argv[TOK_NICKSRV], argv[TOK_TEXT]);
          192 +                return;
          193          } else if (!strcmp("TOPIC", argv[TOK_CMD])) {
          194                  snprintf(msg, sizeof(msg), "-!- %s changed topic to \"%s\"",
          195                                  argv[TOK_NICKSRV],
          196 @@ -637,6 +733,8 @@ proc_server_cmd(int fd, char *buf)
          197                  snprintf(msg, sizeof(msg), "-!- %s kicked %s (\"%s\")",
          198                                  argv[TOK_NICKSRV], argv[TOK_ARG],
          199                                  argv[TOK_TEXT] ? argv[TOK_TEXT] : "");
          200 +                if ((c = channel_find(argv[TOK_CHAN])))
          201 +                        rm_name(c, argv[TOK_ARG]);
          202          } else if (!strcmp("NOTICE", argv[TOK_CMD])) {
          203                  snprintf(msg, sizeof(msg), "-!- \"%s\")",
          204                                  argv[TOK_TEXT] ? argv[TOK_TEXT] : "");