Games-Axmud

 view release on metacpan or  search on metacpan

lib/Games/Axmud/Obj/Telnet.pm  view on Meta::CPAN

        while ($remove_echo--) {
        shift @$output;
        }

        ## Ensure at least a null string when there's no command output - so
        ## "true" is returned in a list context.
        unless (@$output) {
        @$output = ("");
        }

        ## Return command output via named arg, if requested.
        if (defined $output_ref) {
        if (ref($output_ref) eq "SCALAR") {
            $$output_ref = join "", @$output;
        }
        elsif (ref($output_ref) eq "HASH") {
            %$output_ref = @$output;
        }
        }

        wantarray ? @$output : 1;
    } # end sub cmd


    sub cmd_remove_mode {
        my ($self, $mode) = @_;
        my (
        $prev,
        $s,
        );

        $s = *$self->{net_telnet};
        $prev = $s->{cmd_rm_mode};

        if (@_ >= 2) {
        $s->{cmd_rm_mode} = &_parse_cmd_remove_mode($self, $mode);
        }

        $prev;
    } # end sub cmd_remove_mode


    sub dump_log {
        my ($self, $name) = @_;
        my (
        $fh,
        $s,
        );

        $s = *$self->{net_telnet};
        $fh = $s->{dumplog};

        if (@_ >= 2) {
        if (!defined($name) or $name eq "") {  # input arg is ""
            ## Turn off logging.
            $fh = "";
        }
        elsif (&_is_open_fh($name)) {  # input arg is an open fh
            ## Use the open fh for logging.
            $fh = $name;
            select((select($fh), $|=1)[$[]);  # don't buffer writes
        }
        elsif (!ref $name) {  # input arg is filename
            ## Open the file for logging.
            $fh = &_fname_to_handle($self, $name)
            or return;
            select((select($fh), $|=1)[$[]);  # don't buffer writes
        }
        else {
            return $self->error("bad Dump_log argument ",
                    "\"$name\": not filename or open fh");
        }

        $s->{dumplog} = $fh;
        }

        $fh;
    } # end sub dump_log


    sub eof {
        my ($self) = @_;

        *$self->{net_telnet}{eofile};
    } # end sub eof


    sub errmode {
        my ($self, $mode) = @_;
        my (
        $prev,
        $s,
        );

        $s = *$self->{net_telnet};
        $prev = $s->{errormode};

        if (@_ >= 2) {
        $s->{errormode} = &_parse_errmode($self, $mode);
        }

        $prev;
    } # end sub errmode


    sub errmsg {
        my ($self, @errmsgs) = @_;
        my (
        $prev,
        $s,
        );

        $s = *$self->{net_telnet};
        $prev = $s->{errormsg};

        if (@_ >= 2) {
        $s->{errormsg} = join "", @errmsgs;
        }

        $prev;
    } # end sub errmsg


    sub error {
        my ($self, @errmsg) = @_;
        my (
        $errmsg,

lib/Games/Axmud/Obj/Telnet.pm  view on Meta::CPAN

            else {
            ## Die and append caller's line number to message.
            &_croak($self, $errmsg);
            }
        }
        }
        else {
        return $s->{errormsg} ne "";
        }
    } # end sub error


    sub family {
        my ($self, $family) = @_;
        my (
        $prev,
        $s,
        );

        $s = *$self->{net_telnet};
        $prev = $s->{peer_family};

        if (@_ >= 2) {
        $family = &_parse_family($self, $family)
            or return;

        $s->{peer_family} = $family;
        }

        $prev;
    } # end sub family


    sub fhopen {
        my ($self, $fh) = @_;
        my (
        $globref,
        $s,
        );

        ## Convert given filehandle to a typeglob reference, if necessary.
        $globref = &_qualify_fh($self, $fh);

        ## Ensure filehandle is already open.
        return $self->error("fhopen filehandle isn't already open")
        unless defined($globref) and defined(fileno $globref);

        ## Ensure we're closed.
        $self->close;

        ## Save our private data.
        $s = *$self->{net_telnet};

        ## Switch ourself with the given filehandle.
        *$self = *$globref;

        ## Restore our private data.
        *$self->{net_telnet} = $s;

        ## Re-initialize ourself.
        select((select($self), $|=1)[$[]);  # don't buffer writes
        $s = *$self->{net_telnet};
        $s->{blksize} = &_optimal_blksize((stat $self)[11]);
        $s->{buf} = "";
        $s->{eofile} = '';
        $s->{errormsg} = "";
        vec($s->{fdmask}='', fileno($self), 1) = 1;
        $s->{host} = "";
        $s->{last_line} = "";
        $s->{last_prompt} = "";
        $s->{num_wrote} = 0;
        $s->{opened} = 1;
        $s->{pending_errormsg} = "";
        $s->{port} = '';
        $s->{pushback_buf} = "";
        $s->{select_supported} = $^O ne "MSWin32" || -S $self;
        $s->{timedout} = '';
        $s->{unsent_opts} = "";
        &_reset_options($s->{opts});

        1;
    } # end sub fhopen


    sub get {
        my ($self, %args) = @_;
        my (
        $binmode,
        $endtime,
        $errmode,
        $line,
        $s,
        $telnetmode,
        $timeout,
        );
        local $_;

        ## Init.
        $s = *$self->{net_telnet};
        $timeout = $s->{time_out};
        $s->{timedout} = '';
        return if $s->{eofile};

        ## Parse the named args.
        foreach (keys %args) {
        if (/^-?binmode$/i) {
            $binmode = $args{$_};
            unless (defined $binmode) {
            $binmode = 0;
            }
        }
        elsif (/^-?errmode$/i) {
            $errmode = &_parse_errmode($self, $args{$_});
        }
        elsif (/^-?telnetmode$/i) {
            $telnetmode = $args{$_};
            unless (defined $telnetmode) {
            $telnetmode = 0;
            }
        }
        elsif (/^-?timeout$/i) {

lib/Games/Axmud/Obj/Telnet.pm  view on Meta::CPAN


        ## User requested only the currently available lines.
        if (! $all) {
        return &_next_getlines($self, $s);
        }

        ## Read lines until eof or error.
        while (1) {
        $line = $self->getline
            or last;
        push @lines, $line;
        }

        ## Check for error.
        return if ! $self->eof;

        @lines;
    } # end sub getlines


    sub host {
        my ($self, $host) = @_;
        my (
        $prev,
        $s,
        );

        $s = *$self->{net_telnet};
        $prev = $s->{host};

        if (@_ >= 2) {
        unless (defined $host) {
            $host = "";
        }

        $s->{host} = $host;
        }

        $prev;
    } # end sub host


    sub input_log {
        my ($self, $name) = @_;
        my (
        $fh,
        $s,
        );

        $s = *$self->{net_telnet};
        $fh = $s->{inputlog};

        if (@_ >= 2) {
        if (!defined($name) or $name eq "") {  # input arg is ""
            ## Turn off logging.
            $fh = "";
        }
        elsif (&_is_open_fh($name)) {  # input arg is an open fh
            ## Use the open fh for logging.
            $fh = $name;
            select((select($fh), $|=1)[$[]);  # don't buffer writes
        }
        elsif (!ref $name) {  # input arg is filename
            ## Open the file for logging.
            $fh = &_fname_to_handle($self, $name)
            or return;
            select((select($fh), $|=1)[$[]);  # don't buffer writes
        }
        else {
            return $self->error("bad Input_log argument ",
                    "\"$name\": not filename or open fh");
        }

        $s->{inputlog} = $fh;
        }

        $fh;
    } # end sub input_log


    sub input_record_separator {
        my ($self, $rs) = @_;
        my (
        $prev,
        $s,
        );

        $s = *$self->{net_telnet};
        $prev = $s->{"rs"};

        if (@_ >= 2) {
        $s->{"rs"} = &_parse_input_record_separator($self, $rs);
        }

        $prev;
    } # end sub input_record_separator


    sub last_prompt {
        my ($self, $string) = @_;
        my (
        $prev,
        $s,
        );

        $s = *$self->{net_telnet};
        $prev = $s->{last_prompt};

        if (@_ >= 2) {
        unless (defined $string) {
            $string = "";
        }

        $s->{last_prompt} = $string;
        }

        $prev;
    } # end sub last_prompt


    sub lastline {
        my ($self, $line) = @_;
        my (
        $prev,
        $s,
        );

lib/Games/Axmud/Obj/Telnet.pm  view on Meta::CPAN

            $remote_addr = sockaddr_in($port, $ip_addr);
        }
        else {  # family is "ipv6" or "any"
            ## Lookup server's IP address.
            $flags_hint = $family eq "any" ? $AI_ADDRCONFIG : 0;
            ($err, @ai) = Socket::getaddrinfo($host, $port,
                              { socktype => SOCK_STREAM,
                            "family" => $af{$family},
                            "flags" => $flags_hint });
            if ($err == $EAI_BADFLAGS) {
            ## Try again with no flags.
            ($err, @ai) = Socket::getaddrinfo($host, $port,
                              { socktype => SOCK_STREAM,
                                "family"=> $af{$family},
                                "flags" => 0 });
            }
            return $self->error("unknown remote host: $host")
            if $err or !@ai;
            $af = $ai[0]{"family"};
            $remote_addr = $ai[0]{addr};
        }

        ## Create a socket and attach the filehandle to it.
        socket $self, $af, SOCK_STREAM, 0
            or return $self->error("problem creating socket: $!");

        ## Bind to a local network interface.
        if (length $localhost) {
            if ($lfamily eq "ipv4") {
            ## Lookup server's IP address.
            $ip_addr = inet_aton $localhost
                or return $self->error("unknown local host: $localhost");
            $local_addr = sockaddr_in(0, $ip_addr);
            }
            else {  # local family is "ipv6" or "any"
            ## Lookup local IP address.
            ($err, @ai) = Socket::getaddrinfo($localhost, 0,
                              { socktype => SOCK_STREAM,
                                "family"=>$af{$lfamily},
                                "flags" => 0 });
            return $self->error("unknown local host: $localhost: $err")
                if $err or !@ai;
            $local_addr = $ai[0]{addr};
            }

            bind $self, $local_addr
            or return $self->error("problem binding ",
                           "to \"$localhost\": $!");
        }

        ## Open connection to server.
        connect $self, $remote_addr
            or do {
            $errno = "$!";
            $self->close;
            return $self->error("problem connecting to \"$host\", ",
                        "port $port: $errno");
            };
        }

        select((select($self), $|=1)[$[]);  # don't buffer writes
        $s->{blksize} = &_optimal_blksize((stat $self)[11]);
        $s->{buf} = "";
        $s->{eofile} = '';
        $s->{errormsg} = "";
        vec($s->{fdmask}='', fileno($self), 1) = 1;
        $s->{last_line} = "";
        $s->{sock_family} = $af;
        $s->{num_wrote} = 0;
        $s->{opened} = 1;
        $s->{pending_errormsg} = "";
        $s->{pushback_buf} = "";
        $s->{select_supported} = 1;
        $s->{timedout} = '';
        $s->{unsent_opts} = "";
        &_reset_options($s->{opts});

        1;
    } # end sub open


    sub option_accept {
        my ($self, @args) = @_;
        my (
        $arg,
        $option,
        $s,
        @opt_args,
        );
        local $_;

        ## Init.
        $s = *$self->{net_telnet};

        ## Parse the named args.
        while (($_, $arg) = splice @args, 0, 2) {
        ## Verify and save arguments.
        if (/^-?do$/i) {
            ## Make sure a callback is defined.
            return $self->error("usage: an option callback must already ",
                    "be defined when enabling with $_")
            unless $s->{opt_cback};

            $option = &_verify_telopt_arg($self, $arg, $_);
            return unless defined $option;
            push @opt_args, { option    => $option,
                      is_remote => '',
                      is_enable => 1,
                  };
        }
        elsif (/^-?dont$/i) {
            $option = &_verify_telopt_arg($self, $arg, $_);
            return unless defined $option;
            push @opt_args, { option    => $option,
                      is_remote => '',
                      is_enable => '',
                  };
        }
        elsif (/^-?will$/i) {
            ## Make sure a callback is defined.
            return $self->error("usage: an option callback must already ",

lib/Games/Axmud/Obj/Telnet.pm  view on Meta::CPAN

                      is_remote => 1,
                      is_enable => '',
                  };
        }
        else {
            return $self->error('usage: $obj->option_accept(' .
                    '[Do => $telopt,] ',
                    '[Dont => $telopt,] ',
                    '[Will => $telopt,] ',
                    '[Wont => $telopt,]');
        }
        }

        ## Set "receive ok" for options specified.
        &_opt_accept($self, @opt_args);
    } # end sub option_accept


    sub option_callback {
        my ($self, $callback) = @_;
        my (
        $prev,
        $s,
        );

        $s = *$self->{net_telnet};
        $prev = $s->{opt_cback};

        if (@_ >= 2) {
        unless (defined $callback and ref($callback) eq "CODE") {
            &_carp($self, "ignoring Option_callback argument because it's " .
               "not a code ref");
            $callback = $prev;
        }

        $s->{opt_cback} = $callback;
        }

        $prev;
    } # end sub option_callback


    sub option_log {
        my ($self, $name) = @_;
        my (
        $fh,
        $s,
        );

        $s = *$self->{net_telnet};
        $fh = $s->{opt_log};

        if (@_ >= 2) {
        if (!defined($name) or $name eq "") {  # input arg is ""
            ## Turn off logging.
            $fh = "";
        }
        elsif (&_is_open_fh($name)) {  # input arg is an open fh
            ## Use the open fh for logging.
            $fh = $name;
            select((select($fh), $|=1)[$[]);  # don't buffer writes
        }
        elsif (!ref $name) {  # input arg is filename
            ## Open the file for logging.
            $fh = &_fname_to_handle($self, $name)
            or return;
            select((select($fh), $|=1)[$[]);  # don't buffer writes
        }
        else {
            return $self->error("bad Option_log argument ",
                    "\"$name\": not filename or open fh");
        }

        $s->{opt_log} = $fh;
        }

        $fh;
    } # end sub option_log


    sub option_state {
        my ($self, $option) = @_;
        my (
        $opt_state,
        $s,
        %opt_state,
        );

        ## Ensure telnet option is non-negative integer.
        $option = &_verify_telopt_arg($self, $option);
        return unless defined $option;

        ## Init.
        $s = *$self->{net_telnet};
        unless (defined $s->{opts}{$option}) {
        &_set_default_option($s, $option);
        }

        ## Return hashref to a copy of the values.
        $opt_state = $s->{opts}{$option};
        %opt_state = %$opt_state;
        \%opt_state;
    } # end sub option_state


    ## Make ors() synonymous with output_record_separator().
    sub ors { &output_record_separator; }


    sub output_field_separator {
        my ($self, $ofs) = @_;
        my (
        $prev,
        $s,
        );

        $s = *$self->{net_telnet};
        $prev = $s->{"ofs"};

        if (@_ >= 2) {
        unless (defined $ofs) {
            $ofs = "";
        }

        $s->{"ofs"} = $ofs;
        }

        $prev;
    } # end sub output_field_separator


    sub output_log {
        my ($self, $name) = @_;
        my (
        $fh,
        $s,
        );

        $s = *$self->{net_telnet};
        $fh = $s->{outputlog};

        if (@_ >= 2) {
        if (!defined($name) or $name eq "") {  # input arg is ""
            ## Turn off logging.
            $fh = "";
        }
        elsif (&_is_open_fh($name)) {  # input arg is an open fh
            ## Use the open fh for logging.
            $fh = $name;
            select((select($fh), $|=1)[$[]);  # don't buffer writes
        }
        elsif (!ref $name) {  # input arg is filename
            ## Open the file for logging.
            $fh = &_fname_to_handle($self, $name)
            or return;
            select((select($fh), $|=1)[$[]);  # don't buffer writes
        }
        else {
            return $self->error("bad Output_log argument ",
                    "\"$name\": not filename or open fh");
        }

        $s->{outputlog} = $fh;
        }

        $fh;
    } # end sub output_log


    sub output_record_separator {
        my ($self, $ors) = @_;
        my (
        $prev,
        $s,
        );

        $s = *$self->{net_telnet};
        $prev = $s->{"ors"};

        if (@_ >= 2) {
        unless (defined $ors) {
            $ors = "";
        }

        $s->{"ors"} = $ors;
        }

        $prev;
    } # end sub output_record_separator


    sub peerhost {
        my ($self) = @_;
        my (
        $host,
        $sockaddr,
        );
        local $^W = '';  # avoid closed socket warning from getpeername()

        ## Get packed sockaddr struct of remote side and then unpack it.
        $sockaddr = getpeername $self
        or return "";
        (undef, $host) = $self->_unpack_sockaddr($sockaddr);

        $host;
    } # end sub peerhost


    sub peerport {
        my ($self) = @_;
        my (
        $port,
        $sockaddr,
        );
        local $^W = '';  # avoid closed socket warning from getpeername()



( run in 1.147 second using v1.01-cache-2.11-cpan-364913b4093 )