archive/tar with symbolic links

1,154 views
Skip to first unread message

Harish Vishwanath

unread,
Aug 16, 2015, 12:57:18 AM8/16/15
to golang-nuts
Hello

I am trying to generate a tar.gz of an input directory recursively. I am facing issues when the input directory has relative symbolic links.

Here is the input directory structure:


.
|-- lib
|   |-- json-simple-1.1.jar
|   |-- netty-buffer-4.1.0.Beta3.jar
|   |-- netty-codec-4.1.0.Beta3.jar
|   |-- netty-codec-http-4.1.0.Beta3.jar
|   |-- netty-common-4.1.0.Beta3.jar
|   |-- netty-handler-4.1.0.Beta3.jar
|   |-- netty-transport-4.1.0.Beta3.jar
|   |-- slf4j-api-1.7.7.jar
|   |-- slf4j-jdk14-1.7.7.jar
|   `-- slf4j-simple-1.7.7.jar
|-- lob
|   |-- 1
|   |   |-- 1.txt
|   |   `-- 2
|   |       |-- 2.txt
|   |       `-- 3
|   `-- 2sym -> 1/2/2.txt
|-- package.yaml
|-- play
`-- test.go

When I run my program against this, I see this error, right when it hits the symbolic link: 

<snip>
...
...
Path:  lib/slf4j-simple-1.7.7.jar
New Path:  lib/slf4j-simple-1.7.7.jar
10683
Path:  lob/1/1.txt
New Path:  lob/1/1.txt
0
Path:  lob/1/2/2.txt
New Path:  lob/1/2/2.txt
50
Path:  lob/2sym
New Path:  lob/2sym
2015/08/15 19:38:58 archive/tar: write too long
<snip>

Here is my main func that does this:

func WTarGz(outFilePath string, inPath string) error {
    root_directory, _ := filepath.Abs(inPath)
    fw, err := os.Create(outFilePath)
    handleError(err)
    defer fw.Close()

    cwd, _ := os.Getwd()
    os.Chdir(root_directory)
    defer os.Chdir(cwd)

    root_directory = "."
    // gzip write
    gw := gzip.NewWriter(fw)
    defer gw.Close()

    // tar write
    tw := tar.NewWriter(gw)
    defer tw.Close()

    walkFn := func(path string, info os.FileInfo, err error) error {
        if info.Mode().IsDir() {
            return nil
        }
        // Because of scoping we can reference the external root_directory variable
        //        new_path := path[len(root_directory):]
        new_path := path
        fmt.Println("Path: ", path)
        //        fmt.Println("Root Directory: ", root_directory)
        fmt.Println("New Path: ", new_path)
        if len(new_path) == 0 {
            return nil
        }
        fr, err := os.Open(path)
        if err != nil {
            return err
        }
        defer fr.Close()

        if h, err := tar.FileInfoHeader(info, new_path); err != nil {
            log.Fatalln(err)
        } else {
            h.Name = new_path
            if err = tw.WriteHeader(h); err != nil {
                log.Fatalln(err)
            }
        }
        if length, err := io.Copy(tw, fr); err != nil {
            log.Fatalln(err)
        } else {
            fmt.Println(length)
        }
        return nil
    }

    if err = filepath.Walk(root_directory, walkFn); err != nil {
        return err
    }
    return nil

}

Appreciate any help.


Matt Harden

unread,
Aug 16, 2015, 12:28:49 PM8/16/15
to Harish Vishwanath, golang-nuts
Only open and copy the file contents if it's a regular file. info.Mode().IsRegular().

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages