diff options
-rw-r--r-- | include/users.h | 11 | ||||
-rw-r--r-- | src/inspircd.cpp | 27 | ||||
-rw-r--r-- | src/users.cpp | 41 |
3 files changed, 63 insertions, 16 deletions
diff --git a/include/users.h b/include/users.h index 098762eca..a897d8282 100644 --- a/include/users.h +++ b/include/users.h @@ -173,6 +173,12 @@ class userrec : public connection */ char password[MAXBUF]; + /** User's receive queue. + * Lines from the IRCd awaiting processing are stored here. + * Upgraded april 2005, old system a bit hairy. + */ + std::string recvq; + userrec(); virtual ~userrec() { } @@ -209,6 +215,11 @@ class userrec : public connection * this to their oper classes and checking the commands they can execute. */ bool HasPermission(char* command); + + void userrec::AddBuffer(std::string a); + bool userrec::BufferIsReady(); + void userrec::ClearBuffer(); + std::string userrec::GetBuffer(); }; diff --git a/src/inspircd.cpp b/src/inspircd.cpp index ee6fa803a..cb702245c 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -3863,7 +3863,7 @@ int InspIRCd(void) tvs.tv_sec = 0; tv.tv_sec = 0; tv.tv_usec = 10000L; - char data[10240]; + char data[65535]; timeval tval; fd_set sfd; tval.tv_usec = 10000L; @@ -4065,11 +4065,11 @@ int InspIRCd(void) result = EAGAIN; if ((count2a->second->fd != FD_MAGIC_NUMBER) && (count2a->second->fd != -1) && (FD_ISSET (count2a->second->fd, &sfd))) { - memset(data, 0, 10240); - result = read(count2a->second->fd, data, 10240); - + result = read(count2a->second->fd, data, 65535); if (result) { + if (result > 0) + data[result] = '\0'; // perform a check on the raw buffer as an array (not a string!) to remove // characters 0 and 7 which are illegal in the RFC - replace them with spaces. // hopefully this should stop even more people whining about "Unknown command: *" @@ -4080,9 +4080,11 @@ int InspIRCd(void) } userrec* current = count2a->second; int currfd = current->fd; - char* l = strtok(data,"\n"); + //char* l = strtok(data,"\n"); int floodlines = 0; - while (l) + current->AddBuffer(data); + // while there are complete lines to process... + while (current->BufferIsReady()) { floodlines++; if ((floodlines > current->flood) && (current->flood != 0)) @@ -4094,15 +4096,8 @@ int InspIRCd(void) } char sanitized[NetBufferSize]; memset(sanitized, 0, NetBufferSize); - int ptt = 0; - for (int pt = 0; pt < strlen(l); pt++) - { - if (l[pt] != '\r') - { - sanitized[ptt++] = l[pt]; - } - } - sanitized[ptt] = '\0'; + // use GetBuffer to copy single lines into the sanitized string + strlcpy(sanitized,current->GetBuffer().c_str(),MAXBUF); if (*sanitized) { @@ -4127,7 +4122,7 @@ int InspIRCd(void) goto label; } - l = strtok(NULL,"\n"); + //l = strtok(NULL,"\n"); } goto label; } diff --git a/src/users.cpp b/src/users.cpp index c0332dbe4..40589b234 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -44,6 +44,7 @@ userrec::userrec() flood = port = bytes_in = bytes_out = cmds_in = cmds_out = 0; haspassed = false; dns_done = false; + recvq = ""; strcpy(result,""); for (int i = 0; i < MAXCHANS; i++) { @@ -163,3 +164,43 @@ bool userrec::HasPermission(char* command) } +void userrec::AddBuffer(std::string a) +{ + std::string b = ""; + for (int i = 0; i < a.length(); i++) + if ((a[i] != '\r') && (a[i] != '\0') && (a[i] != 7)) + b = b + a[i]; + std::stringstream stream(recvq); + stream << b; + recvq = stream.str(); +} + +bool userrec::BufferIsReady() +{ + for (int i = 0; i < recvq.length(); i++) + if (recvq[i] == '\n') + return true; + return false; +} + +void userrec::ClearBuffer() +{ + recvq = ""; +} + +std::string userrec::GetBuffer() +{ + log(DEBUG,"GetBuffer\n%s\n",recvq.c_str()); + char* line = (char*)recvq.c_str(); + std::string ret = ""; + while ((*line != '\n') && (strlen(line))) + { + ret = ret + *line; + line++; + } + if ((*line == '\n') || (*line == '\r')) + line++; + recvq = line; + return ret; +} + |