ii-1.4-usernames.diff (5512B)
1 diff -r d93eaacde742 ii.c 2 --- a/ii.c Fri Jun 25 10:55:05 2010 +0200 3 +++ b/ii.c Tue Jul 27 17:48:23 2010 -0500 4 @@ -26,10 +26,17 @@ 5 6 enum { TOK_NICKSRV = 0, TOK_USER, TOK_CMD, TOK_CHAN, TOK_ARG, TOK_TEXT, TOK_LAST }; 7 8 +typedef struct Nick Nick; 9 +struct Nick { 10 + char *name; 11 + Nick *next; 12 +}; 13 + 14 typedef struct Channel Channel; 15 struct Channel { 16 int fd; 17 char *name; 18 + Nick *nicks; 19 Channel *next; 20 }; 21 22 @@ -128,18 +135,25 @@ 23 c->next = channels; 24 channels = c; 25 } 26 + c->nicks = NULL; 27 c->fd = fd; 28 c->name = strdup(name); 29 } 30 31 static void rm_channel(Channel *c) { 32 Channel *p; 33 + Nick *n, *nn; 34 if(channels == c) channels = channels->next; 35 else { 36 for(p = channels; p && p->next != c; p = p->next); 37 if(p->next == c) 38 p->next = c->next; 39 } 40 + for(n = c->nicks; n; n = nn) { 41 + nn = n->next; 42 + free(n->name); 43 + free(n); 44 + } 45 free(c->name); 46 free(c); 47 } 48 @@ -217,6 +231,76 @@ 49 fclose(out); 50 } 51 52 +static Channel *lookup_chan(const char *name) { 53 + Channel *c; 54 + for(c = channels; c; c = c->next) 55 + if(!strcmp(name, c->name)) 56 + return c; 57 + return NULL; 58 +} 59 + 60 +static void add_name(const char *chan, const char *name) { 61 + Channel *c; 62 + Nick *n; 63 + if(!(c = lookup_chan(chan))) return; 64 + for(n = c->nicks; n; n = n->next) 65 + if(!strcmp(name, n->name)) return; 66 + if(!(n = malloc(sizeof(Nick)))) { 67 + perror("ii: cannot allocate memory"); 68 + exit(EXIT_FAILURE); 69 + } 70 + n->name = strdup(name); 71 + n->next = c->nicks; 72 + c->nicks = n; 73 +} 74 + 75 +static int rm_name(const char *chan, const char *name) { 76 + Channel *c; 77 + Nick *n, *pn = NULL; 78 + if(!(c = lookup_chan(chan))) return 0; 79 + for(n = c->nicks; n; pn = n, n = n->next) { 80 + if(!strcmp(name, n->name)) { 81 + if(pn) pn->next = n->next; 82 + else c->nicks = n->next; 83 + free(n->name); 84 + free(n); 85 + return 1; 86 + } 87 + } 88 + return 0; 89 +} 90 + 91 +static void proc_names(const char *chan, char *names) { 92 + char *p; 93 + if(!(p = strtok(names," "))) return; 94 + do { 95 + if(*p == '@' || *p == '+') 96 + p++; 97 + add_name(chan,p); 98 + } while((p = strtok(NULL," "))); 99 +} 100 + 101 +static void quit_name(const char *name, const char *user, const char *text) { 102 + Channel *c; 103 + for(c = channels; c; c = c->next) { 104 + if(c->name && rm_name(c->name, name)) { 105 + snprintf(message, PIPE_BUF, "-!- %s(%s) has quit \"%s\"", name, user, text ? text : ""); 106 + print_out(c->name, message); 107 + } 108 + } 109 +} 110 + 111 +static void nick_name(const char *old, const char *new) { 112 + Channel *c; 113 + for(c = channels; c; c = c->next) { 114 + if(c->name && rm_name(c->name, old)) { 115 + add_name(c->name, new); 116 + snprintf(message, PIPE_BUF, "-!- %s changed nick to \"%s\"", old, new); 117 + print_out(c->name, message); 118 + } 119 + } 120 +} 121 + 122 static void proc_channels_privmsg(char *channel, char *buf) { 123 snprintf(message, PIPE_BUF, "<%s> %s", nick, buf); 124 print_out(channel, message); 125 @@ -342,6 +426,14 @@ 126 snprintf(message, PIPE_BUF, "PONG %s\r\n", argv[TOK_TEXT]); 127 write(irc, message, strlen(message)); 128 return; 129 + } else if(!strncmp("353", argv[TOK_CMD], 4)) { 130 + p = strtok(argv[TOK_ARG]," "); 131 + if(!(p = strtok(NULL," "))) 132 + return; 133 + snprintf(message, PIPE_BUF, "%s%s", argv[TOK_ARG] ? argv[TOK_ARG] : "", argv[TOK_TEXT] ? argv[TOK_TEXT] : ""); 134 + print_out(0, message); 135 + proc_names(p, argv[TOK_TEXT]); 136 + return; 137 } else if(!argv[TOK_NICKSRV] || !argv[TOK_USER]) { /* server command */ 138 snprintf(message, PIPE_BUF, "%s%s", argv[TOK_ARG] ? argv[TOK_ARG] : "", argv[TOK_TEXT] ? argv[TOK_TEXT] : ""); 139 print_out(0, message); 140 @@ -356,19 +448,24 @@ 141 } 142 argv[TOK_CHAN] = argv[TOK_TEXT]; 143 snprintf(message, PIPE_BUF, "-!- %s(%s) has joined %s", argv[TOK_NICKSRV], argv[TOK_USER], argv[TOK_TEXT]); 144 + add_name(argv[TOK_CHAN],argv[TOK_NICKSRV]); 145 } else if(!strncmp("PART", argv[TOK_CMD], 5)) { 146 snprintf(message, PIPE_BUF, "-!- %s(%s) has left %s", argv[TOK_NICKSRV], argv[TOK_USER], argv[TOK_CHAN]); 147 + rm_name(argv[TOK_CHAN],argv[TOK_NICKSRV]); 148 } else if(!strncmp("MODE", argv[TOK_CMD], 5)) 149 snprintf(message, PIPE_BUF, "-!- %s changed mode/%s -> %s %s", argv[TOK_NICKSRV], argv[TOK_CMD + 1] ? argv[TOK_CMD + 1] : "" , argv[TOK_CMD + 2]? argv[TOK_CMD + 2] : "", argv[TOK_CMD + 3] ? argv[TOK_CMD + 3] : ""); 150 - else if(!strncmp("QUIT", argv[TOK_CMD], 5)) 151 - snprintf(message, PIPE_BUF, "-!- %s(%s) has quit \"%s\"", argv[TOK_NICKSRV], argv[TOK_USER], argv[TOK_TEXT] ? argv[TOK_TEXT] : ""); 152 - else if(!strncmp("NICK", argv[TOK_CMD], 5)) 153 - snprintf(message, PIPE_BUF, "-!- %s changed nick to %s", argv[TOK_NICKSRV], argv[TOK_TEXT]); 154 - else if(!strncmp("TOPIC", argv[TOK_CMD], 6)) 155 + else if(!strncmp("QUIT", argv[TOK_CMD], 5)) { 156 + quit_name(argv[TOK_NICKSRV], argv[TOK_USER], argv[TOK_TEXT]); 157 + return; 158 + } else if(!strncmp("NICK", argv[TOK_CMD], 5)) { 159 + nick_name(argv[TOK_NICKSRV], argv[TOK_TEXT]); 160 + return; 161 + } else if(!strncmp("TOPIC", argv[TOK_CMD], 6)) 162 snprintf(message, PIPE_BUF, "-!- %s changed topic to \"%s\"", argv[TOK_NICKSRV], argv[TOK_TEXT] ? argv[TOK_TEXT] : ""); 163 - else if(!strncmp("KICK", argv[TOK_CMD], 5)) 164 + else if(!strncmp("KICK", argv[TOK_CMD], 5)) { 165 snprintf(message, PIPE_BUF, "-!- %s kicked %s (\"%s\")", argv[TOK_NICKSRV], argv[TOK_ARG], argv[TOK_TEXT] ? argv[TOK_TEXT] : ""); 166 - else if(!strncmp("NOTICE", argv[TOK_CMD], 7)) 167 + rm_name(argv[TOK_CHAN],argv[TOK_NICKSRV]); 168 + } else if(!strncmp("NOTICE", argv[TOK_CMD], 7)) 169 snprintf(message, PIPE_BUF, "-!- \"%s\")", argv[TOK_TEXT] ? argv[TOK_TEXT] : ""); 170 else if(!strncmp("PRIVMSG", argv[TOK_CMD], 8)) 171 snprintf(message, PIPE_BUF, "<%s> %s", argv[TOK_NICKSRV], argv[TOK_TEXT] ? argv[TOK_TEXT] : "");