Click to See Complete Forum and Search --> : Using telnet in batch mode


victorzhang
08-14-2002, 04:47 AM
Hi all,
I have a net related question,may or may not have anything to do with Linux.But if anyone know if this utility exists,please tell me.
I want to use telent to access my mail box,and then delete all messages from that box without downloading any headers,I can use telnet interactively but can't use it with batch mode,can I use an existing program(if it exists) to finish the task without inventing my own program?
Or if there exist any simple program that can do connect/send a string/wait then get response from server,i can use it.But because I am new to linux programming,pls instruct me to how to compile the new program.

Thanks
Victor

dfx
08-14-2002, 09:27 AM
The "expect" prog can be used to turn any interactive prog into a batch capable prog. If you have ssh access, you can use that easily as well, as ssh can execute remote commands.

To flush your mailbox, you can just trunc your mailbox spool file to zero size, for example with

echo -n > /var/spool/mail/yourusername

victorzhang
08-15-2002, 01:44 AM
Hi,
Thanks for your reply.
Perhaps I didn't say clearly what I want to do.
I want to connect to POP3 mail server located on Internet,in my mailbox,there are a lot of messages I want to discard.
By using telnet,I can delete them without downloading message headers.
I want to do this in batch mode.
How to?
How to use ssh to do the same work as telnet does?
Where is "expect" command?I can't find it in my system.which package does it belong to?I use RH 7.2

Thanks
Victor

dfx
08-15-2002, 04:37 AM
Ah I see. You aren't really using telnet (which is its own protocol), you're just using the telnet prog to talk to a normal tcp connection.

Well you can still use expect for that, but there's an even easier way: you can use simple shell scripting. With a recent bash version, you don't even need an external prog to establish the tcp connection.

You would redirect stdin and stdout to/from a tcp socket (using /dev/tcp notation), and then send commands to that socket and read responses from it, processing them with a shell script.

I always wanted to figure out how that exactly works (I've never tried it myself), so just for ****s and giggles I made a simple shell script that does (I think) exactly what you want. Hope that helps. (Apparently one isn't allowed to attach .sh files here, so I'll post it inline, sorry to everyone.)


#!/bin/bash

read_ok() {
read RESP
RESP1=$(echo "$RESP" | awk '{print $1}')
if [ "$1" = "-n" ]
then
echo "$RESP1"
exit
fi
if [ "$RESP1" != "+OK" ]
then
echo "got error response to $1 command: $RESP" > /dev/stderr
exit 1
fi
}

exec 1> /dev/tcp/localhost/12453 || exit 1
exec 0<&1 || exit 1

echo "USER username"
read_ok USER
echo "PASS yourpasswd"
read_ok PASS

for ((I = 0; ; I++))
do
echo "DELE $I"
RESP=$(read_ok -n)
if [ "$RESP" != "+OK" ]
then
break
fi
done

echo "QUIT"
read_ok -n > /dev/null

victorzhang
08-15-2002, 05:25 AM
Hi dfx,
Thanks for your code.
But in my /etc/ direcotry,there is no tcp subdirectory.Can I use this script?
Could you tell me where can I find more information about /dev/tcp?


Thanks
Victor

dfx
08-15-2002, 05:38 AM
/dev/tcp is special bash notation. This dir doesn't really exist, it's just bash that interprets it specially and opens a network connection if it sees it. The same goes for /dev/stderr, this file doesn't really need to exist, but bash will still deal with it correctly. See "man bash".

victorzhang
08-15-2002, 06:28 AM
Hi,
I exected the script,however there is an error message indicating that the file does not exist.
Maybe there is something wrong in the script,I'll try to find which one caused the error.


Victor

dfx
08-15-2002, 07:23 AM
Maybe your bash is too old, the /dev/tcp thing is probably a very recent addition. It's possible to do the same with external programs such as netcat, but I haven't quite figured out yet how... I'm working on it.

dfx
08-16-2002, 08:25 AM
Ok, I got it to work using named pipes (fifos) and netcat (sometimes called nc). It's not perfect, and I'm pretty sure there's a better way (without named pipes?), but it seems to work.


#!/bin/bash

xexit() {
rm -f ppipe1.$$ ppipe2.$$
if [ -n "$NCPID" ]
then
kill $NCPID > /dev/null 2>&1
fi
exit "$@"
}

read_ok() {
read RESP
RESP1=$(echo "$RESP" | awk '{print $1}')
if [ "$1" = "-n" ]
then
echo "$RESP1"
return
fi
if [ "$RESP1" != "+OK" ]
then
echo "got error response to $1 command: $RESP" > /dev/stderr
xexit 1
fi
}

cd /tmp
rm -f ppipe1.$$ ppipe2.$$
mkfifo -m 600 ppipe1.$$ ppipe2.$$
nc localhost 12453 < ppipe1.$$ > ppipe2.$$ &
NCPID=$!
exec > ppipe1.$$
exec < ppipe2.$$

echo "USER username"
read_ok USER
echo "PASS yourpasswd"
read_ok PASS

for ((I = 0; ; I++))
do
echo "DELE $I"
RESP=$(read_ok -n)
if [ "$RESP" != "+OK" ]
then
break
fi
done

echo "QUIT"
read_ok -n > /dev/null

xexit