Hello everyone,
I'm new to pike, but willing to help.
I found a small error in the reference manual. In the file : refdoc/traditionnal_manual/chapter_2.html 2.1.1 If "If you are interested in having something" instead of "If you are *not* interested in having something"
And on the website, in the forums subsection, you should say something about the pike-devel list, i found it by chance...
Now something a little more interesting : I write a pop3 client module It's documented with autodoc and available here : http://lucane.org/~vincent/pike/POP3.pmod/Client.pike
Do you have any comments on it ?
Have a nice day, Vincent.
I have no real experience with POP3, but I think your client looks simple and nice. Some comments on the pike code:
o Improve the error checking. I think it's reasonable that all the functions throws exceptions for any type of I/O error, except maybe for the operation to open a connection. If you don't want that for some reason, you should at least propagate the error values for the I/O operations better, e.g. returning some kind of success/failure flag and store the errno value in the object so that the user can read it.
o You throw errors from the pop server directly. I don't know exactly what those error messages looks like, but it's likely that they get hard to identify when the context is lost. You should do something like this:
error("Failed to open POP3 connection to %s. Server reply: %s\n", hostname, response);
error("Failed to log in to POP3 account. Server reply: %s\n", response);
etc.
o Maybe combine send_user and send_password to one function? Or is it useful to do one without the other?
o This looks bogus:
do { recv = socket->gets(); } while(!recv);
Doesn't it hang the process if an I/O error occurs there or if the server has closed the connection?
o It's perhaps a bit nicer to make objects of the messages instead of returning them as arrays. That would also make it easier to do future extensions.
o Consider using static instead of private a bit more. Your class becomes hard to inherit if all the low level functions are private.
o It's better to use werror(describe_error(error)) instead of werror(error[0]).
o Fix support for encryption over TLS (aka SSL)?
o Fix an asynchronous mode using callbacks?
/ Martin Stjernholm, Roxen IS
Previous text:
Mmmh no, one isn't usable without the other.
I thought that socket->gets() would throw an error, thus breaking the loop. Isn't it the case ? What is the behaviour of gets() when an error occurs ?
o Fix support for encryption over TLS (aka SSL)?
I don't know anything about TLS.. Do you have an example somewhere ?
o Fix an asynchronous mode using callbacks?
Is it useful ? pop3 seems synchronous to my mind... there's no reason to ask a list of messages and do anything before having that list..
I agree with the other comments. Vincent.
Sometimes it is useful. Some examples:
A GUI mail client that wants to process GUI-events while waiting for the list.
A more general message client that wants to retrieve information from several pop, news and rss sources in parallel.
A webmail interface (like IMHO), talking to a pop server. It needs to be able to process other user's request while geting one user's list of messages.
/ Niels Möller (igelkottsräddare)
Previous text:
Sometimes it is useful. Some examples:
I would use threads for these examples... But ok, i agree it could be useful in certain cases. I will see how to do it properly.
In pike, do you rather use callback methods, or object inheritance (like interfaces in java) ? rather than having, say, X callback methods, only one callback object implementing these X methods...
Vincent.
Hello,
i've modified the pop3 module according to your remarks. i still need to make objects instead of arrays (?), support TLS, and use an asynchronous mode, and implement optional commands.
You can read it here : http://lucane.org/~vincent/pike/POP3.pmod/Client.pike
Have a nice day, Vincent.
I see you still have the loop around socket->gets(). When is it necessary?
The error handling is much better, but the I/O errors still don't include the actual cause of the problem. That can be really frustrating; e.g. if only "Failed to open file foo" is logged somewhere with no hint why. Insufficient permissions? It doesn't exist? The directory doesn't exist? Someone else has an exclusive lock on it? Etc, etc. It's a pain to have to guess what happened. So never ignore the error info in errno.
I'd do something like this:
if(!socket->open_socket()) error("Unable to open socket: %s\n", strerror (socket->errno())); if(!socket->connect(host, port)) error("Unable to connect to %d:%d: %s\n", host, port, strerror (socket->errno()));
Also, by convention you should always end the error descriptions you give to error() with a newline. Various error formatting routines assume there is one.
/ Martin Stjernholm, Roxen IS
Previous text:
pike-devel@lists.lysator.liu.se