Python Forum
i want to rewrite tarnet into python
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
i want to rewrite tarnet into python
#1
i have this bash script that i want to rewrite into python 3:

it's not in python,yet, it's still in bash:
#!/bin/bash
#---------------------------------------------------------------------------------------------------
# Copyright © 2012 - Phil D. Howard - All rights reserved
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# **** This program is distributed in the hope that it will be useful,
# **** but WITHOUT ANY WARRANTY; without even the implied warranty of
# **** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# **** GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#---------------------------------------------------------------------------------------------------
# program    tarnet
# purpose    Send or receive files in tar format over a network.
#
# syntax    tarnet  [options]  [host{/,:}]port  [options]  [files ...]
#
# action    If a host (name or IP address) is given, connect to that host,
#        otherwise listen for connections.  If file names are given,
#        then send a tar stream, otherwise receive and extract.
#
# options    -n        use no compression
#        -b        use bzip2 compression
#        -g        use gzip compression [default]
#        -x        use xz compression
#        -s        use SCTP transport protocol
#        -t        use TCP transport protocol [default]
#        -4        use IPv4 for listening or connect [default]
#        -6        use IPv6 for listening or connect
#        -q        be quiet, do not output list of files
#        -d <directory>    change to this directory
#        fd=descriptor    read passkey from this descriptor (above 2)
#        file=filename    read passkey from this file [default is file=tarnet.pass]
#        env=variable    read passkey from this environment variable
#        pass=passkey    take passkey from this argument directly
#        cipher=cipher    use this cipher [default aes-256-cbc]
#        clevel=number    compression level [default 9]
#---------------------------------------------------------------------------------------------------
# Author:    Phil D. Howard
# Email:    phil (dot) d (dot) howard (at) gmail (dot) com
#---------------------------------------------------------------------------------------------------
# This file is best viewed using a fixed spaced font such as Courier
# and in a display at least 100 columns wide.
#---------------------------------------------------------------------------------------------------

[[ -n "${cipher}"    ]] || cipher="aes-256-cbc"
[[ -n "${ipver}"    ]] || ipver=4
[[ -n "${proto}"    ]] || proto=tcp
[[ -n "${pkfile}"    ]] || pkfile=~/$(basename "${0}").pass
[[ -n "${clevel}"    ]] || clevel=9

trap "echo;echo SIGINT;exit 99" INT
trap "exit 98" TERM

uncmp=( gunzip )
compr=( gzip )
pk=( -pass "file:${pkfile}" )

emsg() { echo "$@" 1>&2 ; }
fail() { emsg "$@" ; exit 1 ; }

while [[ -n "${1}" ]] ; do
    case "x${1}" in
    ( xfd=* )    pk=( -pass "fd:${1:3}"        )    ;;
    ( xfile=* )    pk=( -pass "file:${1:5}"    )    ;;
    ( xenv=* )    pk=( -pass "env:${1:4}"        )    ;;
    ( xpass=* )    pk=( -pass "pass:${1:5}"    )    ;;
    ( xcipher=* )    cipher="${1:7}"                ;;
    ( xclevel=* )    clevel="${1:7}"                ;;
    ( x-q ) quiet=1                        ;;
    ( x-4 )    ipver=4                        ;;
    ( x-6 )    ipver=6                        ;;
    ( x-s )    proto=sctp                    ;;
    ( x-t )    proto=tcp                    ;;
    ( x-d )    shift; cd "${1}" || exit 1            ;;
    ( x-n ) compr=()        ; uncmp=()        ;;
    ( x-b )    compr=( bzip2 )        ; uncmp=( bunzip2 )    ;;
    ( x-g )    compr=( gzip )        ; uncmp=( gunzip )    ;;
    ( x-x )    compr=( xz )        ; uncmp=( xzdec )    ;;
    ( x-* )    fail "Unknown option '${1}'"            ;;

    ( x*/*|x*:*|x[0-9]|x[0-9][0-9]|x[0-9][0-9][0-9]|x[0-9][0-9][0-9][0-9]|x[0-9][0-9][0-9][0-9][0-9] )
    [[ -z "${addrport}" ]] || break
    addrport="${1}"
    ;;

    ( x* )    break                        ;;
    esac
    shift
done

case "${clevel}" in
    ( 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 )    true        ;;
    ( * )                    clevel=9    ;;
esac

case "${ipver}" in
    ( 4 | 6 )    true        ;;
    ( * )    ipver=4        ;;
esac

[[ "${#compr[@]}" = 0 ]] || compr=( "${compr[@]}" "-${clevel}" )

files=( "$@" )

case "${addrport}" in
    ( '['*']':[0-9]* | '['*']'/[0-9]* )
    [[ "x${ipver}" = x4 ]] && fail "IPv4 specified but address is IPv6"
    addr=$( echo "${addrport}" | cut -d '[' -f 2 | cut -d ']' -f 1 )
    port=$( echo "${addrport}" | cut -d ']' -f 2 | tr / : | cut -d ':' -f 2 )
    addr="[${addr}]"
    ipver=6
    ;;
    ( *'['* | *']'[0-9]* )
    fail "Invalid address/port: '${addrport}' [maybe bracketted IPv6 but missing port separator]"
    ;;
    ( *'['* | *']'* )
    fail "Invalid address/port: '${addrport}' [maybe bracketted IPv6 but invalid port]"
    ;;
    ( *::*/*/* )
    fail "Invalid address/port: '${addrport}' [maybe unbracketted IPv6 but multiple ports]"
    ;;
    ( *::*/[0-9]* )
    [[ "x${ipver}" = x4 ]] && fail "IPv4 specified but address is IPv6"
    addr=$( echo "${addrport}" | cut -d / -f 1 )
    port=$( echo "${addrport}" | cut -d / -f 2 )
    addr="[${addr}]"
    ipver=6
    ;;
    ( *::*/* )
    fail "Invalid address/port: '${addrport}' [maybe unbracketted IPv6 but invalid port]"
    ;;
    ( *::* )
    fail "Invalid address/port: '${addrport}' [maybe unbracketted IPv6 but ambiguous port]"
    ;;
    ( */* )
    addr=$( dirname "${addrport}" )
    port=$( basename "${addrport}" )
    ;;
    ( *:*:* )
    fail "Invalid address/port: '${addrport}' [maybe IPv4 but multiple ports]"
    ;;
    ( *:* )
    addr=$( echo "${addrport}" | cut -d : -f 1 )
    port=$( echo "${addrport}" | cut -d : -f 2 )
    ;;
    ( [0-9] | [0-9][0-9] | [0-9][0-9][0-9] | [0-9][0-9][0-9][0-9] | [0-9][0-9][0-9][0-9][0-9] )
    addr=""
    port="${addrport}"
    ;;
    ( * )
    fail "Invalid address/port: '${addrport}' [no valid port]"
    ;;
esac

case "${pk[1]}" in
    ( file:* )
    [[ -e "${pk[1]:5}" ]] || fail "Passkey file '${pk[1]:5}' does not exist"
    [[ -r "${pk[1]:5}" ]] || fail "Passkey file '${pk[1]:5}' is not readable"
    [[ -f "${pk[1]:5}" ]] || fail "Passkey file '${pk[1]:5}' is not a regular file"
    ;;
    ( env:* )
    key=$( eval "echo '${pk[1]:4}'" )
    [[ -z "${key}" ]] || fail "Key environment variable '${pk[1]:4}' is not set"
    ;;
    ( pass:none )
    pk=()
    ;;
esac

[[ "${cipher}" = none ]] && pk=()

#-----------------------------------------------------------------------------
# Find vbuf.
#-----------------------------------------------------------------------------
vbuf=""
for v in {/usr{/local,},}/bin/vbuf ; do
    [[ -x "${v}" ]] && vbuf="${v}" && break
done

#-----------------------------------------------------------------------------
# Output a message based on protocol.
#-----------------------------------------------------------------------------
if [[ -z "${addr}" ]] ; then
    [[ "${proto}" = sctp ]] && emsg "waiting for SCTP session on port ${port} from other tarnet"
    [[ "${proto}" = tcp ]] && emsg "waiting for TCP connection on port ${port} from other tarnet"
fi

#-----------------------------------------------------------------------------
# data receive pipeline ... recv | rbuf | decrypt | uncmp | extar
#-----------------------------------------------------------------------------
recv() {
    if [[ -n "${addr}" ]] ; then
    socat "${proto}${ipver}:${addr}:${port},keepalive" stdout | rbuf
    [[ "${PIPESTATUS
[*]}" = "0 0" ]] || return 1
    else
    socat "${proto}${ipver}-listen:${port},reuseaddr" stdout | rbuf
    [[ "${PIPESTATUS
[*]}" = "0 0" ]] || return 1
    fi
    return 0
}

rbuf() {
    if [[ -n "${vbuf}" ]] ; then
    "${vbuf}" -s 16m -q | decrypt
    [[ "${PIPESTATUS
[*]}" = "0 0" ]] || return 1
    else
    decrypt || exit 1
    fi
    return 0
}

decrypt() {
    if [[ "${#pk[@]}" -gt 0 ]] ; then
    openssl "${cipher}" "${pk[@]}" -salt -d | uncmp
    [[ "${PIPESTATUS
[*]}" = "0 0" ]] || return 1
    else
    emsg "decryption has been disabled"
    uncmp || exit 1
    fi
    return 0
}

uncmp() {
    if [[ "${#uncmp[@]}" -gt 0 ]] ; then
    "${uncmp[@]}" | extar
    [[ "${PIPESTATUS
[*]}" = "0 0" ]] || return 1
    else
    extar || exit 1
    fi
    return 0
}

extar() {
    if [[ -n "${quiet}" ]] ; then
    tar xpf -
    else
    tar xpvf -
    fi
    return $?
}

#-----------------------------------------------------------------------------
# data send pipeline ... mktar | compr | encrypt | sbuf | send
#-----------------------------------------------------------------------------
send() {
    if [[ -n "${addr}" ]] ; then
    sbuf | socat stdin "${proto}${ipver}:${addr}:${port},keepalive"
    else
    sbuf | socat stdin "${proto}${ipver}-listen:${port},reuseaddr"
    fi
    return $?
}

sbuf() {
    if [[ -n "${vbuf}" ]] ; then
    encrypt | "${vbuf}" -s 16m
    [[ "${PIPESTATUS
[*]}" = "0 0" ]] || return 1
    else
    encrypt || exit 1
    fi
    return 0
}

encrypt() {
    if [[ "${#pk[@]}" -gt 0 ]] ; then
    compr | openssl "${cipher}" "${pk[@]}" -salt -e
    [[ "${PIPESTATUS
[*]}" = "0 0" ]] || return 1
    else
    emsg "encryption has been disabled"
    compr || exit 1
    fi
    return 0
}

compr() {
    if [[ "${#compr[@]}" -gt 0 ]] ; then
    mktar | "${compr[@]}"
    [[ "${PIPESTATUS
[*]}" = "0 0" ]] || return 1
    else
    mktar || return 1
    fi
    return 0
}

mktar() {
    tar bcf 1 - "${files[@]}"
    return $?
}

#-----------------------------------------------------------------------------
# Do send or recv.
#-----------------------------------------------------------------------------
if [[ "${#files[@]}" -gt 0 ]] ; then
    send
else
    recv
fi

exit $?
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#2
Likely more complicated to do in Python than in Bash...
Unless noted otherwise, code in my posts should be understood as "coding suggestions", and its use may require more neurones than the two necessary for Ctrl-C/Ctrl-V.
Your one-stop place for all your GIMP needs: gimp-forum.net
Reply
#3
Did you want feedback or were you just sharing?
Reply
#4
(Feb-18-2017, 05:57 PM)micseydel Wrote: Did you want feedback or were you just sharing?

are you motivated to give feedback?  if so, this thread is a good place for it.

(Feb-18-2017, 10:07 AM)Ofnuts Wrote: Likely more complicated to do in Python than in Bash...

really?  why is that?
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#5
Hm! This script uses socat which is an awesome piece of software by itself. There is some sort of encryption also. Perhaps the Python script will be shorter
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#6
(Feb-19-2017, 07:38 AM)wavic Wrote: Hm! This script uses socat which is an awesome piece of software by itself. There is some sort of encryption also. Perhaps the Python script will be shorter

i am hoping so.  much of the bash code was making a flexible pipeline that could have e variable number of commands.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#7
I think pyzmq could be handy for such a task. Look at zerorpc too. You may find it interesting.
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#8
So when you are talking about bash, then your python script is not intended for multi-platform-use anyway, right?
Reply
#9
Replasing shell scripts with Python lead to this - multi-platform usage. In most of the cases.
"As they say in Mexico 'dosvidaniya'. That makes two vidaniyas."
https://freedns.afraid.org
Reply
#10
(Feb-20-2017, 02:44 PM)wavic Wrote: Replasing shell scripts with Python lead to this - multi-platform usage. In most of the cases.

All the shell scripts I write are multi-platform: Linux, OSX, AIX, Solaris, and even Android...  It's when you write a shell script for Windows that it is uni-platform.

MS has become so acutely aware of this that they are adding a Linux command line to Windows.

Otherwise, replacing true shell scripts that use the varoius CLI utilities by Python code requires to implement large parts of these utilities in Python, or adding these utilities to the target system, at which point you can add bash to the lot and use the original script.
Unless noted otherwise, code in my posts should be understood as "coding suggestions", and its use may require more neurones than the two necessary for Ctrl-C/Ctrl-V.
Your one-stop place for all your GIMP needs: gimp-forum.net
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  i want to rewrite logcmd into python Skaperen 11 7,682 Feb-21-2017, 03:49 AM
Last Post: Skaperen

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020