# $Id: move4,v 1.15 2004/01/27 20:53:11 herbert Exp $

function record(field, name, value) {
	if (field == "") {
		return
	}

	i = index(field, ":")
	name = tolower(substr(field, 1, i - 1))
	value = substr(field, i + 1)

	if (name in kmap) {
		name = kmap[name]
	}
	tv[name] = value
}

function ucfirst(s) {
	return toupper(substr(s, 1, 1)) substr(s, 2)
}

function readsize(sizef, size) {
	err = getline size < sizef
	if (err < 0) {
		print "getline failed on " sizef > "/dev/stderr"
		exit 1
	} else if (err == 0) {
		return -1
	}
	return size
}

BEGIN {
	pref = ARGV[1]
	sizef = ARGV[2]
	skipf = ARGV[3]
	pkgf = ARGV[4]
	contents = ARGV[5] == "yes"
	ARGC = 1

	isbin = pref ~ /deb$/

	if (isbin) {
		kmap["optional"] = "suggests"
		kmap["recommended"] = "recommends"
		kmap["class"] = "priority"
		kmap["package_revision"] = "revision"
	} else {
		kmap["source"] = "package"
	}

	i = 0
	# This order is taken from apt which in turn comes from dpkg.
	# Fields specific to the status file have been removed.
	if (isbin) {
		pri[++i] = "Package"
		pri[++i] = "Essential"
		pri[++i] = "Priority"
		pri[++i] = "Section"
		pri[++i] = "Installed-Size"
		pri[++i] = "Maintainer"
		pri[++i] = "Architecture"
		pri[++i] = "Source"
		pri[++i] = "Version"
		pri[++i] = "Replaces"
		pri[++i] = "Provides"
		pri[++i] = "Depends"
		pri[++i] = "Pre-Depends"
		pri[++i] = "Recommends"
		pri[++i] = "Suggests"
		pri[++i] = "Conflicts"
		pri[++i] = "Filename"
		pri[++i] = "Size"
		pri[++i] = "MD5sum"
		pri[++i] = "SHA1sum"
		pri[++i] = "Description"
	} else {
		pri[++i] = "Package"
		pri[++i] = "Binary"
		pri[++i] = "Version"
		pri[++i] = "Priority"
		pri[++i] = "Section"
		pri[++i] = "Maintainer"
		pri[++i] = "Build-Depends"
		pri[++i] = "Build-Depends-Indep"
		pri[++i] = "Build-Conflicts"
		pri[++i] = "Build-Conflicts-Indep"
		pri[++i] = "Architecture"
		pri[++i] = "Standards-Version"
		pri[++i] = "Format"
		pri[++i] = "Directory"
		pri[++i] = "Files"
	}
	prilen = i

	nextsize = readsize(sizef)
	printf "" > skipf
	if (isbin) {
		printf "" > pkgf
	}
}

nextsize < 0 {
	print "unexpected eof encountered on " sizef > "/dev/stderr"
	exit 1
}

{
	size = nextsize
	nextsize = readsize(sizef)
}

isbin {
	suffix = substr($2, length($2) - 3)
	if (suffix == "udeb") {
		suffix = ".udeb"
	}
	cmd = "dpkg-deb -I " $2 " control"
	while ((val = (cmd | getline line)) > 0 && line == "") {
	}

	if (val <= 0) {
		print "dpkg-deb returned nothing on " $2 > "/dev/stderr"
		print $2 > skipf
		close(cmd)
		next
	}

	field = ""
	split("", tv)
	do {
		if (line ~ /^[ \t]/) {
			field = field "\n" line
			continue
		}
		record(field)
		field = line
	} while ((val = (cmd | getline line)) > 0 && line != "")

	val += close(cmd)
	if (val < 0) {
		print "dpkg-deb failed on " $2 > "/dev/stderr"
		print $2 > skipf
		next
	}
	record(field)

	tv["md5sum"] = " " $1
	tv["size"] = " " size
	if ("revision" in tv) {
		tv["version"] = tv["version"] "-" tv["revision"]
		delete tv["revision"]
	}
}

!isbin {
	while ((val = (getline line < $2)) > 0) {
		if (line == "") {
			continue
		}
		if (line ~ /^-----BEGIN PGP SIGNED MESSAGE-----/) {
			while ((val = (getline line < $2)) > 0) {
				if (line != "") {
					continue
				}
				break
			}
			if (val > 0) {
				continue
			}
		}
		break
	}

	if (val <= 0) {
		if (val < 0) {
			print "Failed to read " $2 > "/dev/stderr"
		} else {
			print "Invalid dsc file " $2 > "/dev/stderr"
		}
		print $2 > skipf
		close($2)
		next
	}

	field = ""
	split("", tv)
	do {
		if (line ~ /^-----BEGIN PGP SIGNATURE-----/) {
			break
		}
		if (line ~ /^[ \t]/) {
			field = field "\n" line
			continue
		}
		record(field)
		field = line
	} while ((val = (getline line < $2)) > 0 && line != "")

	close($2)
	if (val < 0) {
		print "Failed to read " $2 > "/dev/stderr"
		print $2 > skipf
		next
	}
	record(field)

	dir = $2
	file = $2
	sub(/\/[^\/]*$/, "", dir)
	sub(/.*\//, "", file)

	n = split(tv["files"], a)
	files = dir " " file
	for (i = 3; i <= n; i += 3) {
		files = files " " a[i]
	}
	tv["files"] = "\n " $1 " " size " " file tv["files"]
	tv["section"] = tv["section"]
	tv["priority"] = tv["priority"]
	tv["directory"] = tv["directory"]
}

{
	split(tv["package"], a)
	src = bin = a[1]

	if ("source" in tv) {
		split(tv["source"], a)
		src = a[1]
	} else {
		src = bin
	}

	split(tv["version"], a)
	ver = a[1]
}

isbin {
	ever = ver
	sub(/.*:/, "", ever)

	key = substr(src, 1, 1)
	if (key == "l" && substr(src, 1, 3) == "lib") {
		key = substr(src, 1, 4)
	}

	split(tv["architecture"], a)
	arch = a[1]

	split(tv["section"], a)
	dist = getdist(a[1])

	dir = "pool/" dist "/" key "/" src
	filename = dir "/" bin "_" ever "_" arch suffix
	tv["filename"] = " " filename
	ifname = ".apt-move/" dir "/.index/" bin "_" ver "_" arch
	cfname = ".apt-move/" dir "/.content/" bin "_" ver "_" arch
}

{
	ifn = src "_" bin
	cnt = ++count[ifn]
	cfn = pref "/" ifn "_content_" cnt
	ifn = pref "/" ifn "_" cnt

	for (i = 1; i <= prilen; i++) {
		name = tolower(pri[i])
		if (name in tv) {
			print pri[i] ":" tv[name] > ifn
			delete tv[name]
		}
	}
	for (name in tv) {
		print ucfirst(name) ":" tv[name] > ifn
	}
	print "" > ifn
	if (close(ifn)) {
		print "Error closing " ifn > "/dev/stderr"
		exit 1
	}
}

contents {
	cmd = "dpkg-deb -c " $2

	ocmd = "sort > " cfn
	printf "" | ocmd
	while ((val = (cmd | getline line)) > 0) {
		if (line ~ /^d/) {
			continue
		}
		sub(/.* \.\//, "", line)
		print line | ocmd
	}
	if (close(ocmd)) {
		close(cmd)
		print "Error closing " ocmd > "/dev/stderr"
		exit 1
	}

	val += close(cmd)
	if (val < 0) {
		print "dpkg-deb failed on " $2 > "/dev/stderr"
		print $2 > skipf
		next
	}

	printf "1\tD .apt-move/%s/.content\n", dir
	printf "3\tm %s %s\n", cfn, cfname
}

isbin {
	printf "1\tD %s\n", dir
	printf "1\tD .apt-move/%s/.index\n", dir
	printf "2\tm %s %s\n", $2, filename
	printf "3\tm %s %s\n", ifn, ifname
	print ifname " " $2 > pkgf
}

!isbin {
	print src " " ver " " ifn " " files
}
