Jump to content

Reading from socket


lazarantal
Go to solution Solved by salathe,

Recommended Posts

Hi,

I am trying to use the LIST command provided by Google for IMAP (as an extension).

If I connect to gmail imap from linux telnet and send this command from the console, I get the following result:

[#####@#### ~]$ telnet-ssl -z ssl imap.gmail.com 993
Trying 64.233.183.111...
Connected to gmail-imap.l.google.com.
Escape character is '^]'.
* OK Gimap ready for requests from 81.201.58.35 f4if1005730nfh.69
1 LIST "" "*"
* LIST (\HasNoChildren) "/" "INBOX"
* LIST (\Noselect \HasChildren) "/" "[Gmail]"
* LIST (\HasNoChildren \All) "/" "[Gmail]/All Mail"
* LIST (\HasNoChildren \Drafts) "/" "[Gmail]/Drafts"
* LIST (\HasNoChildren \Important) "/" "[Gmail]/Important"
* LIST (\HasNoChildren \Sent) "/" "[Gmail]/Sent Mail"
* LIST (\HasNoChildren \Junk) "/" "[Gmail]/Spam"
* LIST (\HasNoChildren \Flagged) "/" "[Gmail]/Starred"
* LIST (\HasNoChildren \Trash) "/" "[Gmail]/Trash"
1 OK Success


If I am sending this command from php, I am receiving only the last line:

* OK Gimap ready for requests from 212.51.93.33 e8if455192eeo.69 * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 UIDPLUS COMPRESS=DEFLATE ENABLE MOVE C01 OK ###########@gmail.com ######## authenticated (Success) C02 OK Success


My php code is the following:

fwrite($fp, "C01 LOGIN username password\r\n");

while ($line = fgets($fp)) {
echo $line;
$line = preg_split('/\s+/', $line, 0, PREG_SPLIT_NO_EMPTY);
$code = $line[0];
if (strtoupper($code) == 'C01') {
break;
}
}

fwrite($fp, "C02 LIST '' '*'\r\n");

while ($line2 = fgets($fp))
{
echo $line2;
$line2 = preg_split('/\s+/', $line2, 0, PREG_SPLIT_NO_EMPTY);
$code = $line2[0];
if (strtoupper($code) == 'C02') {
break;
}
}

What am I doing wrong?

Regards,
Tony

Link to comment
Share on other sites

You can't just do a simple while(fgets()) loop when reading your socket. fgets() will block if there is no data to be read meaning your script will just halt on that first loop waiting for more data when what you really need to do is quit that loop and send the next command.

 

To do that your best bet is to put the socket connection into non-blocking mode with stream_set_blocking and change your loop to correctly determine if fgets returned data or not. If there is no data available I believe it would return false, but a little testing should figure that out for sure.

 

There's actually a fair amount to consider when dealing with two-way socket communication and ensuring you handle the data properly. You might be able to hack together something that works for your needs but you may be better off doing some googleing to try and find a pre-written library to do what you want.

Link to comment
Share on other sites

Thank you for the advices!

 

@jazzman1 - As the folder structure returned by the Gmail LIST command may vary from user to user, it is not feasable to write the linux console's content into a file, and read it from there each time it's needed. That is why I am trying to execute the command from php and process the result in real time.

 

@kicken -  You are right, fgets is stoped and blocked if no data can be read from the socket. However in my case the fgets is getting stopped (not blocked) when the loop is reaching the point when there is no more data provided. According to the documentations and according to the linux console response my php script should get (and echo) the following:

 

C02 LIST "" "*"
* LIST (\HasNoChildren) "/" "INBOX"
* LIST (\Noselect \HasChildren) "/" "[Gmail]"
* LIST (\HasNoChildren \All) "/" "[Gmail]/All Mail"
* LIST (\HasNoChildren \Drafts) "/" "[Gmail]/Drafts"
* LIST (\HasNoChildren \Important) "/" "[Gmail]/Important"
* LIST (\HasNoChildren \Sent) "/" "[Gmail]/Sent Mail"
* LIST (\HasNoChildren \Junk) "/" "[Gmail]/Spam"
* LIST (\HasNoChildren \Flagged) "/" "[Gmail]/Starred"
* LIST (\HasNoChildren \Trash) "/" "[Gmail]/Trash"
C02 OK Success

 

I know that the fgets is not blocked because the last line is printed (which is also the stop condition): C02 OK Success

 

For some reason my php script is not getting or not printing the lines before the last one (All the starred lines).

Link to comment
Share on other sites

  • Solution

The LIST command that you're sending via the PHP script is different to that that is expected (and the one you demonstrated with telnet).  The PHP script sends:

C02 LIST '' '*'

When it should send:

C02 LIST "" "*"

See the difference?  Something like the following would suffice:

fwrite($fp, 'C02 LIST "" "*"' . "\r\n"); 
Edited by salathe
Link to comment
Share on other sites

 

The LIST command that you're sending via the PHP script is different to that that is expected (and the one you demonstrated with telnet).  The PHP script sends:

C02 LIST '' '*'

When it should send:

C02 LIST "" "*"

See the difference?  Something like the following would suffice:

fwrite($fp, 'C02 LIST "" "*"' . "\r\n"); 

 

You are right, I've exchanged the single and double quotes and now I get the full response. I would not have thinked that this might cause the problem, the server returned a "Successfull" response (not a "bad command" one) Thank you!

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.