changeset 16:38b64afbaf79

add ut. ( unix-like tools )
author pyon@macmini
date Sun, 17 Jun 2018 20:29:45 +0900
parents 3673b244ad94
children 72ce457fb99d
files src/getexr/getexr.go src/ut/lu/lu.go src/ut/main.go
diffstat 3 files changed, 777 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/getexr/getexr.go	Sun Jan 21 17:31:21 2018 +0900
+++ b/src/getexr/getexr.go	Sun Jun 17 20:29:45 2018 +0900
@@ -27,7 +27,7 @@
     flag.Parse()
 
     if ( *version ) {
-        fmt.Fprintf( os.Stderr, "getexr - Get Exchange Rate  [ version = %s ]\n",ver )
+        fmt.Fprintf( os.Stderr, "getexr - Get Exchange Rate  [ version = %s ]\n", ver )
         os.Exit( 0 )
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ut/lu/lu.go	Sun Jun 17 20:29:45 2018 +0900
@@ -0,0 +1,298 @@
+/*
+    little unix tool library.
+*/
+package lu
+
+import (
+    "archive/tar"
+    "bufio"
+    "bytes"
+    "compress/gzip"
+    "crypto/md5"
+    "crypto/sha256"
+    "fmt"
+    "io"
+    "log"
+    "os"
+    "os/exec"
+    "path/filepath"
+    "strings"
+)
+
+func CmdTime( cmdline string ) {
+    cmd := exec.Command( "ls", "-l" )
+	cmd.Stdin = strings.NewReader( "some input" )
+	var out bytes.Buffer
+	cmd.Stdout = &out
+	err := cmd.Run()
+	if err != nil {
+		log.Fatal( err )
+	}
+	fmt.Printf( "%q\n", out.String() )
+}
+
+/* cut -d, -f: */
+func CutCsv( files []string, cols []string ) {
+}
+
+/* cat -n: done. */
+func Cat_n( files []string ) {
+    if len( files ) == 0 {
+        cnt := 1
+        input := bufio.NewScanner( os.Stdin )
+        for input.Scan() {
+            fmt.Printf( "%5d  %s\n", cnt, input.Text() )
+            cnt++
+        }
+    } else {
+        for _, file := range files {
+            cnt := 1
+            f, _ := os.Open( file )
+            input := bufio.NewScanner( f )
+            for input.Scan() {
+                fmt.Printf( "%5d  %s\n", cnt, input.Text() )
+                cnt++
+            }
+            f.Close()
+        }
+    }
+}
+
+/* wc -l: done. */
+func Wc_l( files []string ) {
+    if len( files ) == 0 {
+        cnt := 0
+        input := bufio.NewScanner( os.Stdin )
+        for input.Scan() {
+            cnt++
+        }
+        fmt.Printf( "%d\n", cnt )
+    } else {
+        for _, file := range files {
+            cnt := 0
+            f, _ := os.Open( file )
+            input := bufio.NewScanner( f )
+            for input.Scan() {
+                cnt++
+            }
+            f.Close()
+            fmt.Printf( "%s:\t%5d\n", file, cnt )
+        }
+    }
+}
+
+/* tar xvfz: done. */
+func UnTgz( files []string ) {
+
+    for _, file := range files {
+
+        f, err := os.Open( file )
+        if err != nil {
+            log.Fatal( err )
+        }
+        zr, err := gzip.NewReader( f )
+        if err != nil {
+            log.Fatal( err )
+        }
+
+        tr := tar.NewReader( zr )
+
+        for {
+            hdr, err := tr.Next()
+            if err == io.EOF {
+                break // End of archive
+            }
+            if err != nil {
+                log.Fatal( err )
+            }
+            fmt.Printf( "%s\n", hdr.Name )
+
+            dir := filepath.Dir( hdr.Name )
+            if ( dir != "" ) {
+                os.MkdirAll( dir, 0744 )
+            }
+            f, err := os.OpenFile( hdr.Name, os.O_RDWR|os.O_CREATE, 0644 )
+            if err != nil {
+                log.Fatal( err )
+            }
+            if _, err := io.Copy( f, tr ); err != nil {
+                log.Fatal( err )
+            }
+
+            if err := f.Close(); err != nil {
+                log.Fatal( err )
+            }
+        }
+
+        if err := zr.Close(); err != nil {
+            log.Fatal( err )
+        }
+    }
+
+}
+
+/* tac: done. */
+func Reverse( files []string ) {
+    var buf []string
+    if len( files ) == 0 {
+        input := bufio.NewScanner( os.Stdin )
+        for input.Scan() {
+            buf = append( buf, input.Text() )
+        }
+    } else {
+        for _, file := range files {
+            f, _ := os.Open( file )
+            input := bufio.NewScanner( f )
+            for input.Scan() {
+                buf = append( buf, input.Text() )
+            }
+            f.Close()
+        }
+    }
+    for i := len( buf ); i > 0; i-- {
+        fmt.Println( buf[i-1] )
+    }
+}
+
+func Grep( word string, inv bool, files []string ) {
+    if len( files ) == 0 {
+        fmt.Println("grep stdin")
+    } else {
+        fmt.Println("grep")
+    }
+}
+
+/* uniq: done. */
+func Uniq( cnt, dup bool, files []string ) {
+    var lines []string
+    lcnt := make( map[string]int )
+    lpnt := make( map[string]bool )
+
+    if len( files ) == 0 {
+        input := bufio.NewScanner( os.Stdin )
+        for input.Scan() {
+            lines = append( lines, input.Text() )
+            lcnt[ input.Text() ]++
+        }
+    } else {
+        for _, file := range files {
+            f, _ := os.Open( file )
+            input := bufio.NewScanner( f )
+            for input.Scan() {
+                lines = append( lines, input.Text() )
+                lcnt[ input.Text() ]++
+            }
+            f.Close()
+        }
+    }
+
+    for _, line := range lines {
+        if !lpnt[ line ] {
+            if dup && lcnt[ line ] == 1 {
+                continue
+            }
+            if cnt {
+                fmt.Printf( "%5d  ,", lcnt[ line ] )
+            }
+            fmt.Printf( "%s\n", line )
+            lpnt[ line ] = true
+        }
+    }
+}
+
+func Head( n int, files []string ) {
+    if n > 0 {
+        if len( files ) == 0 {
+            input := bufio.NewScanner( os.Stdin )
+            for input.Scan() {
+                fmt.Println( input.Text() )
+                n--
+                if n == 0 {
+                    return
+                }
+            }
+        } else {
+            for _, file := range files {
+                if n == 0 {
+                    return
+                }
+                f, _ := os.Open( file )
+                input := bufio.NewScanner( f )
+                for input.Scan() {
+                    fmt.Println( input.Text() )
+                    n--
+                    if n == 0 {
+                        break
+                    }
+                }
+                f.Close()
+            }
+        }
+    } else {
+        if len( files ) == 0 {
+
+        } else {
+
+        }
+    }
+}
+
+/* replace:  */
+func Replace( s, t string, files []string ) {
+    if len( files ) == 0 {
+        input := bufio.NewScanner( os.Stdin )
+        for input.Scan() {
+        }
+    } else {
+        for _, file := range files {
+            f, _ := os.Open( file )
+            input := bufio.NewScanner( f )
+            for input.Scan() {
+            }
+            f.Close()
+        }
+    }
+}
+
+/* touch:  */
+func Touch( files []string ) {
+    for _, file := range files {
+        f, _ := os.Open( file )
+        f.Close()
+    }
+}
+
+/* md5: done. */
+func Md5( files []string ) {
+    for _, file := range files {
+        f, _ := os.Open( file )
+        h := md5.New()
+        if _, err := io.Copy( h, f ); err != nil {
+            log.Fatal( err )
+        }
+        f.Close()
+        if len( files ) == 1 {
+            fmt.Printf( "%x\n", h.Sum( nil ) )
+        } else {
+            fmt.Printf( "%s:\t%x\n", file, h.Sum( nil ) )
+        }
+    }
+}
+
+/* sha256: done.  */
+func Sha256( files []string ) {
+    for _, file := range files {
+        f, _ := os.Open( file )
+        h := sha256.New()
+        if _, err := io.Copy( h, f ); err != nil {
+            log.Fatal( err )
+        }
+        f.Close()
+        if len( files ) == 1 {
+            fmt.Printf( "%x\n", h.Sum( nil ) )
+        } else {
+            fmt.Printf( "%s:\t%x\n", file, h.Sum( nil ) )
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ut/main.go	Sun Jun 17 20:29:45 2018 +0900
@@ -0,0 +1,478 @@
+/*
+ MU : muto's utility tool.
+
+ TODO:
+    password
+    delete file on server
+*/
+package main
+
+import (
+    "archive/tar"
+    "bufio"
+    "bytes"
+    "compress/gzip"
+    "flag"
+    "fmt"
+    "io"
+    "io/ioutil"
+    "log"
+    "mime/multipart"
+    "net"
+    "net/http"
+    "os"
+    "runtime"
+    "strconv"
+    "strings"
+    "time"
+
+    "./lu"
+)
+
+var version = "1.01"
+
+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 compupld = flag.Bool( "zu", false, "compress & upload files. (.tgz)" )              // ok
+    var compress = flag.Bool( "z",  false, "compress files. ( not upload. )" )              // 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( "q", 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 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 replace  = flag.Bool( "r", false, "replace strings. ( s/arg1/arg2/g )" )
+    var sort     = flag.Bool( "s", false, "little sort tool." )
+    var nsort    = flag.Bool( "ns", false, "little number sort tool." )
+    var grep     = flag.Bool( "a", false, "little grep tool." )
+    var grepv    = flag.Bool( "b", false, "little grep -v 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 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 )
+        addrs, err := net.InterfaceAddrs()
+        if err != nil {
+            log.Fatal( err )
+        }
+        ip := "127.0.0.1"
+        for _, addr := range addrs {
+            if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
+                if ipnet.IP.To4() != nil {
+                    ip = ipnet.IP.String()
+                }
+            }
+        }
+        fmt.Fprintf( os.Stderr, " [%s]\n", ip )
+        os.Exit( 0 )
+    }
+
+    /* 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 *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 || *grepv {
+        if flag.NArg() < 2 {
+            fmt.Println( "too ?? argnument." )
+            os.Exit( 0 )
+        }
+        if err := is_exist_files( flag.Args()[1:] ); err != nil {
+            log.Fatal( err )
+        }
+        lu.Grep( flag.Args()[0], *grepv, flag.Args()[1:] )
+        os.Exit( 0 )
+    }
+
+    if *migemo {
+        fmt.Fprintln( os.Stderr, "not implement" )
+        os.Exit( 3 )
+    }
+
+    if *replace {
+        if err := is_exist_files( flag.Args() ); err != nil {
+            log.Fatal( err )
+        }
+        lu.Replace( "", "", flag.Args() )
+        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 *ipscan {
+        fmt.Fprintln( os.Stderr, "not implement" )
+        os.Exit( 2 )
+    }
+
+    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 || *compupld {
+                tmpfile, err := ioutil.TempFile( ".", "muxx" )
+                if err != nil {
+                    log.Fatal( err )
+                }
+
+                if err := archive_compress( tmpfile.Name(), flag.Args() ); err != nil {
+                    log.Fatal( err )
+                }
+
+                tgz := prefix + tmpfile.Name() + ".tgz"
+                os.Rename( tmpfile.Name(), tgz )
+                fmt.Printf( "archive & compress ...done [%s].\n", tgz )
+
+                if *compupld {
+                    if err := post_file( url, tgz ); err != nil {
+                        log.Fatal( err )
+                    }
+                    fmt.Println( "upload ...done." )
+                    defer os.Remove( tgz )
+                }
+                // 非圧縮
+            } 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 archive_compress( zfile string, files []string ) ( error ) {
+    tgz, err := os.Create( zfile )
+    if err != nil {
+        return err
+    }
+    defer tgz.Close()
+
+    gw := gzip.NewWriter( tgz )
+    defer gw.Close()
+    tw := tar.NewWriter( gw )
+    defer tw.Close()
+
+    for _, file := range files {
+        f, err := os.Open( file )
+        if err != nil {
+            return err
+        }
+        defer f.Close()
+
+        stat, _ := f.Stat()
+        header := new( tar.Header )
+        header.Name = file
+        header.Size = stat.Size()
+        header.Mode = int64( stat.Mode() )
+        header.ModTime = stat.ModTime()
+
+        if err := tw.WriteHeader( header ); err != nil {
+            return err
+        }
+        if _, err := io.Copy( tw, f ); err != nil {
+            return err
+        }
+    }
+    return nil
+}
+
+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()
+}