func appendLink(tw *tar.Writer, tfh io.Seeker, fn string) (pos1 uint64, pos2 uint64, err error) { if !fileIsSymlink(fn) { return appendFile(tw, tfh, fn) } logger.Tracef("adding link %s (%s) to %s", tfh, fn, tw) hdr, e := FileTarHeader(fn) hdr.Size = 0 hdr.Typeflag = tar.TypeSymlink hdr.Linkname = BaseName(FindLinkOrigin(fn, false)) // logger.Printf("fn=%s hdr=%+v tm=%s", fn, hdr, hdr.Typeflag) if e != nil { err = e return } p, e := tfh.Seek(0, 1) if e != nil { err = e return } pos1 = uint64(p) if err = WriteTar(tw, hdr, nil); err != nil { return } _ = tw.Flush() if p, err = tfh.Seek(0, 1); err != nil { return } pos2 = uint64(p) return }
//addFile adds the file named name as a tar entry named tarname func addFile(name string, tarname string, tw *tar.Writer) error { if tarname == "" { tarname = name } fi, err := os.Stat(name) if err != nil { return err } hdr, err := tar.FileInfoHeader(fi, "") if err != nil { return err } hdr.Name = tarname err = tw.WriteHeader(hdr) if err != nil { return err } f, err := os.Open(name) if err != nil { return err } _, err = io.Copy(tw, f) if err != nil { return err } tw.Flush() return nil }
// appends file to tar func appendFile(tw *tar.Writer, tfh io.Seeker, fn string) (pos1 uint64, pos2 uint64, err error) { logger.Tracef("adding %s (%s) to %s", tfh, fn, tw) hdr, e := FileTarHeader(fn) if e != nil { err = e return } sfh, e := os.Open(fn) if e != nil { err = e return } defer sfh.Close() p, e := tfh.Seek(0, 1) if e != nil { err = e return } pos1 = uint64(p) if err = WriteTar(tw, hdr, sfh); err != nil { return } _ = tw.Flush() if p, err = tfh.Seek(0, 1); err != nil { return } pos2 = uint64(p) return }
func addFileToTar(zw *tar.Writer, item someutils.ArchiveItem, isVerbose bool, outPipe io.Writer) error { if isVerbose { fmt.Fprintf(outPipe, "Adding %s\n", item.FileSystemPath) } binfo, err := os.Stat(item.FileSystemPath) if err != nil { return err } if binfo.IsDir() { header, err := tar.FileInfoHeader(binfo, "") if err != nil { return err } header.Name = item.ArchivePath err = zw.WriteHeader(header) if err != nil { return err } file, err := os.Open(item.FileSystemPath) if err != nil { return err } fis, err := file.Readdir(0) for _, fi := range fis { err = addFileToTar(zw, someutils.ArchiveItem{filepath.Join(item.FileSystemPath, fi.Name()), filepath.Join(item.ArchivePath, fi.Name()), nil}, isVerbose, outPipe) if err != nil { return err } } } else { header, err := tar.FileInfoHeader(binfo, "") if err != nil { return err } header.Name = item.ArchivePath err = zw.WriteHeader(header) if err != nil { return err } bf, err := os.Open(item.FileSystemPath) if err != nil { return err } defer bf.Close() _, err = io.Copy(zw, bf) if err != nil { return err } err = zw.Flush() if err != nil { return err } err = bf.Close() if err != nil { return err } } return err }
func WriteTar(tw *tar.Writer, hdr *tar.Header, r io.Reader) (err error) { if err = tw.WriteHeader(hdr); err != nil { logger.Errorf("error writing tar header %+v into %+v: %s", hdr, tw, err) } if hdr.Typeflag == tar.TypeSymlink { } else { _, err = io.Copy(tw, r) } if err != nil { logger.Criticalf("error copying tar data %+v into %+v: %s", r, tw, err) return } err = tw.Flush() return }
// Adds a file to the tar archive tw func tarFile(root, name string, tw *tar.Writer, fakeroot bool) { fi, err := os.Stat(name) if err != nil { ExitError(err) } //Write header. TODO symlinks hdr, err := tar.FileInfoHeader(fi, "") if err != nil { ExitError(err) } hdr.Name = strings.Replace(name, root, "./", 1) //Force root owner and group in the tarball if fakeroot { hdr.Uid, hdr.Gid = 0, 0 hdr.Uname, hdr.Gname = "root", "root" } err = tw.WriteHeader(hdr) if err != nil { ExitError(err) } //Create it if it's a directory if fi.IsDir() { tw.Flush() return } //Write the contents of the input file infile, err := os.Open(name) if err != nil { ExitError(err) } defer infile.Close() _, err = io.Copy(tw, infile) if err != nil { ExitError(err) } tw.Flush() }
func iterWriteTar(path string, tw *tar.Writer) { file, err := os.Open(path) handleErr(err) defer file.Close() fi, err := os.Lstat(path) handleErr(err) isSym := (fi.Mode() & os.ModeSymlink) != 0 symPath := "" if isSym { symPath, err = os.Readlink(path) handleErr(err) } h, err := tar.FileInfoHeader(fi, symPath) handleErr(err) h.Name = file.Name() // maybe? if !isSym { h.Size = fi.Size() } b, err := ioutil.ReadAll(file) handleErr(err) err = tw.WriteHeader(h) handleErr(err) if !isSym { _, err = tw.Write(b) handleErr(err) } err = tw.Flush() handleErr(err) }
func walk(fs testfs.FileSystem, t *tar.Writer) (err error) { cwd, err := fs.Getwd() if err != nil { return } f, err := fs.OpenFile(cwd, os.O_RDONLY, 0) if err != nil { return } fi, err := f.Readdir(-1) if err != nil { return } for _, file := range fi { // Add a new file to the archive var hdr *tar.Header hdr, err = tarHdr(file) if err != nil { return } // Make header name fully qualified if cwd[len(cwd)-1] == '/' { hdr.Name = cwd + hdr.Name } else { hdr.Name = cwd + "/" + hdr.Name } // Strip leading slashes if hdr.Name[0] == '/' { hdr.Name = hdr.Name[1:] } err = t.WriteHeader(hdr) if err != nil { return } // Write the file data to the archive if !file.IsDir() && file.Size() > 0 { var target testfs.File target, err = fs.Open(file.Name()) if err != nil { return } _, err = io.Copy(t, target) if err != nil { return } } // Close the file in the archive err = t.Flush() if err != nil { return } // If a directory, recurse into it if file.IsDir() { err = fs.Chdir(file.Name()) if err != nil { return } return walk(fs, t) } } return }