On Sun, 03 Sep 2000, Bruce Dawson <[EMAIL PROTECTED]> wrote:
>
> If the other side of the connection was through a masquerading firewall,
> then the masquerading timeouts are probably what's causing the freezing.

I am using masquerading, but I don't think those timeouts would be hanging
the whole connection. However, I can't say for sure. How would this hang
the whole connection?


> (Or the other end is timing out and hanging up and your rsh kludge 
> can't catch that

I think this is more likely the problem. I have written a cu(1)
replacement ("devopen", see below) that allows me to log data transfer
until the point where the contraption hangs, but nothing stands out as an
obvious reason...  Nothing in /var/log/messages either from the kernel
and ppp driver.

BTW, I am doing all of this on a cheap $7.95 5-hour/month concentric.net
account I just got last month, perhaps their PPP connection (Merrimack)
is not that stable???

> are you using trap in the script?)

What signal should be trapped? SIGPIPE, SIGCHILD? How should the signal 
be interpreted as to what happened?

A probably better solution is to use a client/server socket() connection
rather than rsh, but I haven't tried this...


> I've been using pmtty to do something similar, but its an old c-program kludge

This may be useful, could you send a pointer if you have one available?


> I don't suppose you would mind posting your script?

Sure, I wrote a perl script called "ptyexec" that runs a command and connects
the command's stdin and stdout to a pseudoterminal (/dev/ptyXY and /dev/ttyXY).

I use "ptyexec" to run the rsh to the remote machine "remotehost" and open
the remote modem:

# ptyexec rsh remotehost -l runge "cu --nostop -s 38400 -E '' -l /dev/ttyS0"

"remotehost" is the machine with the modem, /dev/ttyS0, and cu(1) attaches its 
STDIN and STDOUT to the modem.

On success, the script "ptyexec" then prints out info indicating which
pseudo terminal has been glued to the command like this:

PID:696
MASTER: /dev/ptyp6
SLAVE:  /dev/ttyp6

Then, on the same machine "ptyexec" was run on, I take the slave
"/dev/ttyp6" and pass it to pppd in place of the modem. It is sort of
like this:

pppd connect 'chat -v ""   ATZ OK ATDT4231000 CONNECT' /dev/ttyp6 38400 debug nodetach 
name runge

(but I also have some stuff in /etc/ppp/options too. These settings seem to
work fine for local/regular modem connections...)

Instead of cu(1) I also use an awful hack "devopen" that opens up the
modem and uses getc() (slow!!!) to connect STDIN and STDOUT to the
modem device, i.e.

# ptyexec rsh remotehost -l runge "devopen -s 38400 /dev/ttyS0"

I can use this for extra debugging (but haven't found anything useful yet). 
Surprisingly, "devopen" seems to keep the connection going longer than
cu(1)... but that may just be luck (or ignoring bad data)


Here are the scripts. Just a 1/2 hour hack! If you can see any places
for improvement please let me know.

-----------------------------------------------------------------------------
ptyexec:

  #!/bin/sh -- # A comment mentioning perl
eval 'exec perl -S $0 ${1+"$@"}'
        if 0;
#
# ptyexec: connect the STDIN and STDOUT of some command to a 
# pseudo terminal (e.g. /dev/ptyp2 (master) and /dev/ttyp2 (slave))
#
# based on "ssh-ppp" (ppp over secure shell VPN hack)
#
# Usage: ptyexec <command and args to run ...>
#
# Runs the command in background; writes to output what pseudoterminal
# has been connected to it.
#

@cmd = @ARGV;

die "no command" unless @cmd;

# loop over possible pseudoterminals until we can open one:
foreach $m1 ("p" .. "z") {
        foreach $m2 ("0".."9", "a".."f") {
                &try("$m1$m2"); # exit takes place in try() on success
        }
}
exit 1;

sub try {
        my ($dev) = @_;

        my $master = "/dev/pty$dev";
        my $slave  = "/dev/tty$dev";

        # try to open the pseudoterminal read/write:
        if ( open(PTY, "+>$master") ) {
                # now fork off a child in background to exec @cmd:
                my $pid = fork();
                die "cannot fork, $!" if ! defined($pid);

                if ( ! $pid ) {
                        # child remaps his stdio to the pseudoterm:
                        open(STDIN,  "<&PTY") || die "reopen STDIN,  $!";
                        open(STDOUT, ">&PTY") || die "reopen STDOUT, $!";
                        close(PTY);

                        # and then runs the command:
                        exec @cmd;
                        # exec failed:
                        die "exec: " . join(' ', @cmd) . ": $!";
                } else {
                        # parent tells the user what we have set up: 
                        close(PTY);
                        sleep 1;
                        print STDOUT "PID:$pid\n";
                        if ( ! kill 0, $pid ) {
                                # see if the child is still alive:
                                print STDOUT "WARNING: NO CHILD PID\n";
                        }
                        print STDOUT "MASTER: $master\n";
                        print STDOUT "SLAVE:  $slave\n";
                        exit 0;
                }
        }
}

-----------------------------------------------------------------------------
devopen (for debugging, cu(1) replacement):

  #!/bin/sh -- # A comment mentioning perl
eval 'exec perl -S $0 ${1+"$@"}'
        if 0;
#
# Open a device (e.g. a modem line) and connect our STDIN and STDOUT to it.
# Program is very inefficient, but is useful for debugging and logging.
# See cu(1) for a better implementation.
#
# Usage: devopen [-s <speed>] <line>
#

if ( $ARGV[0] eq '-s' ) {
        shift;
        $speed = shift;
}

$device = shift;

# open the device read/write:
open(DEV, "+>$device") || die "open DEV: $!";

# call stty(1) to set up speed + etc for the device:
system("stty $speed -echo raw <$device >$device");

# fork a child process to handle the I/O in the opposite direction:
$pid = fork();
die "cannot fork, $!" if ! defined($pid);

if ( ! $pid ) {
        # child does:  device -> STDOUT
        select(STDOUT); $| = 1;
        while(1) {
                # TODO: use of getc() is mighty inefficient but can
                # keep up with a modem...
                $c = getc(DEV);
                last if $c eq '';
                print STDOUT $c;
        }
} else {
        # parent does: STDIN -> device
        select(DEV); $| = 1;
        while(1) {
                $c = getc(STDIN);
                last if $c eq '';
                print DEV $c;
        }
}
exit 0;


**********************************************************
To unsubscribe from this list, send mail to
[EMAIL PROTECTED] with the following text in the
*body* (*not* the subject line) of the letter:
unsubscribe gnhlug
**********************************************************

Reply via email to