aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorepochqwert <epoch@hacking.allowed.org>2015-10-05 00:37:02 -0500
committerepochqwert <epoch@hacking.allowed.org>2015-10-05 00:37:02 -0500
commit617c641f21c4be1e14d463dec89821daa112b58d (patch)
tree44cca462fa06f13b75bd16c526d967df1028ca07
parent66e6d359ac08684ed63541548ac7fdb7309abf11 (diff)
downloadlibirc-617c641f21c4be1e14d463dec89821daa112b58d.tar.gz
libirc-617c641f21c4be1e14d463dec89821daa112b58d.zip
fixed up some of runem that hadn't been made for multiple fds.
update to link example bot to use line_cutter
-rw-r--r--examples/link.c63
-rw-r--r--libirc.c106
2 files changed, 99 insertions, 70 deletions
diff --git a/examples/link.c b/examples/link.c
index 680550c..3d5a0cc 100644
--- a/examples/link.c
+++ b/examples/link.c
@@ -33,70 +33,36 @@ void message_handler(int fd,char *from,struct user *user,char *line) {
}
void line_handler(int fd,char *line) {//this should be built into the libary?
- char *s=line,*t=0,*u=0;
char *temp;
+ char **a;
char tmp[512];
struct user *user=malloc(sizeof(struct user));
- 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;
printf("line: '%s'\n",line);
- if(line[0]==':') {
- if((user->nick=strchr(line,':'))) {
- *(user->nick)=0;
- (user->nick)++;
- }
- }
- if(user->nick) {
- if((s=strchr((user->nick),' '))) {
- *s=0;
- s++;
- if((t=strchr(s,' '))) {
- *t=0;
- t++;
- if((u=strchr(t,' '))) {//:
- *u=0;
- u++;
- }
- }
- }
- 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;
- }
- }
- if(!user->user && s) {
- if(!strcmp(s,"004")) {
+ a=line_cutter(fd,line,user);
+ if(!user->user && a[0]) {
+ if(!strcmp(a[0],"004")) {
snprintf(tmp,sizeof(tmp)-1,"JOIN %s\r\n",chans[fdtoi(fd)]);
temp=strchr(chans[fdtoi(fd)],' ');
if(temp) *temp=0;
mywrite(fd,tmp);
}
}
- if(s && t && u) {
- if(!strcmp(s,"PRIVMSG")) {
- message_handler(fd,*t=='#'?t:user->nick,user,++u);
+ if(a[0] && a[1] && a[2]) {
+ if(!strcmp(a[0],"PRIVMSG")) {
+ message_handler(fd,*a[1]=='#'?a[1]:user->nick,user,a[2]);
}
}
- if(s && user->nick && t) {
- if(!strcmp(s,"JOIN")) {
- snprintf(tmp,sizeof(tmp)-1,"%cACTION %s has joined %s%c",1,user->nick,t+(*t==':'),1);
+ if(a[0] && user->nick && a[1]) {
+ if(!strcmp(a[0],"JOIN")) {
+ snprintf(tmp,sizeof(tmp)-1,"%cACTION %s has joined %s%c",1,user->nick,a[1]+(*a[1]==':'),1);
privmsg_others(fd,tmp);
}
- if(!strcmp(s,"PART")) {
- snprintf(tmp,sizeof(tmp)-1,"%cACTION %s has parted %s%c",1,user->nick,t+(*t==':'),1);
+ if(!strcmp(a[0],"PART")) {
+ snprintf(tmp,sizeof(tmp)-1,"%cACTION %s has parted %s%c",1,user->nick,a[1]+(*a[1]==':'),1);
privmsg_others(fd,tmp);
}
- if(!strcmp(s,"QUIT")) {
- snprintf(tmp,sizeof(tmp)-1,"%cACTION %s has quited %s%c",1,user->nick,t+(*t==':'),1);
+ if(!strcmp(a[0],"QUIT")) {
+ snprintf(tmp,sizeof(tmp)-1,"%cACTION %s has quited %s%c",1,user->nick,a[1]+(*a[1]==':'),1);
privmsg_others(fd,tmp);
}
}
@@ -119,6 +85,7 @@ int main(int argc,char *argv[]) {
for(i=0;((i*3)+3)<argc;i++) {
printf("%d server: %s port: %s channel: %s\n",i,argv[(i*3)+1],argv[(i*3)+2],argv[(i*3)+3]);
fds[i]=serverConnect(argv[(i*3)+1],argv[(i*3)+2]);
+ if(fds[i] == -1) return 1;
chans[i]=strdup(argv[(i*3)+3]);
mywrite(fds[i],"NICK link8239\r\nUSER a b c :d\r\n");
}
diff --git a/libirc.c b/libirc.c
index 9344766..13e3458 100644
--- a/libirc.c
+++ b/libirc.c
@@ -26,7 +26,7 @@ int serverConnect(char *serv,char *port) {
int s[2];
int pid;
int try_ipv4;
- char *name[3];
+ char *name[4];
char buf[SILLYLIMIT];
struct addrinfo hints, *servinfo, *p=0;
struct hostent *he;
@@ -37,7 +37,11 @@ int serverConnect(char *serv,char *port) {
if(*serv == '|') {
name[0]=serv+1;
name[1]=port;
- name[2]=0;
+ if((name[2]=strchr(port,' '))) {
+ *name[2]=0;
+ name[2]++;
+ name[3]=0;
+ }
socketpair(PF_LOCAL,SOCK_STREAM,0,s);
if(!(pid=fork())) {
dup2(s[1],fileno(stdin));
@@ -45,6 +49,7 @@ int serverConnect(char *serv,char *port) {
execv(name[0],name);
}
if(pid == -1) return -1;
+ printf("libirc: serverConnect: returning something! %d\n",fd);
return s[0];
}
memset(&hints,0,sizeof hints);
@@ -65,9 +70,17 @@ int serverConnect(char *serv,char *port) {
,hints.ai_family))) continue;
for(;*(he->h_addr_list);(he->h_addr_list)++) {
inet_ntop(hints.ai_family,*(he->h_addr_list),buf,SILLYLIMIT);
- if(!getaddrinfo(buf,port,&hints,&servinfo))
- for(p=servinfo;p;p=p->ai_next)
- if(connect(fd,p->ai_addr, p->ai_addrlen) < 0) continue; else return fd;
+ if(!getaddrinfo(buf,port,&hints,&servinfo)) {
+ for(p=servinfo;p;p=p->ai_next) {
+ if(connect(fd,p->ai_addr, p->ai_addrlen) < 0) {
+ printf("libirc: serverConnect: trying something else...\n");
+ continue;
+ } else {
+ printf("libirc: serverConnect: returning something! %d\n",fd);
+ return fd;
+ }
+ }
+ }
}
}
printf("I tried as hard as I could and couldn't connect to %s:%s\n",serv,port);
@@ -80,8 +93,29 @@ int fdlen(int *fds) {
return i+1;
}
+
+char *memstr(char *s,char *find,size_t l) {
+ return memmem(s,l,find,strlen(find));
+}
+
+/* already in string.h!
+char *memmem(char *s,char *find,size_t sl,size_t fl) {
+ size_t i,j,fl;
+ if(!s) return 0;
+ if(!find) return 0;
+ for(i=0;i<l;i++) {
+ for(j=0;j<fl;j++) {
+ if(s[i] != find[j]) break;
+ }
+ if(j == fl) return s+i;
+ }
+ return 0;
+}
+*/
+
int runem(int *fds,void (*line_handler)(),void (*extra_handler)()) {
int j;
+ int hack;
int fdl=fdlen(fds);
fd_set master;
fd_set readfs;
@@ -89,17 +123,19 @@ int runem(int *fds,void (*line_handler)(),void (*extra_handler)()) {
int fdmax=0,n,i;
char *backlogs[fdl];
char *t,*line=0;
- int blsize=CHUNK;
- int bllen=0;
+ int blsize[fdl];
+ int bllen[fdl];
char buffers[fdl][CHUNK];//THIS IS *NOT* NULL TERMINATED.
if(fds[0] == -1) return 0;
FD_ZERO(&master);
FD_ZERO(&readfs);
for(i=0;fds[i] != -1;i++) {
FD_SET(fds[i],&master);
- backlogs[i]=malloc(CHUNK+1);
+ backlogs[i]=malloc(CHUNK);
memset(backlogs[i],0,CHUNK);
memset(buffers[i],0,CHUNK);
+ blsize[i]=CHUNK;
+ bllen[i]=0;
fdmax=fds[i]>fdmax?fds[i]:fdmax;
}
for(;;) {
@@ -112,31 +148,56 @@ int runem(int *fds,void (*line_handler)(),void (*extra_handler)()) {
for(i=0;fds[i] != -1;i++) {
if(!FD_ISSET(fds[i],&readfs)) continue;
if((n=recv(fds[i],buffers[i],CHUNK,0)) <= 0) return (perror("recv"),2);
- buffers[i][n]=0;//deff right.
- if(bllen+n >= blsize) {//this is probably off...
- blsize+=n;
- t=malloc(blsize);
+ if(bllen[i]+n > blsize[i]) {//this is probably off...
+ t=malloc(blsize[i]+n);
if(!t) exit(253);
- memcpy(t,backlogs[i],blsize-n+1);
+ memcpy(t,backlogs[i],blsize[i]);
+ blsize[i]+=n;
free(backlogs[i]);
backlogs[i]=t;
}
- memcpy(backlogs[i]+bllen,buffers[i],n);
- bllen+=n;
- while((t=strstr(backlogs[i],"\r\n"))) {
+ memcpy(backlogs[i]+bllen[i],buffers[i],n);
+ bllen[i]+=n;
+
+ //manually loop?
+//works for IRC that uses \r\n. need to make it work for just \n too?
+/*
+ while((t=memstr(backlogs[i],"\r\n",bllen[i]))) {//no. backlogs aren't nulled.
line=backlogs[i];
- if(!strncmp(line,"PING",4)) {
+ if((t-backlogs[i]) >=4 && !strncmp(line,"PING",4)) {
line[1]='O';
write(fds[i],line,t-backlogs[i]+2);
} else {
- if(!strncmp(line,"ERROR",5)) return 0;
+ if(!strncmp(line,"ERROR",5)) return 0;
*t=0;
- line_handler(fds[i],line);
+ if(line_handler) line_handler(fds[i],line);
}
- bllen-=((t+2)-backlogs[i]);
- if(bllen <= 0) bllen=0;
- else memmove(backlogs[i],(t+2),bllen);
+ bllen[i]-=((t+2)-backlogs[i]);
+ if(bllen[i] <= 0) bllen[i]=0;
+ else memmove(backlogs[i],(t+2),bllen[i]);
}
+*/
+ while((t=memchr(backlogs[i],'\n',bllen[i]))) {//no. backlogs aren't nulled.
+ line=backlogs[i];
+ if(*(t-1) == '\r') {
+ t--;
+ hack=2;
+ } else {
+ hack=1;
+ }
+ if((t-backlogs[i]) >=4 && !strncmp(line,"PING",4)) {
+ line[1]='O';
+ write(fds[i],line,t-backlogs[i]+hack);
+ } else {
+ if(!strncmp(line,"ERROR",5)) return 0;
+ *t=0;
+ if(line_handler) line_handler(fds[i],line);
+ }
+ bllen[i]-=((t+hack)-backlogs[i]);
+ if(bllen[i] <= 0) bllen[i]=0;
+ else memmove(backlogs[i],(t+hack),bllen[i]);
+ }
+
}
}
return 0;
@@ -168,6 +229,7 @@ int ircConnect(char *serv,char *port,char *nick,char *user) {
char **line_cutter(int fd,char *line,struct user *user) {
int i;
char **a=malloc(sizeof(char *) * 256);//heh.
+ if(!a) exit(54);
memset(a,0,sizeof(char *) * 256);
if(!user) return 0;
user->nick=0;