view src/ut/main.go @ 56:7396e7407abd

searcher version up.
author pyon@macmini
date Sat, 27 Jun 2020 16:25:13 +0900
parents 1b293bb0a011
children
line wrap: on
line source

/*
 UT : Unix like utility Tool.

 TODO:
    password
    delete file on server
*/
package main

import (
    "bufio"
    "bytes"
    "flag"
    "fmt"
    "io"
    "io/ioutil"
    "log"
    "mime/multipart"
    "net/http"
    "os"
    "runtime"
    "strconv"
    "strings"
    "time"

    "./lu"
    "./nw"
)

var version = "1.06"

func main() {

    var getfile  = flag.Bool( "g", false, "get a file from site." )                         // ok
    var putfile  = flag.Bool( "G", false, "put a file to site." )                           // ok
    var compress = flag.Bool( "z",  false, "compress files. (.tgz)" )                       // ok
    var uncmprss = flag.Bool( "x",  false, "uncompress files. (.tgz )" )                    // ok
    var noprefix = flag.Bool( "n", false, "not add prefix(YYYYMMDDhhmm_) to filename." )    // ok

    var wget     = flag.Bool( "w", false, "little wget tool." )                             // ok
    var wc_l     = flag.Bool( "l", false, "little wc -l tool." )                            // ok
    var catn     = flag.Bool( "C", false, "little cat -n tool." )                           // ok
    var reverse  = flag.Bool( "R", false, "little tac tool. ( reverse file )" )             // ok
    var uniq     = flag.Bool( "u",   false, "little uniq tool." )                           // ok
    var uniqc    = flag.Bool( "uc",  false, "little uniq tool.( count )" )                  // ok
    var uniqd    = flag.Bool( "ud",  false, "little uniq tool.( only dup )" )               // ok
    var uniqdc   = flag.Bool( "udc", false, "little uniq tool.( count dup )" )              // ok
    var md5      = flag.Bool( "md5",    false, "md5." )                                     // ok
    var sha256   = flag.Bool( "sha256", false, "sha256." )                                  // ok
    var grep     = flag.String( "a", "", "little grep tool." )                              // ok
    var grepv    = flag.String( "b", "", "little grep -v tool." )                           // ok
    var orgrep   = flag.String( "A", "", "little grep tool. ( from list file )" )           // ok
    var orgrepv  = flag.String( "B", "", "little grep -v tool. ( from list file )" )        // ok
    var tee      = flag.String( "e", "", "little tee tool." )                               // ok
    var replace  = flag.Bool( "r", false, "replace strings. ( s/arg1/arg2/g )" )            // ok
    var nc       = flag.Bool( "nc",  false, "netcat." )                                     // ok
    var ncl      = flag.Bool( "ncl", false, "netcat listen-mode." )                         // ok
    var fserver  = flag.Int( "fs", 0, "file server." )                                      // ok
    var wserver  = flag.Int( "ws", 0, "web server." )                                       // ok

    var msleep   = flag.Bool( "M", false, "sleep." )
    //var swatch   = flag.Bool( "W", false, "stop watch." )
    //var bccalc   = flag.Bool( "j", false, "calculator." )
    //var bhole   = flag.Bool( "k", false, "black hole. ( /dev/null )" )
    var cmdtime  = flag.Bool( "T", false, "measure program running time." )
    var touch    = flag.Bool( "t", false, "little touch tool." )
    var sort     = flag.Bool( "s", false, "little sort tool." )
    var nsort    = flag.Bool( "ns", false, "little number sort tool." )
    var tree     = flag.Bool( "f", false, "little tree tool." )
    var head     = flag.Int(  "d",     0, "little head/tail tool.( head:n, tail:-n )" )
    //var cut      = flag.String( "c", "", "little cut tool ( only csv )." )
    var migemo   = flag.Bool( "m", false, "migemo tool." )
    //var split    = flag.Int(  "s",   100, "split file ( default 100 MB )." )
    var ipscan   = flag.Bool( "p", false, "ping." )
    var ptscan   = flag.Int( "P", 0, "port scan." )
    var minfo    = flag.Bool( "i", false, "print machine infomation." )                     // half-ok

    //var imgsz    = flag.String( "is", "", "resize image" )
    //var imgconv  = flag.String( "ic", "", "convert image type" )

    var pversion = flag.Bool( "v", false, "print version." )                                // ok
    var help     = flag.Bool( "h", false, "help." )                                         // ok
    flag.Parse()

    if *pversion {
        fmt.Fprintf( os.Stderr, "%s [ ver %s ]\n", os.Args[0], version )
        os.Exit( 0 )
    }

    if *help {
        print_help()
        os.Exit( 0 )
    }

    if *minfo {
        // IP, mask, gw, dns
        host, _ := os.Hostname()
        fmt.Fprintf( os.Stderr, "OS = %s\n", runtime.GOOS )
        fmt.Fprintf( os.Stderr, "ARCH = %s\n", runtime.GOARCH )
        fmt.Fprintf( os.Stderr, "HOSTNAME = %s", host )
        fmt.Fprintf( os.Stderr, " [%s]\n", nw.GetLocalIP() )
        os.Exit( 0 )
    }

    /* Here Servers */
    if *fserver != 0 {
        addr := nw.GetLocalIP() + ":" + fmt.Sprintf( "%d", *fserver )
        log.Fatal( http.ListenAndServe( addr, http.FileServer( http.Dir( ".") ) ) )
    }

    if *wserver != 0 {
        addr := nw.GetLocalIP() + ":" + fmt.Sprintf( "%d", *wserver )
        http.HandleFunc( "/", func( w http.ResponseWriter, r *http.Request ) {
            if flag.NArg() == 0 {
                fmt.Fprintf( w, "WebServer\n" )
                return
            }
            file := flag.Args()[0]
            f, err := os.Open( file )
            if err != nil {
                fmt.Fprintf( w, "WebServer\n" )
            }
            if _, err = io.Copy( w, f ); err != nil {
                log.Fatal( err )
            }
            f.Close()
        } )
        log.Fatal( http.ListenAndServe( addr, nil ) )
    }

    /* Here Utility Function ( unix tool like tools ) */
    if *msleep {
        fmt.Fprintln( os.Stderr, "not implement" )
        os.Exit( 3 )
    }

    if *cmdtime {
        fmt.Fprintln( os.Stderr, "not implement" )
        os.Exit( 3 )
    }

    if *wget {  // done.
        if flag.NArg() == 0 {
            fmt.Fprintln( os.Stderr, "no url" )
            os.Exit( 1 )
        }
        url := flag.Args()[0]
        if !strings.Contains( url, "://" ) {
            url = "http://" + url
        }

        fmt.Printf( "%s", url_get( url ) )
        os.Exit( 0 )
    }

        /*
    if *cut {
        fmt.Fprintln( os.Stderr, "not implement" )
        if err := is_exist_files( flag.Args() ); err != nil {
            log.Fatal( err )
        }
        lu.CutCsv( flag.Args() )
        os.Exit( 3 )
    }
        */

    if *tee != "" { // done.
        lu.Tee( *tee )
        os.Exit( 0 )
    }

    if *sort {
        fmt.Fprintln( os.Stderr, "not implement" )
        os.Exit( 3 )
    }

    if *nsort {
        fmt.Fprintln( os.Stderr, "not implement" )
        os.Exit( 3 )
    }

    if *tree {
        fmt.Fprintln( os.Stderr, "not implement" )
        os.Exit( 3 )
    }

    if *catn {  // done.
        if err := is_exist_files( flag.Args() ); err != nil {
            log.Fatal( err )
        }
        lu.Cat_n( flag.Args() )
        os.Exit( 0 )
    }

    if *wc_l {  // done.
        if err := is_exist_files( flag.Args() ); err != nil {
            log.Fatal( err )
        }
        lu.Wc_l( flag.Args() )
        os.Exit( 0 )
    }

    if *uniq || *uniqc || *uniqd || *uniqdc {   // done.
        if err := is_exist_files( flag.Args() ); err != nil {
            log.Fatal( err )
        }
        if *uniqdc {
            *uniqc, *uniqd = true, true
        }
        lu.Uniq( *uniqc, *uniqd, flag.Args() )
        os.Exit( 0 )
    }

    if *head != 0 {
        fmt.Fprintln( os.Stderr, "not implement" )
        if err := is_exist_files( flag.Args() ); err != nil {
            log.Fatal( err )
        }
        lu.Head( *head, flag.Args() )
        os.Exit( 0 )
    }

    if *reverse {   // done.
        if err := is_exist_files( flag.Args() ); err != nil {
            log.Fatal( err )
        }
        lu.Reverse( flag.Args() )
        os.Exit( 0 )
    }

    if *grep != "" {    // done.
        if err := is_exist_files( flag.Args() ); err != nil {
            log.Fatal( err )
        }
        lu.Grep( *grep, false, flag.Args() )
        os.Exit( 0 )
    }

    if *grepv != "" {   // done.
        if err := is_exist_files( flag.Args() ); err != nil {
            log.Fatal( err )
        }
        lu.Grep( *grepv, true, flag.Args() )
        os.Exit( 0 )
    }

    if *orgrep != "" {
        if err := is_exist_files( flag.Args() ); err != nil {
            log.Fatal( err )
        }
        lu.OrGrep( *orgrep, false, flag.Args() )
        os.Exit( 0 )
    }

    if *orgrepv != "" {
        if err := is_exist_files( flag.Args() ); err != nil {
            log.Fatal( err )
        }
        lu.OrGrep( *orgrepv, true, flag.Args() )
        os.Exit( 0 )
    }

    if *migemo {
        fmt.Fprintln( os.Stderr, "not implement" )
        os.Exit( 3 )
    }

    if *replace {   // done.
        if flag.NArg() < 2 {
            fmt.Fprintf( os.Stderr, "too few argument.\n" )
            os.Exit( 1 )
        }
        if err := is_exist_files( flag.Args() ); err != nil {
            log.Fatal( err )
        }
        lu.Replace( flag.Args()[0], flag.Args()[1], flag.Args()[2:] )
        os.Exit( 0 )
    }

    if *touch {
        if err := is_exist_files( flag.Args() ); err != nil {
            log.Fatal( err )
        }
        lu.Touch( flag.Args() )
        os.Exit( 0 )
    }

    if *md5 {   // done.
        if err := is_exist_files( flag.Args() ); err != nil {
            log.Fatal( err )
        }
        lu.Md5( flag.Args() )
        os.Exit( 0 )
    }

    if *sha256 {    // done.
        if err := is_exist_files( flag.Args() ); err != nil {
            log.Fatal( err )
        }
        lu.Sha256( flag.Args() )
        os.Exit( 0 )
    }

    if *nc {    // done.
        if flag.NArg() != 2 {
            fmt.Fprintf( os.Stderr, "$ ut -nc 192.168.0.55 8080\n" )
            os.Exit( 1 )
        }
        nw.Netcat( flag.Args()[0], flag.Args()[1] )
        os.Exit( 0 )
    }

    if *ncl {   // done.
        if flag.NArg() == 0 {
            fmt.Fprintf( os.Stderr, "$ ut -ncl 8080\n" )
            os.Exit( 1 )
        }
        nw.Netcat_l( flag.Args()[0] )
        os.Exit( 0 )
    }

    if *ipscan {
        fmt.Fprintln( os.Stderr, "not implement" )
        os.Exit( 2 )
    }

    if *ptscan != 0 {
        fmt.Fprintln( os.Stderr, "not implement" )
        fmt.Fprintln( os.Stderr, "$ ut -P 1 192.168.0.101 3000 # vanilla scan\n" )
        fmt.Fprintln( os.Stderr, "$ ut -P 2 192.168.0.101 3000 # syn scan\n" )
        fmt.Fprintln( os.Stderr, "$ ut -P 3 192.168.0.101 3000 # fin scan\n" )
        fmt.Fprintln( os.Stderr, "$ ut -P 4 192.168.0.101 3000 # Xmas scan\n" )
        fmt.Fprintln( os.Stderr, "$ ut -P 9 192.168.0.101 3000 # null scan\n" )
        os.Exit( 2 )
    }

    if *compress && !*putfile {  // done.
        if err := is_exist_files( flag.Args() ); err != nil {
            log.Fatal( err )
        }
        tgz := time.Now().Format( "200601021504.tgz" )
        lu.Tgz( tgz, flag.Args() )
        os.Exit( 0 )
    }

    if *uncmprss {  // done.
        if err := is_exist_files( flag.Args() ); err != nil {
            log.Fatal( err )
        }
        lu.UnTgz( flag.Args() )
        os.Exit( 0 )
    }

    /* Here My Uplaad / Download Function */
    host := "http://777.nazo.cc"

    if *putfile {
        if flag.NArg() > 0 {

            // アップロードには,このプログラムで認証が必要:未実装
            if !is_valid_user() {
                fmt.Println( "wrong password." )
                os.Exit( 0 )
            }

            for _, file := range flag.Args() {
                if _, err := os.Stat( file ); os.IsNotExist( err ) {
                    fmt.Fprintf( os.Stderr, "%s: not exist\n", file )
                }
            }

            url := host + "/uploader/index.cgi/goup/post"
            //url = "http://localhost:3000/gofile"

            var prefix string
            if !*noprefix {
                prefix = time.Now().Format( "200601021504_" )
            }

            // 圧縮
            if *compress {
                tmpfile, err := ioutil.TempFile( ".", "muxx" )
                if err != nil {
                    log.Fatal( err )
                }

                tgz := prefix + tmpfile.Name() + ".tgz"
                os.Rename( tmpfile.Name(), tgz )
                defer os.Remove( tgz )
                lu.Tgz( tgz, flag.Args() )
                fmt.Printf( "archive & compress ...done [%s].\n", tgz )

                if err := post_file( url, tgz ); err != nil {
                    log.Fatal( err )
                }
                fmt.Println( "upload ...done." )
            // 非圧縮
            } else {
                for _, file := range flag.Args() {
                    if !*noprefix {
                        c, err := ioutil.ReadFile( file )
                        if err != nil {
                            log.Fatal( err )
                        }
                        if err := ioutil.WriteFile( prefix + file, c, 0644 ); err != nil {
                            log.Fatal( err )
                        }
                    }
                    if err := post_file( url, prefix + file ); err != nil {
                        log.Fatal( err )
                    }
                    fmt.Println( file + "\tupload ...done." )
                }
            }
        }
        os.Exit( 0 )
    }

    // ファイル一覧を取得
    if *getfile {
        url := host + "/uploader/index.cgi/goup/"
        list := url_get( url )
        files := strings.Split( string( list ), "\n" )

        var filename [100]string
        for i, file := range files {
            info := strings.Split( file, "#" )
            fmt.Printf( "[%3d] %-28s %10s  %s\n", i + 1, info[0], info[1], info[2] )
            filename[i] = info[0]
        }

        fmt.Print( "> " )
        scanner := bufio.NewScanner( os.Stdin )
        scanner.Scan()
        input := scanner.Text()

        if strings.Compare( input, "q" ) == 0 || strings.Compare( input, "bye" ) == 0 {
            fmt.Println( "bye." )
            os.Exit( 0 )
        }

        no, err := strconv.Atoi( input )
        if err != nil || no < 1 || no > len( files ) {
            fmt.Fprint( os.Stderr, "bad input\n" )
            os.Exit( 0 )
        }

        url = host + "/uploader/files/goup/" + filename[ no - 1 ]
        fmt.Printf( "downloading %s...\n", filename[ no - 1 ] )
        bytes := url_get( url )
        if err := ioutil.WriteFile( filename[ no - 1 ], bytes, 0644 ); err != nil {
            log.Fatal( err )
        }
        os.Exit( 0 )
    }

    print_help()
}

// Subroutines
func url_get( url string ) []byte {
    res, err := http.Get( url )
	if err != nil {
		log.Fatal( err )
	}
	b, err := ioutil.ReadAll( res.Body )
	res.Body.Close()
	if err != nil {
		log.Fatal( err )
	}
    return b
}

func post_file( url, file string ) error {

    f, err := os.Open( file )
    if err != nil {
        return err
    }
    defer f.Close()

    buf := &bytes.Buffer{}
    writer := multipart.NewWriter( buf )
    fw, err := writer.CreateFormFile( "filename", file )
    if err != nil {
        return err
    }

    if _, err = io.Copy( fw, f ); err != nil {
        return err
    }

    ct :=  writer.FormDataContentType()
    writer.Close()

    resp, err := http.Post( url, ct, buf )
    if err != nil {
        fmt.Fprintf( os.Stderr, "%s", resp.Status )
        return err
    }

    return nil
}

func is_valid_user() bool {
    return true
    return false
}

func is_exist_files( files []string ) error {
    for _, file := range files {
        if _, err := os.Stat( file ); os.IsNotExist( err ) {
            return fmt.Errorf( "%s: not exist\n", file )
        }
    }
    return nil
}

func print_help() {
    fmt.Fprintf( os.Stderr, "Usage of %s [%s]:\n", os.Args[0], version )
    flag.PrintDefaults()
}