diff options
-rw-r--r-- | libhashtable/libhashtable.c | 23 | ||||
-rw-r--r-- | libirc/irc.h | 1 | ||||
-rw-r--r-- | libirc/libirc.c | 117 | ||||
-rw-r--r-- | segfault.c | 58 |
4 files changed, 146 insertions, 53 deletions
diff --git a/libhashtable/libhashtable.c b/libhashtable/libhashtable.c index 02b981e..496a3ee 100644 --- a/libhashtable/libhashtable.c +++ b/libhashtable/libhashtable.c @@ -129,32 +129,37 @@ int ht_setkey(struct hashtable *ht,char *key,void *value) { return 0; } -struct entry *ll_getentry(struct entry *start,char *msg) { +struct entry *ll_getentry(struct entry *start,char *key) { struct entry *m; - if(!msg) return NULL; + if(!key) return NULL; if(!start) return NULL; for(m=start;m;m=m->next) { - if(!strncmp(msg,m->original,strlen(m->original)) && (msg[strlen(m->original)]==' ' || msg[strlen(m->original)] == 0)) {//this allows !c to get called when using !c2 if !c2 is defined after !c. >_> + if(!strncmp(key,m->original,strlen(m->original)) && (key[strlen(m->original)]==' ' || key[strlen(m->original)] == 0)) {//this allows !c to get called when using !c2 if !c2 is defined after !c. >_> return m; } } return NULL; } -//returns the linked list at the key. +//returns the table entry (a linked list) at the key. struct entry *ht_getentry(struct hashtable *ht,char *key) { unsigned short h=hash(key); if(!ht->bucket[h]) return NULL; return ht->bucket[h]->ll; } -//returns the node -struct entry *ht_getnode(struct hashtable *ht,char *msg) { - return ll_getentry(ht_getentry(ht,msg),msg); +//returns the node in the linked list in the table entry that matches the key. +struct entry *ht_getnode(struct hashtable *ht,char *key) { + return ll_getentry(ht_getentry(ht,key),key); } //you'll probably want to use me. -void *ht_getvalue(struct hashtable *ht,char *msg) { - struct entry *tmp=ll_getentry(ht_getentry(ht,msg),msg); +void *ht_getvalue(struct hashtable *ht,char *key) { + struct entry *tmp=ll_getentry(ht_getentry(ht,key),key); return tmp?tmp->target:0; } + +//delete the node in the linked list in the table entry that matches the key. +void *ht_delete(struct hashtable *ht,char *key) { + ll_delete(ht_getentry(ht,key)); +} diff --git a/libirc/irc.h b/libirc/irc.h index 4520bf4..231cd84 100644 --- a/libirc/irc.h +++ b/libirc/irc.h @@ -1,3 +1,4 @@ int runit(int fd,void (*line_handler)(),void (*extra_handler)()) ; int ircConnect(char *serv,char *port,char *nick,char *user) ; int serverConnect(char *serv,char *port) ; +char **line_cutter(int fd,char *line,struct user *user) ; diff --git a/libirc/libirc.c b/libirc/libirc.c index 2394459..dd1c0d0 100644 --- a/libirc/libirc.c +++ b/libirc/libirc.c @@ -12,29 +12,64 @@ //#define DEBUG "epoch" //nick or channel to send debug info to. #define CHUNK 4096 +int main(int argc,char *argv[]) { + return 0; +} + +#define SILLYLIMIT 256 + int serverConnect(char *serv,char *port) { - struct addrinfo hints, *servinfo, *p; int rv; int fd=0; + int n=1; + int try_ipv4=0; + char buf[SILLYLIMIT]; + struct addrinfo hints, *servinfo, *p=0; + struct in_addr saddr; + struct in6_addr saddr6; + struct hostent *he; memset(&hints,0,sizeof hints); hints.ai_family=AF_INET; hints.ai_socktype=SOCK_STREAM; if((fd=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP)) < 0) { perror("socket"); - return fd; + return -1; } - if((rv=getaddrinfo(serv,port,&hints,&servinfo)) != 0) { - fprintf(stderr,"error resolving '%s'.\n",serv); - return 0; - } - for(p=servinfo;p;p=p->ai_next) { - if (connect(fd,p->ai_addr, p->ai_addrlen) < 0) { - perror("connect"); - continue; - } - break; - } - return p?fd:0; +/* + for(try_ipv4=0;try_ipv4 < 2;try_ipv4++) { + if(!(he=gethostbyname2( + try_ipv4 + ?inet_aton(serv,&saddr) + ?inet_ntoa(saddr) + :serv + :inet_pton(AF_INET6,serv,&saddr6) + ?inet_ntop(AF_INET6,&saddr6,buf,SILLYLIMIT) + :serv + ,try_ipv4?AF_INET:AF_INET6))) return -1; + + for(;*(he->h_addr_list);he->h_addr_list++) { + printf("trying to connect to %s:%s attempt #%d\n",serv,port,n); + n++; +*/ +// if((rv=getaddrinfo(he->h_addr_list,port,&hints,&servinfo)) != 0) { + if((rv=getaddrinfo(serv,port,&hints,&servinfo)) != 0) { + fprintf(stderr,"error resolving '%s'.\n",serv); + return -1; + } + for(p=servinfo;p;p=p->ai_next) { + if(connect(fd,p->ai_addr, p->ai_addrlen) < 0) { + perror("connect"); + continue; + } else { + return fd; + } + } + //printf("trying a differnt address...\n"); + //} + //printf("trying a different AF...\n"); + //} + //printf("well, shit. how'd I get here?\n"); + return -1; } int fdlen(int *fds) { @@ -59,7 +94,7 @@ int runem(int *fds,void (*line_handler)(),void (*extra_handler)()) { FD_ZERO(&master); FD_ZERO(&readfs); for(i=0;fds[i] != -1;i++) { - if(!backlogs[i]) return 252; + //if(!backlogs[i]) return 252;//wtf is this here for? ofc they're not set! FD_SET(fds[i],&master); backlogs[i]=malloc(CHUNK+1); memset(backlogs[i],0,CHUNK); @@ -70,7 +105,7 @@ int runem(int *fds,void (*line_handler)(),void (*extra_handler)()) { while(!done) { for(fd=0;fd<=fdmax;fd++) { if(FD_ISSET(fd,&master)) { - extra_handler(fd); + if(extra_handler) extra_handler(fd); } } readfs=master; @@ -169,3 +204,53 @@ int ircConnect(char *serv,char *port,char *nick,char *user) { write(fd,sendstr,strlen(sendstr)); return fd; } + +struct user { + char *nick; + char *user; + char *host; +}; + +//this function mangles the input. +//gotta free the returned pointer but not each pointer in the array. +char **line_cutter(int fd,char *line,struct user *user) { + int i; + char **a=malloc(16);//heh. + memset(a,0,sizeof(char *)*16); + if(!user) return 0; + user->nick=0; + user->user=0; + user->host=0; + + if(strchr(line,'\r')) *strchr(line,'\r')=0; + if(strchr(line,'\n')) *strchr(line,'\n')=0; + if(line[0]==':') { + if((user->nick=strchr(line,':'))) { + *(user->nick)=0; + (user->nick)++; + } + } + if(user->nick) { + if((a[0]=strchr((user->nick),' '))) { + for(i=0;a[i+1]=strchr(a[i],' ') && i<15;i++) { + *a[i]=0; + a[i]++; + if(a[i][0] == ':') {//we're done. + a[i]++; + break; + } + } + } + if(((user->user)=strchr((user->nick),'!'))) { + *(user->user)=0; + (user->user)++; + if(((user->host)=strchr((user->user),'@'))) { + *(user->host)=0; + (user->host)++; + } + } else { + user->host=user->nick; + } + } + return a; +} @@ -1056,9 +1056,16 @@ void message_handler(int fd,char *from,struct user *user,char *msg,int redones) } void line_handler(int fd,char *line) {//this should be built into the libary? - char *s=line,*t=0,*u=0; char tmp[512]; struct user *user=malloc(sizeof(struct user)); + if(recording_raw) { + append_file(fd,"epoch",RAWLOG,line,'\n'); + } + //line will be mangled by the cutter. + char **a=line_cutter(fd,line,user); + +//stuff covered by line_cutter below here. +/* user->nick=0; user->user=0; user->host=0; @@ -1072,9 +1079,6 @@ void line_handler(int fd,char *line) {//this should be built into the libary? //only sub-parse nickuserhost stuff if starts with : //strchr doesn't like null pointers. :/ why not just take them and return null? //check that I haven't gone past the end of the string? nah. it should take care of itself. - if(recording_raw) { - append_file(fd,"epoch",RAWLOG,line,'\n'); - } if(line[0]==':') { if((user->nick=strchr(line,':'))) { *(user->nick)=0; @@ -1105,22 +1109,19 @@ void line_handler(int fd,char *line) {//this should be built into the libary? user->host=user->nick; } } - - printf("<%s!%s@%s> '%s' '%s' '%s'\n", - user->nick, - user->user, - user->host, - s,t,u); - if(!user->user && s) { //server message +*/ +//end of stuff covered by line_cutter + if(!user->user && a[0]) { //server message //:armitage.hacking.allowed.org 353 asdf = #default :@SegFault @FreeArtMan @foobaz @wall @Lamb3_13 @gizmore @blackh0le strcpy(tmp,"!"); - strcat(tmp,s); + strcat(tmp,a[0]); if(ht_getnode(&alias,tmp) == NULL && ht_getnode(&alias,"!###") != NULL) { strcpy(tmp,"!###"); +// privmsg(fd,*a[1]=='#'?a[1]:user->nick,a[0]); } if(ht_getnode(&alias,tmp) != NULL) { strcat(tmp," "); - strcat(tmp,u);//lol. fixme later. + strcat(tmp,a[2]);//lol. fixme. user->nick=strdup("epoch"); user->user=strdup("epoch"); user->host=strdup("localhost"); @@ -1130,37 +1131,38 @@ void line_handler(int fd,char *line) {//this should be built into the libary? free(user->host); } } - if(s && t && u) { - if(!strcmp(s,"PRIVMSG") && strcmp(user->nick,myuser->nick)) { + if(a[0] && a[1] && a[2]) { + if(!strcmp(a[0],"PRIVMSG") && strcmp(user->nick,myuser->nick)) { if(strcmp(user->nick,myuser->nick)) { - message_handler(fd,*t=='#'?t:user->nick,user,++u,0); + message_handler(fd,*a[1]=='#'?a[1]:user->nick,user,++a[2],0); } else { - if(debug) privmsg(fd,*t=='#'?t:user->nick,"This server has an echo"); + if(debug) privmsg(fd,*a[2]=='#'?a[2]:user->nick,"This server has an echo"); } } } - if(s && user->nick && t) { - if(!strcmp(s,"JOIN")) { - irc_mode(fd,t+(*t==':'),"+o",user->nick);//sometimes t will start with a : This check should go into the parser up there. + if(a[0] && user->nick && a[1]) { + if(!strcmp(a[0],"JOIN")) { + irc_mode(fd,a[1],"+o",user->nick); } - if(!strcmp(s,"MODE") && mode_magic) { - if(u) { - if(*u == '-') {//auto-give modes back that are removed in front of segfault. - *u='+'; - irc_mode(fd,t,u,"");//u contains the nick the mode is being removed from. + if(!strcmp(a[0],"MODE") && mode_magic) { + if(a[2]) { + if(*a[2] == '-') {//auto-give modes back that are removed in front of segfault. + *a[2]='+'; + irc_mode(fd,a[1],a[2],""); } } } - if(!strcmp(s,"NICK") && t) { + if(!strcmp(a[0],"NICK") && a[1]) { if(!strcmp(user->nick,myuser->nick)) { free(myuser->nick); - if(!t) exit(79); - if(!(myuser->nick=strdup(t+1))) exit(179); + if(!a[1]) exit(79); + if(!(myuser->nick=strdup(a[1]))) exit(179); } } } free(user); + free(a); } int main(int argc,char *argv[]) { |