Example #1
0
// fills tar.Header missing information (uid/gid, username/groupname, times ...)
func FillHeader(hdr *tar.Header) {
	var cuname string
	cuid := os.Getuid()
	if curr, err := user.LookupId(fmt.Sprintf("%d", cuid)); err == nil {
		cuname = curr.Username
	}
	if hdr.Uid == 0 {
		if hdr.Uname == "" {
			hdr.Uid = cuid
			hdr.Uname = cuname
		} else {
			if usr, err := user.Lookup(hdr.Uname); err == nil {
				if i, err := fmt.Sscanf("%d", usr.Uid); err == nil {
					hdr.Uid = i
					hdr.Uname = usr.Username
				}
			}
		}
	}
	if hdr.Gid == 0 {
		if hdr.Gname == "" {
			if hdr.Uid != 0 {
				if usr, err := user.LookupId(fmt.Sprintf("%d", hdr.Uid)); err == nil {
					if i, err := fmt.Sscanf("%d", usr.Gid); err == nil {
						hdr.Gid = i
					}
				}
			}
		}
	}
	if hdr.ModTime.IsZero() {
		hdr.ModTime = time.Now()
	}
	if hdr.AccessTime.IsZero() {
		hdr.AccessTime = hdr.ModTime
	}
	if hdr.ChangeTime.IsZero() {
		hdr.ChangeTime = hdr.ModTime
	}
}
Example #2
0
func createArchive() int {
	archive := tar.NewWriter(output)
	defer archive.Close()
	exit_value := 0

	for _, f := range fileList {
		err := filepath.Walk(f, func(path string, info os.FileInfo, err error) error {
			if err != nil {
				return err
			}

			if verbose {
				fmt.Fprintf(os.Stderr, "%s\n", path)
			}

			var hdr tar.Header
			hdr.Name = path
			hdr.Size = info.Size()
			hdr.Mode = int64(info.Mode())
			hdr.ModTime = info.ModTime()

			// this is not portable:
			hdr.Uid = int(info.Sys().(*syscall.Stat_t).Uid)
			hdr.Gid = int(info.Sys().(*syscall.Stat_t).Gid)

			if user, err := user.LookupId(fmt.Sprintf("%d", hdr.Uid)); err == nil {
				hdr.Uname = user.Name
			}
			// TODO: lookup group, too.

			switch info.Mode() & os.ModeType {
			case 0:
				hdr.Typeflag = tar.TypeReg
			case os.ModeDir:
				hdr.Typeflag = tar.TypeDir
			case os.ModeSymlink:
				hdr.Typeflag = tar.TypeSymlink
				linkname, err := os.Readlink(path)
				if err != nil {
					fmt.Fprintf(os.Stderr, "Warning: can't readlink a symlink: %v\n", err)
					return nil
				} else {
					hdr.Linkname = linkname
				}
			case os.ModeNamedPipe:
				hdr.Typeflag = tar.TypeFifo
			case os.ModeSocket:
				fmt.Fprintf(os.Stderr, "Warning: can't tar a socket\n")
				return nil
			case os.ModeDevice:
				fmt.Fprintf(os.Stderr, "Warning: device files are currently unsupported\n")
				return nil
				/*
					if (info.Mode() & os.ModeCharDevice) != 0 {
						os.Typeflag = tar.TypeChar
					} else {
						os.Typeflag = tar.TypeBlock
					}
				*/
			}

			if err := archive.WriteHeader(&hdr); err != nil {
				fmt.Fprintf(os.Stderr, "Writing archive header for %s failed: %v\n", path, err)
				exit_value = 1
				return nil
			}
			defer archive.Flush()

			if hdr.Typeflag == tar.TypeReg {
				if f, err := os.Open(path); err != nil {
					fmt.Fprintf(os.Stderr, "Opening file %s failed: %v\n", path, err)
					exit_value = 1
					return nil
				} else {
					io.Copy(archive, f)
					f.Close()
				}
			}
			return nil
		})
		if err != nil {
			fmt.Fprintf(os.Stderr, "An error occured: %v\n", err)
			exit_value = 1
		}
	}

	return exit_value
}