diff --git a/lib/modules/Protocols.pmod/Line.pmod b/lib/modules/Protocols.pmod/Line.pmod index 53577f3175332765c214d2e5d125e688b57a9ea1..770d8c77593ba81637ddac2409a60b712214f0bd 100644 --- a/lib/modules/Protocols.pmod/Line.pmod +++ b/lib/modules/Protocols.pmod/Line.pmod @@ -1,5 +1,5 @@ /* - * $Id: Line.pmod,v 1.4 1998/10/10 00:54:32 grubba Exp $ + * $Id: Line.pmod,v 1.5 1998/10/12 15:44:27 nisse Exp $ * * Line-buffered protocol handling. * @@ -29,6 +29,7 @@ class simple con->close(); }; catch { + // FIXME: Don't do this. It will break SSL connections. /nisse destruct(con); }; } @@ -77,25 +78,29 @@ class simple } static string read_buffer = ""; + + static string get_line() + { + int i = search(read_buffer, "\r\n"); + if (i == -1) { + return 0; + } + string data = read_buffer[..i-1]; // Not the "\r\n". + read_buffer = read_buffer[i+2..]; + + return data; + } + static void read_callback(mixed ignored, string data) { touch_time(); read_buffer += data; - while(1) { - int i = search(read_buffer, "\r\n"); - if (i == -1) { - return; - } - data = read_buffer[..i-1]; // Not the "\r\n". - read_buffer = read_buffer[i+2..]; - _handle_command(data); - - if (read_buffer == "") { - return; - } - } + string line; + + while( (line = get_line()) ) + _handle_command(line); } object(ADT.queue) send_q = ADT.queue(); @@ -115,6 +120,7 @@ class simple // EOF con->set_write_callback(0); con->close(); + // FIXME: Don't do this! It will break SSL connections. /nisse catch { destruct(con); }; con = 0; return; @@ -205,3 +211,65 @@ class smtp_style con->set_write_callback(write_callback); } }; + +class imap_style +{ + inherit simple; + + function handle_literal = 0; + int literal_length; + + function timeout_handler = 0; + + static void read_callback(mixed ignored, string data) + { + touch_time(); + + read_buffer += data; + + while(1) { + if (handle_literal) + { + if (strlen(read_buffer) < literal_length) + return; + string literal = read_buffer[..literal_length - 1]; + read_buffer = read_buffer[literal_length..]; + + function handler = handle_literal; + handle_literal = 0; + + handler(literal); + } else { + string line = get_line(); + if (line) + handle_command(line); + else + break; + } + } + } + + void expect_literal(int length, function callback) + { + literal_length = length; + handle_literal = callback; + } + + static void do_timeout() + { + if (timeout_handler) + { + con->set_read_callback(0); + con->set_close_callback(0); + + timeout_handler(); + } else + ::do_timeout(); + } + + void create(object con_, int|void timeout_, function|void callback) + { + timeout_handler = callback; + ::create(con_, timeout_); + } +}