From bfdcd8473ce5d239441f651558d6624d04363850 Mon Sep 17 00:00:00 2001 From: Sound and Fury Date: Sat, 21 Aug 2010 17:35:26 +0100 Subject: [PATCH] Handle Low-Level Quoting Quote character is \020 (^P), to which MQUOTE is defined in irc.h ^P n => \n ^P r => \r ^P 0 => \0 (may break things; this needs dealing with) ^P ^P => ^P --- irc.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- irc.h | 4 +++ 2 files changed, 84 insertions(+), 7 deletions(-) diff --git a/irc.c b/irc.c index 9b47cca..c1c4085 100644 --- a/irc.c +++ b/irc.c @@ -95,7 +95,9 @@ int autoconnect(fd_set *master, int *fdmax) int irc_tx(int fd, char * packet) { //printf(">> %s\n\n", packet); // for debugging purposes - unsigned long l=strlen(packet)+1; + char pq[512]; + low_quote(packet, pq); + unsigned long l=max(strlen(packet)+1, 511); unsigned long p=0; while(p0) { - char c=(*data)[l]; + char c=buf[l]; if((strchr("\n\r", c)!=NULL) || (l>510)) { cr=true; - (*data)[l]=0; + buf[l]=0; } l++; } } + *data=low_dequote(buf); + if(!*data) + return(1); return(0); } +void low_quote(char *from, char to[512]) +{ + int o=0; + while((*from) && (o<510)) + { + char c=*from++; + switch(c) + { + case '\n': + to[o++]=MQUOTE; + to[o++]='n'; + break; + case '\r': + to[o++]=MQUOTE; + to[o++]='r'; + break; + case MQUOTE: + to[o++]=MQUOTE; + to[o++]=MQUOTE; + break; + case 0: // can't happen right now + to[o++]=MQUOTE; + to[o++]='0'; + break; + default: + to[o++]=c; + break; + } + } + to[o]=0; +} + +char * low_dequote(char *buf) +{ + char *rv=(char *)malloc(512); + if(!rv) return(NULL); + char *p=buf; + int o=0; + while(*p) + { + if(*p==MQUOTE) + { + char c=*++p; + switch(c) + { + case '0': + rv[o]=0; // Warning: this may break things using strlen() etc. TODO: replace char * everywhere with a string datatype that can handle embedded \0s + break; + case 'n': + rv[o]='\n'; + break; + case 'r': + rv[o]='\r'; + break; + case MQUOTE: // MQUOTE MQUOTE => MQUOTE, so fall through + default: + rv[o]=c; + break; + } + } + else + { + rv[o]=*p; + } + p++;o++; + } + rv[o]=0; + return(rv); +} + int irc_numeric(char *cmd, int b) // TODO check the strtok()s for NULLs { int num=0; diff --git a/irc.h b/irc.h index 2e35d5b..069bd59 100644 --- a/irc.h +++ b/irc.h @@ -25,10 +25,14 @@ #include "config.h" #include "numeric.h" +#define MQUOTE '\020' + int irc_connect(char *server, char *portno, char *nick, char *username, char *fullname, fd_set *master, int *fdmax); int autoconnect(fd_set *master, int *fdmax); int irc_tx(int fd, char * packet); int irc_rx(int fd, char ** data); +void low_quote(char *from, char to[512]); +char * low_dequote(char *buf); // Received-IRC message handlers. strtok() state leaks across the boundaries of these functions, beware! int irc_numeric(char *cmd, int b);