📄 irc.c
字号:
#ifdef HAVE_CONFIG_H# include <config.h>#endif#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <time.h>#include <ctype.h>#include <sys/socket.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/time.h>#include <ncurses.h>#include "defines.h"#include "colors.h"#include "codes.h"#include "scheck.h"#include "scmds.h"#include "nap.h"#include "winio.h"#include "irc.h"#include "alias.h"#include "lists.h"#ifdef MEMWATCH #include "memwatch.h"#endifextern info_t info;extern chans_t *chanl, *curchan, *recent;extern int wmode;extern int tind;int ircsock = 0;char *nbuf;char *mnick = NULL;int ircin=0, ircmode=0, nwho=0;char ircbuf[4096] = "\0";int cpos = 0, cport = -1;in_irc_cmd_t handlers[] = { { "ping", hping }, { "433", h433 }, { "372", h372 }, { "353", h353 }, { "332", h332 }, { "333", h333 }, { "311", h311 }, { "319", h319 }, { "312", h312 }, { "367", h367 }, { "376", h376 }, { "315", h315 }, { "352", h352 }, { "324", h324 }, { "341", h341 }, { "314", h314 }, { "317", h317 }, { "313", h313 }, { "join", hjoin }, { "part", hpart }, { "topic", htopic }, { "quit", hquit }, { "nick", hnick }, { "mode", hmode }, { "kick", hkick }, { "privmsg", hprivmsg }, { "notice", hnotice }, { "invite", hinvite }, { "482", herr }, { "475", herr }, { "474", herr }, { "473", herr }, { "472", herr }, { "471", herr }, { "461", herr }, { "443", herr }, { "442", herr }, { "421", herr }, { "406", herr }, { "404", herr }, { "401", herr }, { "error", herr2 }, { NULL, 0 }};out_irc_cmd_t outs[] = { { "msg", imsg }, { "quit", iquit }, { "kick", ikick }, { "me", ime }, { "notice", inotice }, { "nick", inick }, { "irc", iirc }, { "whois", iwhois }, { "topic", itopic }, { "part", ipart }, { "addr", iaddr }, { "ban", iban }, { "nap", inap }, { "ctcp", ictcp }, { "invite", iinvite }, { "opsay", iopsay }, { "dcc", idcc }, { "chat", ichat }, { NULL, NULL },};int dccfunc(WINDOW *win, sock_t *m){ char *nm = strchr(m->socknm, ' ')+1; unsigned char msg[1024]; int i; memset(msg, 0, sizeof(msg)); for (i=0;i<1024;i++) { if (read(m->fd, msg+i, 1) <= 0) { wp(win, "%s* DCC Connection to %s closed%s\n", RED, nm, WHITE); drw(win); delsock(m->fd); return(1); } if (msg[i] == '\n') { msg[i] = 0; if (i > 0 && msg[i-1] == '\r') msg[i-1] = 0; break; } } wp(win, "%s* [%s(%s)%s]%s %s\n", BRIGHT(GREEN), WHITE, nm, BRIGHT(GREEN), WHITE, msg); drw(win); return(1);}int ldcc(WINDOW *win, sock_t *m){ int s; struct sockaddr_in frm; int frmlen = sizeof(frm); char *nm=NULL; s = accept(m->fd, (struct sockaddr *)&frm, &frmlen); if (s == -1) { delsock(m->fd); return(1); } msprintf(&nm, "chat %s", strchr(m->socknm, ' ')+1); addsock(s, nm, S_R, dccfunc); free(nm); wp(win, "%s* DCC Connection to %s established%s\n", BRIGHT(CYAN), strchr(m->socknm, ' ')+1, WHITE); drw(win); delsock(m->fd); return(1);}int inirc(WINDOW *win, sock_t *m){ int s = m->fd, i, r, cnt, pt, j; char buf[4096], **tok; sock_t *t; memset(buf, 0, sizeof(buf)); j = recv(s, &buf, sizeof(buf), MSG_PEEK); if (j <= 0) { wp(win, "%s* Disconnected from IRC server%s\n", RED, WHITE); drw(win); close(ircsock); ircsock = 0; ircin = 0; nwho = 0; delircchans(); if (wmode && screen==MAIN_SCREEN) { dscr(win); drw(win); indraw(); dstatus(); } ircmode = 0; mnick = NULL; delsock(m->fd); return(1); } if (!strchr(buf, '\n') && !(*ircbuf)) { r = recv(s, ircbuf, j, 0); cpos += r; return(1); } else if (!(*ircbuf)) { for (i=0;buf[i]!='\n';i++); memset(buf, 0, sizeof(buf)); r = recv(s, buf, i+1, 0); } else if (!strchr(buf, '\n')) { r = recv(s, ((char *)ircbuf)+cpos, j, 0); cpos += r; return(1); } else { for (i=0;buf[i]!='\n';i++); r = recv(s, ((char *)ircbuf)+cpos, i+1, 0); cpos = 0; strcpy(buf, ircbuf); memset(ircbuf, 0, sizeof(ircbuf)); } if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = 0; if (buf[strlen(buf)-1] == '\r') buf[strlen(buf)-1] = 0; if (nvar("debug") == 2) { wp(win, "<-- |%s|\n", buf); drw(win); } tok = form_tokso(buf, &cnt); if (*buf == ':') pt = 1; else pt = 0; for (i=0;;i++) { if (!handlers[i].text) { if (nvar("debug") == 1) { wp(win, "<-- |%s|\n", buf); drw(win); } for (i=0;tok[i];i++) free(tok[i]); free(tok); return(1); } if (!strcasecmp(tok[pt], handlers[i].text)) { r = handlers[i].func(s, buf, tok, cnt, win); for (i=0;tok[i];i++) free(tok[i]); free(tok); t = findsock("input"); if (t) { indraw(); } dstatus(); if (!r) { delsock(m->fd); } return(1); } } if (!r) { delsock(m->fd); } return(1);}char *gnick(char *in){ int i; for (i=0;in[i]!='!';i++) { if (!in[i]) { nbuf = strdup(in); return(nbuf); } } nbuf = (char *)malloc(i+1); memset(nbuf, 0, i+1); strncpy(nbuf, in, i); return(nbuf);}/* delete all irc channels (retain napster channels) */void delircchans(){ chans_t *c; while (1) { list_find(c, chanl, c->q == 2); if (!c) { break; } delchan(c); }}/* delete all napster channels (retain irc channels) */void delnapchans(){ chans_t *c; while (1) { list_find(c, chanl, c->q != 2); if (!c) { break; } delchan(c); }}int checkouts(int s, char *str, char **tok, int num, WINDOW *win){ int i; for (i=0;;i++) { if (!outs[i].text) return(0); if (!strcasecmp(outs[i].text, tok[0])) { outs[i].func(s, str, tok, num, win); return(1); } }}I_IRC_FUNC(hping){ ssock(s, "PONG %s\n", tok[1]); return(1);}I_IRC_FUNC(h433){ if (!ircin && mnick && mnick[strlen(mnick)-1] != '_') { strcat(mnick, "_"); ssock(s, "NICK %s\n", mnick); return(1); } if (!ircin) { if (mnick) free(mnick); mnick = NULL; } wp(win, "%s* Nickname is already taken, specify a new one%s\n", RED, WHITE); drw(win); return(1);}I_IRC_FUNC(h372){ wp(win, "%s* %s%s\n", YELLOW, str+strlen(tok[0])+strlen(tok[1])+strlen(tok[2])+4, WHITE); drw(win); return(1);}I_IRC_FUNC(h353){ int i, c, j; chans_t *cur; user_t *usr; cur = findchan(chanl, tok[4]); if (!cur) return(1); recent = cur; wp(win, "%s* Users %s:%s\n", YELLOW, cur->nm, WHITE); for (i=5,c=0;i<num;i++) { if (c == 4) { wp(win, "\n"); c = 0; } if (!(*tok[i])) continue; if (i == 5) { c++; wp(win, "%s[%s%s", DARK, WHITE, tok[i]+1); for (j=16-strlen(tok[i]+1);j>=0;j--) wp(win, " "); wp(win, "%s]%s", DARK, WHITE); if (*(tok[i]+1) == '@' || *(tok[i]+1) == '+') { if (finduser(cur, tok[i]+2)) continue; adduser(cur, tok[i]+2, 0, 0); usr = finduser(cur, tok[i]+2); if (*(tok[i]+1) == '@') usr->flag |= NAP_OP; else usr->flag |= NAP_VOICE; } else { if (finduser(cur, tok[i]+1)) continue; adduser(cur, tok[i]+1, 0, 0); } } else { c++; wp(win, "%s[%s%s", DARK, WHITE, tok[i]); for (j=16-strlen(tok[i]);j>=0;j--) wp(win, " "); wp(win, "%s]%s", DARK, WHITE); if (*tok[i] == '@' || *tok[i] == '+') { if (finduser(cur, tok[i]+1)) continue; adduser(cur, tok[i]+1, 0, 0); usr = finduser(cur, tok[i]+1); if (*tok[i] == '@') usr->flag |= NAP_OP; else usr->flag |= NAP_VOICE; } else { if (finduser(cur, tok[i])) continue; adduser(cur, tok[i], 0, 0); } } } if (c) wp(win, "\n"); drw(win); recent = NULL; return(1);}I_IRC_FUNC(hjoin){ chans_t *cur, *cur1=NULL; char *nk = gnick(tok[0]+1); if (strcasecmp(nk, mnick)) { if (!(cur = findchan(chanl, tok[2]+1))) { free(nk); return(1); } adduser(cur, nk, 0, 0); finduser(cur, nk)->addr = strdup(tok[0]+strlen(nk)+2); recent = cur; wp(win, "%s* %s (%s%s%s) has joined %s%s\n", BRIGHT(GREEN), nk, WHITE, tok[0]+strlen(nk)+2, BRIGHT(GREEN), cur->nm, WHITE); drw(win); recent = NULL; free(nk); return(1); } if (!chanl) { chanl = (chans_t *)malloc(sizeof(chans_t)); cur = chanl; } else { for (cur=chanl;cur!=NULL;cur=cur->next) cur1 = cur; cur = (chans_t *)malloc(sizeof(chans_t)); cur1->next = cur; } cur->nm = strdup(tok[2]+1); cur->users = NULL; cur->q = 2; cur->key = 0; cur->l = 0; cur->flag = 0; cur->topic = NULL; cur->p = 0; cur->next = NULL; curchan = cur; ssock(s, "MODE %s\n", cur->nm); ssock(s, "WHO %s\n", cur->nm); nwho++; free(nk); return(1);}I_IRC_FUNC(hpart){ chans_t *cur, *pt; char *nk = gnick(tok[0]+1); if (strcasecmp(nk, mnick)) { if (!(cur = findchan(chanl, tok[2]))) { free(nk); return(1); } deluser(cur, nk); recent = cur; wp(win, "%s* %s (%s%s%s) has left %s%s\n", GREEN, nk, WHITE, tok[0]+strlen(nk)+2, GREEN, cur->nm, WHITE); drw(win); recent = NULL; free(nk); return(1); } pt = findchan(chanl, tok[2]); wp(win, "%s* Left channel %s%s\n", GREEN, pt->nm, WHITE); drw(win); delchan(pt); drw(win); free(nk); return(1);}I_IRC_FUNC(hquit){ chans_t *cur; char *nk = gnick(tok[0]+1); for (cur=chanl;cur;cur=cur->next) { if (finduser(cur, nk)) { recent = cur; if (wmode) wp(win, "%s* %s (%s%s%s) has quit IRC (%s%s%s)%s\n", BRIGHT(BLUE), nk, WHITE, tok[0]+strlen(nk)+2, BRIGHT(BLUE), WHITE, str+strlen(tok[0])+strlen(tok[1])+3, BRIGHT(BLUE), WHITE); deluser(cur, nk); recent = NULL; } } if (!wmode) wp(win, "%s* %s (%s%s%s) has quit IRC (%s%s%s)%s\n", BRIGHT(BLUE), nk, WHITE, tok[0]+strlen(nk)+2, BRIGHT(BLUE), WHITE, str+strlen(tok[0])+strlen(tok[1])+3, BRIGHT(BLUE), WHITE); drw(win); free(nk); return(1);}I_IRC_FUNC(hnick){ chans_t *cur; char *nk = gnick(tok[0]+1); user_t *usr; for (cur=chanl;cur;cur=cur->next) { if ((usr = finduser(cur, nk))) { recent = cur; if (wmode) wp(win, "%s* %s has changed his nick to %s%s\n", BRIGHT(YELLOW), nk, tok[2]+1, WHITE); free(usr->nm); usr->nm = strdup(tok[2]+1); } } if (!wmode) wp(win, "%s* %s has changed his nick to %s%s\n", BRIGHT(YELLOW), nk, tok[2]+1, WHITE); drw(win); if (!strcasecmp(nk, mnick)) { free(mnick); mnick = strdup(tok[2]+1); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -