Note that there are some explanatory texts on larger screens.

plurals
  1. POClosing connections via s_client in a shell script
    primarykey
    data
    text
    <p>I am trying to make a connection to an IMAP server within a shell script. While I can connect and issue the commands, closing the connection suitably seems impossible.</p> <p>This is the test command I am using:</p> <pre><code>openssl s_client -crlf -connect server:993 &lt;&lt;EOF 01 login USERNAME PASSWORD 02 LIST "" "*" 03 logout EOF </code></pre> <p>Because the connection is closed as soon as the input runs out, this occurs before any output is received so I never receive the required data.</p> <p>If I add the option <code>-ign_eof</code> option so that it will ignore the input ending to keep the connection open the output is returned as desired. But instead after the connection has been closed...</p> <pre><code>* BYE Logging out 03 OK Logout completed. </code></pre> <p>...s_client remains alive so execution never returns to the script.</p> <p>Is there a solution which will cause s_client to terminate when the server closes the connection?</p> <p>Or is there an alternative method using standard tools? The script would be run on Mac OS X, Debian, and a Redhat derivate, and possibly an Android terminal emulator so I would like to use fairly standard tools for portability rather than specialist packages.</p> <p>Update: I have come up with an answer that I am not entirely happy with, but which does work. It uses a script to pipe commands to the openssl but which then enters an infinite loop to keep stdin open until it receives a signal to tell it to quit. Here is my test script:</p> <pre><code>#!/bin/sh if [ "$1" = "doit" ]; then trap "echo \"04 logout\"; exit" SIGUSR1 echo "00 login USERNAME PASSWORD" echo "01 SELECT PID-$$" echo "02 SELECT FOLDER" echo "03 FETCH 1:* (BODY[HEADER.FIELDS (Subject)])" while :; do :; done fi MYFLAG= $0 doit | openssl s_client -crlf -connect server:993 2&gt;/dev/null | while read LINE; do LINE=`echo "$LINE" | tr -d '\r'` [ "${LINE:0:4}" = "* OK" ] &amp;&amp; MYFLAG=Y [ "${LINE:0:33}" = "01 NO Mailbox doesn't exist: PID-" ] &amp;&amp; PID="${LINE##*PID-}" [ "$MYFLAG" ] &amp;&amp; echo "$LINE" [ "$PID" -a "$LINE" = "03 OK Fetch completed." ] &amp;&amp; kill -USR1 $PID done echo "Finished." </code></pre> <p>The script calls itself with a parameter to output the IMAP commands which is piped to openssl, whose output is piped into a <code>read</code> loop so it can be processed. The MYFLAG variable is just used to hide the information output by openssl and just echo the output from the server connection.</p> <p>I select a dummy folder name which includes the PID of the second instance of the script as a way to pass this back, obviously a temporary file would have been better but for the testing I wanted to keep everything self contained and be able to watch what was happening.</p> <p>Once the fetch information has been displayed and the server returns the OK response, it sends a SIGUSR1 signal to the second instance of the script, that then sends the logout message and quits, closing stdin which causes s_client to disconnect.</p> <p>Originally I included the <code>04 logout</code> command in the initial set of echos, but when I did this the read loop only displayed as far as the fetch output then stalled, it did not even show the OK status for the operation, though everything was received.</p> <p>Also I need to use <code>tr</code> to strip trailing carriage returns, but if I pipe the output from openssl through then nothing is received by the read loop.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload