diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 92bc959..5f9c5b1 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -65,7 +65,7 @@ }, { "ImportPath": "github.com/pkg/sftp", - "Rev": "739c35a6a165fce018800dcd7caa02040309e024" + "Rev": "4f25752b7ac0c524bfb6f780435f29cfd5b6c9e3" }, { "ImportPath": "github.com/rakyll/pb", @@ -73,8 +73,8 @@ }, { "ImportPath": "github.com/russross/blackfriday", - "Comment": "v1.4-12-gd18b67a", - "Rev": "d18b67ae0afd61dae240896eae1785f00709aa31" + "Comment": "v1.4-17-gb803157", + "Rev": "b8031576aa454ce8a52a7faf1a4359a72f8bdf95" }, { "ImportPath": "github.com/satori/go.uuid", diff --git a/Godeps/_workspace/src/github.com/pkg/sftp/.travis.yml b/Godeps/_workspace/src/github.com/pkg/sftp/.travis.yml new file mode 100644 index 0000000..a4fb252 --- /dev/null +++ b/Godeps/_workspace/src/github.com/pkg/sftp/.travis.yml @@ -0,0 +1,19 @@ +language: go +go_import_path: github.com/pkg/sftp +go: + - 1.5.2 + - 1.4.3 + - tip + +sudo: false + +addons: + ssh_known_hosts: + - bitbucket.org + +install: + - go get -t -v ./... + - ssh-keygen -t rsa -q -P "" -f /home/travis/.ssh/id_rsa + +script: + - go test -integration -v ./... diff --git a/Godeps/_workspace/src/github.com/pkg/sftp/README.md b/Godeps/_workspace/src/github.com/pkg/sftp/README.md index d49f3b1..f87cf6b 100644 --- a/Godeps/_workspace/src/github.com/pkg/sftp/README.md +++ b/Godeps/_workspace/src/github.com/pkg/sftp/README.md @@ -3,7 +3,7 @@ sftp The `sftp` package provides support for file system operations on remote ssh servers using the SFTP subsystem. -[![wercker status](https://app.wercker.com/status/7d3e9b916954ac3a7ed15a457938bac4/s/master "wercker status")](https://app.wercker.com/project/bykey/7d3e9b916954ac3a7ed15a457938bac4) +[!"unix status")](https://travis-ci.org/pkg/sftp.svg) usage and examples ------------------ diff --git a/Godeps/_workspace/src/github.com/pkg/sftp/client.go b/Godeps/_workspace/src/github.com/pkg/sftp/client.go index 93cbc88..7a8e442 100644 --- a/Godeps/_workspace/src/github.com/pkg/sftp/client.go +++ b/Godeps/_workspace/src/github.com/pkg/sftp/client.go @@ -544,7 +544,8 @@ func (c *Client) Remove(path string) error { case *StatusError: switch err.Code { // some servers, *cough* osx *cough*, return EPERM, not ENODIR. - case ssh_FX_PERMISSION_DENIED, ssh_FX_FAILURE: + // serv-u returns ssh_FX_FILE_IS_A_DIRECTORY + case ssh_FX_PERMISSION_DENIED, ssh_FX_FAILURE, ssh_FX_FILE_IS_A_DIRECTORY: return c.removeDirectory(path) default: return err @@ -666,9 +667,7 @@ func (c *Client) dispatchRequest(ch chan<- result, p idmarshaler) { c.inflight[p.id()] = ch if err := sendPacket(c.w, p); err != nil { delete(c.inflight, p.id()) - c.mu.Unlock() ch <- result{err: err} - return } c.mu.Unlock() } @@ -736,7 +735,7 @@ func (f *File) Read(b []byte) (int, error) { inFlight := 0 desiredInFlight := 1 offset := f.offset - ch := make(chan result) + ch := make(chan result, 1) type inflightRead struct { b []byte offset uint64 @@ -832,7 +831,7 @@ func (f *File) WriteTo(w io.Writer) (int64, error) { offset := f.offset writeOffset := offset fileSize := uint64(fi.Size()) - ch := make(chan result) + ch := make(chan result, 1) type inflightRead struct { b []byte offset uint64 @@ -942,7 +941,6 @@ func (f *File) WriteTo(w io.Writer) (int64, error) { return copied, firstErr.err } return copied, nil - } // Stat returns the FileInfo structure describing file. If there is an @@ -966,7 +964,7 @@ func (f *File) Write(b []byte) (int, error) { inFlight := 0 desiredInFlight := 1 offset := f.offset - ch := make(chan result) + ch := make(chan result, 1) var firstErr error written := len(b) for len(b) > 0 || inFlight > 0 { @@ -1029,7 +1027,7 @@ func (f *File) ReadFrom(r io.Reader) (int64, error) { inFlight := 0 desiredInFlight := 1 offset := f.offset - ch := make(chan result) + ch := make(chan result, 1) var firstErr error read := int64(0) b := make([]byte, f.c.maxPacket) diff --git a/Godeps/_workspace/src/github.com/pkg/sftp/client_integration_test.go b/Godeps/_workspace/src/github.com/pkg/sftp/client_integration_test.go index c50a859..b4f995a 100644 --- a/Godeps/_workspace/src/github.com/pkg/sftp/client_integration_test.go +++ b/Godeps/_workspace/src/github.com/pkg/sftp/client_integration_test.go @@ -1233,6 +1233,23 @@ func TestServerRoughDisconnect(t *testing.T) { sftp.Close() } +// sftp/issue/26 writing to a read only file caused client to loop. +func TestClientWriteToROFile(t *testing.T) { + sftp, cmd := testClient(t, READWRITE, NO_DELAY) + defer cmd.Wait() + defer sftp.Close() + + f, err := sftp.Open("/dev/zero") + if err != nil { + t.Fatal(err) + } + defer f.Close() + _, err = f.Write([]byte("hello")) + if err == nil { + t.Fatal("expected error, got", err) + } +} + func benchmarkRead(b *testing.B, bufsize int, delay time.Duration) { size := 10*1024*1024 + 123 // ~10MiB diff --git a/Godeps/_workspace/src/github.com/pkg/sftp/server_integration_test.go b/Godeps/_workspace/src/github.com/pkg/sftp/server_integration_test.go index 2d887f0..744e381 100644 --- a/Godeps/_workspace/src/github.com/pkg/sftp/server_integration_test.go +++ b/Godeps/_workspace/src/github.com/pkg/sftp/server_integration_test.go @@ -36,14 +36,6 @@ const ( OPENSSH_SFTP = false ) -/*********************************************************************************************** - - -SSH server scaffolding; very simple, no strict auth. This is for unit testing, not real servers - - -***********************************************************************************************/ - var ( hostPrivateKeySigner ssh.Signer privKey = []byte(` @@ -350,7 +342,7 @@ func testServer(t *testing.T, useSubsystem bool, readonly bool) (net.Listener, s for { conn, err := listener.Accept() if err != nil { - fmt.Fprintf(sshServerDebugStream, "ssh server socket closed\n") + fmt.Fprintf(sshServerDebugStream, "ssh server socket closed: %v\n", err) break } @@ -358,7 +350,8 @@ func testServer(t *testing.T, useSubsystem bool, readonly bool) (net.Listener, s defer conn.Close() sshSvr, err := sshServerFromConn(conn, useSubsystem, basicServerConfig()) if err != nil { - t.Fatal(err) + t.Error(err) + return } err = sshSvr.Wait() fmt.Fprintf(sshServerDebugStream, "ssh server finished, err: %v\n", err) @@ -374,10 +367,18 @@ func runSftpClient(t *testing.T, script string, path string, host string, port i if _, err := os.Stat(*testSftpClientBin); err != nil { t.Skip("sftp client binary unavailable") } - cmd := exec.Command(*testSftpClientBin /*"-vvvv",*/, "-b", "-", "-o", "StrictHostKeyChecking=no", "-o", "LogLevel=ERROR", "-o", "UserKnownHostsFile /dev/null", "-P", fmt.Sprintf("%d", port), fmt.Sprintf("%s:%s", host, path)) - stdout := &bytes.Buffer{} + args := []string{ + // "-vvvv", + "-b", "-", + "-o", "StrictHostKeyChecking=no", + "-o", "LogLevel=ERROR", + "-o", "UserKnownHostsFile /dev/null", + "-P", fmt.Sprintf("%d", port), fmt.Sprintf("%s:%s", host, path), + } + cmd := exec.Command(*testSftpClientBin, args...) + var stdout bytes.Buffer cmd.Stdin = bytes.NewBufferString(script) - cmd.Stdout = stdout + cmd.Stdout = &stdout cmd.Stderr = sftpClientDebugStream if err := cmd.Start(); err != nil { return "", err @@ -426,12 +427,14 @@ ls -l /usr/bin/ goWords := spaceRegex.Split(goLine, -1) opWords := spaceRegex.Split(opLine, -1) // allow words[2] and [3] to be different as these are users & groups + // also allow words[1] to differ as the link count for directories like + // proc is unstable during testing as processes are created/destroyed. for j, goWord := range goWords { if j > len(opWords) { bad = true } opWord := opWords[j] - if goWord != opWord && j != 2 && j != 3 { + if goWord != opWord && j != 1 && j != 2 && j != 3 { bad = true } } diff --git a/Godeps/_workspace/src/github.com/pkg/sftp/sftp.go b/Godeps/_workspace/src/github.com/pkg/sftp/sftp.go index 934684c..c1a5ae3 100644 --- a/Godeps/_workspace/src/github.com/pkg/sftp/sftp.go +++ b/Godeps/_workspace/src/github.com/pkg/sftp/sftp.go @@ -46,6 +46,32 @@ const ( ssh_FX_NO_CONNECTION = 6 ssh_FX_CONNECTION_LOST = 7 ssh_FX_OP_UNSUPPORTED = 8 + + // see draft-ietf-secsh-filexfer-13 + // https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.1 + ssh_FX_INVALID_HANDLE = 9 + ssh_FX_NO_SUCH_PATH = 10 + ssh_FX_FILE_ALREADY_EXISTS = 11 + ssh_FX_WRITE_PROTECT = 12 + ssh_FX_NO_MEDIA = 13 + ssh_FX_NO_SPACE_ON_FILESYSTEM = 14 + ssh_FX_QUOTA_EXCEEDED = 15 + ssh_FX_UNKNOWN_PRINCIPAL = 16 + ssh_FX_LOCK_CONFLICT = 17 + ssh_FX_DIR_NOT_EMPTY = 18 + ssh_FX_NOT_A_DIRECTORY = 19 + ssh_FX_INVALID_FILENAME = 20 + ssh_FX_LINK_LOOP = 21 + ssh_FX_CANNOT_DELETE = 22 + ssh_FX_INVALID_PARAMETER = 23 + ssh_FX_FILE_IS_A_DIRECTORY = 24 + ssh_FX_BYTE_RANGE_LOCK_CONFLICT = 25 + ssh_FX_BYTE_RANGE_LOCK_REFUSED = 26 + ssh_FX_DELETE_PENDING = 27 + ssh_FX_FILE_CORRUPT = 28 + ssh_FX_OWNER_INVALID = 29 + ssh_FX_GROUP_INVALID = 30 + ssh_FX_NO_MATCHING_BYTE_RANGE_LOCK = 31 ) const ( diff --git a/Godeps/_workspace/src/github.com/pkg/sftp/wercker.yml b/Godeps/_workspace/src/github.com/pkg/sftp/wercker.yml deleted file mode 100644 index 1ca9d37..0000000 --- a/Godeps/_workspace/src/github.com/pkg/sftp/wercker.yml +++ /dev/null @@ -1,34 +0,0 @@ -box: wercker/golang -# Build definition -build: - # The steps that will be executed on build - steps: - # Sets the go workspace and places you package - # at the right place in the workspace tree - - setup-go-workspace - - # Gets the dependencies - - script: - name: go get - code: | - cd $WERCKER_SOURCE_DIR - go version - go get -t ./... - - # Build the project - - script: - name: go build - code: | - go build ./... - - # Test the project - - script: - name: go test - code: | - go test ./... - - - script: - name: go test -integration - cost: | - go test -intergration ./... - diff --git a/Godeps/_workspace/src/github.com/russross/blackfriday/block.go b/Godeps/_workspace/src/github.com/russross/blackfriday/block.go index b5b0841..7fb472e 100644 --- a/Godeps/_workspace/src/github.com/russross/blackfriday/block.go +++ b/Godeps/_workspace/src/github.com/russross/blackfriday/block.go @@ -320,6 +320,11 @@ func (p *parser) html(out *bytes.Buffer, data []byte, doRender bool) int { return size } + // check for HTML CDATA + if size := p.htmlCDATA(out, data, doRender); size > 0 { + return size + } + // no special case recognized return 0 } @@ -397,12 +402,10 @@ func (p *parser) html(out *bytes.Buffer, data []byte, doRender bool) int { return i } -// HTML comment, lax form -func (p *parser) htmlComment(out *bytes.Buffer, data []byte, doRender bool) int { - i := p.inlineHtmlComment(out, data) - // needs to end with a blank line - if j := p.isEmpty(data[i:]); j > 0 { - size := i + j +func (p *parser) renderHTMLBlock(out *bytes.Buffer, data []byte, start int, doRender bool) int { + // html block needs to end with a blank line + if i := p.isEmpty(data[start:]); i > 0 { + size := start + i if doRender { // trim trailing newlines end := size @@ -416,6 +419,35 @@ func (p *parser) htmlComment(out *bytes.Buffer, data []byte, doRender bool) int return 0 } +// HTML comment, lax form +func (p *parser) htmlComment(out *bytes.Buffer, data []byte, doRender bool) int { + i := p.inlineHTMLComment(out, data) + return p.renderHTMLBlock(out, data, i, doRender) +} + +// HTML CDATA section +func (p *parser) htmlCDATA(out *bytes.Buffer, data []byte, doRender bool) int { + const cdataTag = "') { + i++ + } + i++ + // no end-of-comment marker + if i >= len(data) { + return 0 + } + return p.renderHTMLBlock(out, data, i, doRender) +} + // HR, which is the only self-closing block tag considered func (p *parser) htmlHr(out *bytes.Buffer, data []byte, doRender bool) int { if data[0] != '<' || (data[1] != 'h' && data[1] != 'H') || (data[2] != 'r' && data[2] != 'R') { @@ -432,19 +464,7 @@ func (p *parser) htmlHr(out *bytes.Buffer, data []byte, doRender bool) int { } if data[i] == '>' { - i++ - if j := p.isEmpty(data[i:]); j > 0 { - size := i + j - if doRender { - // trim newlines - end := size - for end > 0 && data[end-1] == '\n' { - end-- - } - p.r.BlockHtml(out, data[:end]) - } - return size - } + return p.renderHTMLBlock(out, data, i+1, doRender) } return 0 diff --git a/Godeps/_workspace/src/github.com/russross/blackfriday/block_test.go b/Godeps/_workspace/src/github.com/russross/blackfriday/block_test.go index b33c257..60da6ca 100644 --- a/Godeps/_workspace/src/github.com/russross/blackfriday/block_test.go +++ b/Godeps/_workspace/src/github.com/russross/blackfriday/block_test.go @@ -1530,3 +1530,41 @@ func TestBlockComments(t *testing.T) { } doTestsBlock(t, tests, 0) } + +func TestCDATA(t *testing.T) { + var tests = []string{ + "Some text\n\n\n", + "

Some text

\n\n\n", + + "CDATA ]]\n\n\n", + "

CDATA ]]

\n\n\n", + + "CDATA >\n\n]]>\n", + "

CDATA >

\n\n]]>\n", + + "Lots of text\n\n\n", + "

Lots of text

\n\n\n", + + "]]>\n", + "]]>\n", + } + doTestsBlock(t, tests, 0) + doTestsBlock(t, []string{ + "``` html\n\n```\n", + "
<![CDATA[foo]]>\n
\n", + + "\n", + "\n", + + ` def func(): +> pass +]]> +`, + ` def func(): +> pass +]]> +`, + }, EXTENSION_FENCED_CODE) +} diff --git a/Godeps/_workspace/src/github.com/russross/blackfriday/inline.go b/Godeps/_workspace/src/github.com/russross/blackfriday/inline.go index 044ae70..7dac6b8 100644 --- a/Godeps/_workspace/src/github.com/russross/blackfriday/inline.go +++ b/Godeps/_workspace/src/github.com/russross/blackfriday/inline.go @@ -575,7 +575,7 @@ func link(p *parser, out *bytes.Buffer, data []byte, offset int) int { return i } -func (p *parser) inlineHtmlComment(out *bytes.Buffer, data []byte) int { +func (p *parser) inlineHTMLComment(out *bytes.Buffer, data []byte) int { if len(data) < 5 { return 0 } @@ -599,7 +599,7 @@ func leftAngle(p *parser, out *bytes.Buffer, data []byte, offset int) int { data = data[offset:] altype := LINK_TYPE_NOT_AUTOLINK end := tagLength(data, &altype) - if size := p.inlineHtmlComment(out, data); size > 0 { + if size := p.inlineHTMLComment(out, data); size > 0 { end = size } if end > 2 { diff --git a/Makefile b/Makefile index 2b4dc32..53206a0 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -VERSION := $(shell git describe --abbrev=6 --dirty --always --tags) +VERSION := $(shell git describe --abbrev=6 --dirty=-unreleased --always --tags) V := "blablabla.go" all: corectl docs @@ -8,17 +8,24 @@ corectl: clean Makefile @echo "package main" > $(V) @echo "var Version = \"$(VERSION)\"" >> $(V) @mkdir -p ./documentation/ - godep save ./... godep go build -o corectl @touch $@ clean: - @rm -rf corectl ./Godeps ./documentation/ + @rm -rf corectl ./documentation/ + +godeps_diff: + @godep diff + +godeps_save: godeps_diff + @rm -rf Godeps/ + @godep save ./... + @git status docs: corectl documentation/markdown documentation/man documentation/man: force - @mkdir documentation/man + @mkdir documentation/man @./corectl utils mkMan @for p in $$(ls documentation/man/*.1); do \ sed -i "s/$$(/bin/date '+%h %Y')//" "$$p" ;\ @@ -26,7 +33,7 @@ documentation/man: force done documentation/markdown: force - @mkdir documentation/markdown + @mkdir documentation/markdown @./corectl utils mkMkdown @for p in $$(ls documentation/markdown/*.md); do \ sed -i '/spf13\/cobra/d' "$$p" ;\ diff --git a/main.go b/main.go index f5af0c9..fd46300 100644 --- a/main.go +++ b/main.go @@ -69,14 +69,13 @@ func init() { func versionCommand(cmd *cobra.Command, args []string) { var ( - err error - latest *github.RepositoryRelease + err error + latest *github.RepositoryRelease ) fmt.Printf("%s\n%s\n\n", "CoreOS over OSX made simple.", "❯❯❯ http://github.com/TheNewNormal/corectl") - fmt.Println("Installed version:", - strings.Split(strings.TrimPrefix(Version, "v"), "-")[0]) + fmt.Println("Installed version:", strings.TrimPrefix(Version, "v")) if latest, _, err = github.NewClient(nil).Repositories.GetLatestRelease("TheNewNormal", "corectl"); err != nil {