diff -ruN dpkg-1.10.10.0lib641/debian/changelog dpkg-1.10.10.0lib641+subarch/debian/changelog
--- dpkg-1.10.10.0lib641/debian/changelog	2003-07-12 15:39:03.000000000 -0400
+++ dpkg-1.10.10.0lib641+subarch/debian/changelog	2003-07-15 21:17:08.000000000 -0400
@@ -1,3 +1,9 @@
+dpkg (1.10.10.0lib641+subarch) unstable; urgency=low
+
+  * added primitive subarchitecture support for dpkg 
+
+ -- Bart Trojanowski <bart@jukie.net>  Sat, 12 Jul 2003 16:10:23 -0400
+
 dpkg (1.10.10.0lib641) unstable; urgency=low
 
   * lib64 support added.
diff -ruN dpkg-1.10.10.0lib641/main/main.h dpkg-1.10.10.0lib641+subarch/main/main.h
--- dpkg-1.10.10.0lib641/main/main.h	2002-05-20 01:56:01.000000000 -0400
+++ dpkg-1.10.10.0lib641+subarch/main/main.h	2003-07-12 22:46:14.000000000 -0400
@@ -98,6 +98,10 @@
 
 void filesdbinit(void);
 
+/* from subarch.c */
+
+void assert_support_for_arch (const char *const arch);
+
 /* from archives.c */
 
 void archivefiles(const char *const *argv);
diff -ruN dpkg-1.10.10.0lib641/main/Makefile.in dpkg-1.10.10.0lib641+subarch/main/Makefile.in
--- dpkg-1.10.10.0lib641/main/Makefile.in	2002-08-24 15:54:18.000000000 -0400
+++ dpkg-1.10.10.0lib641+subarch/main/Makefile.in	2003-07-12 22:40:09.000000000 -0400
@@ -8,7 +8,7 @@
 
 SOURCES		= main.c enquiry.c filesdb.c archives.c processarc.c \
 		  cleanup.c select.c packages.c configure.c remove.c \
-		  help.c depcon.c errors.c update.c 
+		  help.c depcon.c errors.c update.c subarch.c
 
 MAN8PAGES	= dpkg.8 dpkg-query.8
 
diff -ruN dpkg-1.10.10.0lib641/main/processarc.c dpkg-1.10.10.0lib641+subarch/main/processarc.c
--- dpkg-1.10.10.0lib641/main/processarc.c	2002-05-25 23:53:43.000000000 -0400
+++ dpkg-1.10.10.0lib641+subarch/main/processarc.c	2003-07-15 21:37:43.000000000 -0400
@@ -207,12 +207,7 @@
     return;
   }
 
-  if (pkg->available.architecture && *pkg->available.architecture &&
-      strcmp(pkg->available.architecture,"all") &&
-      strcmp(pkg->available.architecture,architecture))
-    forcibleerr(fc_architecture,
-                _("package architecture (%s) does not match system (%s)"),
-                pkg->available.architecture,architecture);
+  assert_support_for_arch (pkg->available.architecture);
     
   if (!pkg->installed.valid) blankpackageperfile(&pkg->installed);
   assert(pkg->available.valid);
diff -ruN dpkg-1.10.10.0lib641/main/subarch.c dpkg-1.10.10.0lib641+subarch/main/subarch.c
--- dpkg-1.10.10.0lib641/main/subarch.c	1969-12-31 19:00:00.000000000 -0500
+++ dpkg-1.10.10.0lib641+subarch/main/subarch.c	2003-07-15 21:13:34.000000000 -0400
@@ -0,0 +1,313 @@
+/*
+ * dpkg - main program for package management
+ * processarc.c - the huge function process_archive
+ *
+ * Copyright (C) 1995 Ian Jackson <ian@chiark.greenend.org.uk>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with dpkg; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <utime.h>
+#include <assert.h>
+#include <time.h>
+#include <ctype.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <config.h>
+#include <dpkg.h>
+#include <dpkg-db.h>
+#include <tarfn.h>
+#include <myopt.h>
+
+#include "filesdb.h"
+#include "main.h"
+#include "archives.h"
+
+#define DPKG_SUBARCHTABLE "/usr/share/dpkg/subarchtable"
+
+/* the database storage */
+static char *archs_buf = NULL;
+typedef struct arch_s {
+	char  *name;
+	int    subarch_cnt;
+	char **subarchs;
+} arch_t;
+static arch_t *archs = NULL;
+static int arch_cnt = 0;
+
+/* local function prototypes */
+static int test_support_for_arch (const char *const deb_arch, 
+		const char *const sys_arch);
+static int parse_subarchs (void);
+static int parse_subarchs_line_helper (char *line, arch_t *arch);
+
+/* ------------------------------------------------------------------------ */
+/* main entry point into this module */
+
+/* this function returns only if the deb_arch can be installed on the running
+ * system. */
+void
+assert_support_for_arch (const char *const deb_arch)
+{
+	if (deb_arch && *deb_arch 
+			&& strcmp(deb_arch, "all") 
+			&& ! test_support_for_arch (deb_arch, architecture)) {
+		forcibleerr(fc_architecture,
+				_("package architecture (%s) does not "
+					"match system (%s)"),
+					deb_arch, architecture);
+	}
+}
+
+/* ------------------------------------------------------------------------ */
+/* helper functions */
+
+/* do a recursive test on subarchtable, parse DPKG_SUBARCHTABLE if needed;
+ * return non-zero if deb_arch can be installed on sys_arch */
+static int
+test_support_for_arch (const char *const deb_arch, const char *const sys_arch)
+{
+	int a, s;
+	arch_t *arch;
+
+	/* do we have a direct match */
+	if (0 == strcmp(deb_arch, sys_arch))
+		return 1;
+
+	/* continue only if we can parse the architectures file;
+	 * or have parsed it already */
+	if (! parse_subarchs ())
+		return 0;
+
+	for (a=0; a<arch_cnt; a++) {
+		arch = &archs[a];
+
+		/* if the system architecture does not */
+		if (strcmp (sys_arch, arch->name))
+			continue;
+
+		/* compare the debian architecture with each subarch */
+		for (s=0; s<arch->subarch_cnt; s++) {
+
+			/* if we find a match return success */
+			if (test_support_for_arch (deb_arch, 
+						arch->subarchs[s]))
+				return 1;
+		}
+	}
+
+	/* we found nothing compatible */
+	return 0;
+}
+
+/* parse the DPKG_SUBARCHTABLE file and store results in archs table;
+ * return 0 on failure, 1 on success */
+static int 
+parse_subarchs (void)
+{
+	int rc, fd, max;
+	struct stat st;
+	char *p, *t;
+
+	/* return success if we have a valid table already */
+	if (arch_cnt>0 && archs && archs_buf) 
+		return 1;
+
+	/* return ailure if we failed previously */
+	if (arch_cnt==-1)
+		return 0;
+
+	/* get the file */
+	fd = open (DPKG_SUBARCHTABLE, O_RDONLY);
+	if (fd < 0)
+		return 0;
+
+	rc = fstat (fd, &st);
+	if (rc < 0)
+		goto error_with_file;
+
+	/* get the flat file into a buffer */
+	archs_buf = malloc (st.st_size+1);
+	if (NULL == archs_buf)
+		goto error_with_file;
+
+	rc = read (fd, archs_buf, st.st_size);
+	if (rc < 0)
+		goto error_with_archs_buf;
+	archs_buf[rc] = 0;
+
+	/* count the maximum number of lines - we will assume we have this
+	 * many arches at maxium */
+	p = archs_buf;
+	max = 2;
+	while (*p) {
+		if (*p == '\n' || *p == '\r')
+			max ++;
+		p++;
+	}
+
+	if (!max)
+		goto error_with_archs_buf;
+
+	/* build the array of architectures */
+	archs = malloc ((max+1) * sizeof (arch_t));
+	if (NULL == archs)
+		goto error_with_archs_buf;
+
+	p = archs_buf;
+	arch_cnt = 0;
+	while ( (t = strsep (&p, "\n\r")) != NULL ) {
+
+		/* find first non space */
+		while (*t && isspace(*t)) t++;
+
+		/* end of line */
+		if (!*t || t>=p) 
+			continue;
+
+		/* comment */
+		if (*t == '#')
+			continue;
+
+		/* invalid first character */
+		if (!isalpha(*t)) { 
+			/* bail if we get a bad token */
+			ohshit(_("%s: invalid token in:\n\t%s\n"),
+					DPKG_SUBARCHTABLE, t);
+		}
+
+		rc = parse_subarchs_line_helper (t, &archs[arch_cnt]);
+		if (rc) {
+			/* bail if we cannot parse the line */
+			ohshit(_("%s: could not parse line:\n\t%s\n"),
+					DPKG_SUBARCHTABLE, t);
+		}
+		
+		/* advance */
+		arch_cnt++;
+	}
+	archs[arch_cnt].name = NULL;
+
+	/* and we are done */
+	close (fd);
+	return 1;
+
+	//free (archs);
+	//archs = NULL;
+error_with_archs_buf:
+	free (archs_buf);
+	archs_buf = NULL;
+error_with_file:
+	close (fd);
+	arch_cnt = -1;
+	return 0;
+}
+
+static inline char *
+ltrim (char *str)
+{
+	char *p = str;
+	while (*p && isspace(*p)) p++;
+	return p;
+}
+
+static inline char *
+rtrim (char *str)
+{
+	char *p = str;
+	while (*p && !isspace(*p)) p++;
+	*p=0;
+	return str;
+}
+
+static inline char *
+trim (char *str)
+{
+	return rtrim (ltrim (str));
+}
+
+static int
+parse_subarchs_line_helper (char *line, arch_t *arch)
+{
+	int rc;
+	char *p = line;
+	char *sub, *t;
+	int max, cnt;
+
+	/* assume failure */
+	rc = -EINVAL;
+
+	/* get the architecture name */
+	arch->name = strsep (&p, ":");
+	if (arch->name == NULL || p == NULL)
+		goto error_parsing_name;
+
+	/* remove leading and trailing spaces */
+	arch->name = trim (arch->name);
+
+	/* guess number of words */
+	t = p;
+	max = 1;
+	while (*t && *t!='#') {
+		max ++;
+		while (*t && isspace(*t)) t++;
+		while (*t && *t!='#' && !isspace(*t)) t++;
+	}
+	*t = 0;
+
+	/* allocate the array of pointers for this */
+	arch->subarchs = malloc (max * sizeof (char*));
+
+	/* parse for real */
+	cnt = 0;
+	while ( (sub = strsep (&p, " \n\t")) != NULL ) {
+
+		/* empty token */
+		if (!*sub || isspace (*sub))
+			continue;
+
+		/* comment on rest of line */
+		if (*sub == '#')
+			break;
+
+		/* invalid first character */
+		if (!isalpha(*sub))
+			goto error_parsing_line;
+
+		/* store and advance */
+		arch->subarchs[cnt++] = sub;
+	}
+	arch->subarch_cnt = cnt;
+	arch->subarchs[cnt] = NULL;
+
+	return 0;
+
+error_parsing_line:
+	free (arch->subarchs);
+	arch->subarchs = NULL;
+error_parsing_name:
+	arch->name = NULL;
+	return rc;
+}
+
diff -ruN dpkg-1.10.10.0lib641/Makefile.in dpkg-1.10.10.0lib641+subarch/Makefile.in
--- dpkg-1.10.10.0lib641/Makefile.in	2003-04-26 12:26:19.000000000 -0400
+++ dpkg-1.10.10.0lib641+subarch/Makefile.in	2003-07-15 21:15:57.000000000 -0400
@@ -19,6 +19,7 @@
 	$(mkinstalldirs) $(DESTDIR)$(dpkgsharedir)/origins
 	$(INSTALL_DATA) $(srcdir)/origin $(DESTDIR)$(dpkgconfdir)/origins/debian
 	$(INSTALL_DATA) $(srcdir)/archtable $(DESTDIR)$(dpkgsharedir)/archtable
+	$(INSTALL_DATA) $(srcdir)/subarchtable $(DESTDIR)$(dpkgsharedir)/subarchtable
 
 clean: clean-recursive
 	rm -f $(GENFILES)
diff -ruN dpkg-1.10.10.0lib641/subarchtable dpkg-1.10.10.0lib641+subarch/subarchtable
--- dpkg-1.10.10.0lib641/subarchtable	1969-12-31 19:00:00.000000000 -0500
+++ dpkg-1.10.10.0lib641+subarch/subarchtable	2003-07-15 21:15:10.000000000 -0400
@@ -0,0 +1,14 @@
+# s390 family
+s390x: s390
+
+# sparc family
+sparc64: sparc
+
+# ppc family
+ppc64: ppc
+
+# x86 family
+amd64: i686
+i686: i586
+i586: i486
+i486: i386

