Last active
April 26, 2019 07:26
-
-
Save snizovtsev/2d282f2d58337ecbbe72356b2c041b8d to your computer and use it in GitHub Desktop.
Tar to squashfs using pseudo file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// $ go run tar2sfs.go distro.tar > INDEX | |
// $ mksquashfs ./sysroot distro.img -pf INDEX -noappend | |
package main | |
import ( | |
"archive/tar" | |
"flag" | |
"fmt" | |
"io" | |
"log" | |
"os" | |
"strconv" | |
"strings" | |
"github.com/pkg/errors" | |
) | |
func pseudoQuote(name string) string { | |
if strings.ContainsAny(name, "\n\" ") { | |
return fmt.Sprintf("\"%s\"", strings.ReplaceAll(name, "\"", "\\\"")) | |
} else { | |
return name | |
} | |
} | |
func pseudoDef(tarpath string, block int64, hdr tar.Header) string { | |
var name, uid, gid, data string | |
var kind byte | |
name = pseudoQuote(hdr.Name) | |
mode := hdr.Mode & 07777 | |
if hdr.Uname != "" { | |
uid = hdr.Uname | |
} else { | |
uid = strconv.Itoa(hdr.Uid) | |
} | |
if hdr.Gname != "" { | |
gid = hdr.Gname | |
} else { | |
gid = strconv.Itoa(hdr.Gid) | |
} | |
switch hdr.Typeflag { | |
case tar.TypeReg: | |
kind = 'f' | |
data = fmt.Sprintf( | |
" dd status=none if=%q bs=512 skip=%d | tar xOf - --occurrence %q", | |
tarpath, block, hdr.Name) | |
case tar.TypeDir: | |
kind = 'd' | |
case tar.TypeBlock: | |
kind = 'b' | |
data = fmt.Sprintf("%d %d", hdr.Devmajor, hdr.Devminor) | |
case tar.TypeChar: | |
kind = 'c' | |
data = fmt.Sprintf("%d %d", hdr.Devmajor, hdr.Devminor) | |
case tar.TypeSymlink: | |
kind = 's' | |
data = hdr.Linkname | |
case tar.TypeLink: | |
kind = 's' | |
data = hdr.Linkname | |
// case tar.TypeFifo: | |
// case tar.TypeGNUSparse: | |
default: | |
log.Fatal("Unsupported tar node type: %c", hdr.Typeflag) | |
} | |
return fmt.Sprintf("%s %c %o %s %s %s", name, kind, mode, uid, gid, data) | |
} | |
func main() { | |
flag.Parse() | |
if len(flag.Args()) != 1 { | |
log.Fatal("Input tar is missing") | |
} | |
tarpath := flag.Arg(0) | |
tarfd, err := os.Open(tarpath) | |
if err != nil { | |
log.Fatal(err) | |
} | |
defer tarfd.Close() | |
iter := tar.NewReader(tarfd) | |
var offset int64 = 0 | |
for { | |
hdr, err := iter.Next() | |
if err == io.EOF { | |
break | |
} | |
if err != nil { | |
log.Fatal(errors.Wrap(err, tarpath)) | |
} | |
fmt.Println(pseudoDef(tarpath, offset, *hdr)) | |
offset, err = tarfd.Seek(0, io.SeekCurrent) | |
if offset%512 != 0 { | |
panic("Tar header is not aligned") | |
} | |
if hdr.Size > 0 { | |
offset = (offset / 512) + (hdr.Size-1)/512 + 1 | |
} else { | |
offset /= 512 | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment