Hi,

I had this patch laying around, that I fished from the net some time
ago, either from gluck.d.o or from raw.no (cannot remember anymore).
It's not good for merging, but just sending it so that it does not
get lost.

regards,
guillem
--- orig/configure.ac
+++ mod/configure.ac
@@ -10,6 +10,17 @@
 
 AM_INIT_AUTOMAKE([1.8 gnu])
 
+dpkg_archlist=''
+AC_MSG_CHECKING(Debian compatible-architecture list)
+dpkg_archlist="`awk '$1 == "'$dpkg_archset'" { $1=""; print $0 }' $srcdir/subarchtable`"
+if test "x$dpkg_archlist" = "x"; then
+   AC_MSG_RESULT([$dpkg_archset not found in subarchtable])
+   dpkg_archlist='{ "'$dpkg_archset'" }'
+   else
+   AC_MSG_RESULT([found])
+fi
+AC_DEFINE_UNQUOTED(ARCH_LIST, ${dpkg_archlist}, [Set this to the list of allowable architectures for this CPU type.])
+
 AM_GNU_GETTEXT_VERSION(0.14.1)
 AM_GNU_GETTEXT()
 


--- orig/debian/changelog
+++ mod/debian/changelog
@@ -1,3 +1,9 @@
+dpkg (1.13.2~multiarch1) multiarch; urgency=low
+
+  * Update multiarch patches to current newest version
+
+ -- Tollef Fog Heen <[EMAIL PROTECTED]>  Tue,  8 Mar 2005 13:50:31 +0100
+  
 dpkg (1.13.2~) experimental; urgency=low
 
   * 
@@ -278,6 +284,22 @@
 
  -- Scott James Remnant <[EMAIL PROTECTED]>  Tue,  1 Jun 2004 18:21:40 -0300
 
+dpkg (1.10.21.multiarch.20040601.01) unstable; urgency=low
+
+  * Fix (badly) problem of migrating uniarch libs to multiarch.
+
+ -- Hugo Mills <[EMAIL PROTECTED]>  Tue, 1 Jun 2004 20:29:40 +0100
+
+dpkg (1.10.21.multiarch.20040528.01) unstable; urgency=low
+
+  * Accept Multi-Arch: field in control files.
+  * Add database of acceptable architectures for multi-arch systems.
+  * Use libfoo:arch for package name internally for all multi-arch
+    packages.
+  * Handle shared symlinks for multi-arch packages.
+
+ -- Hugo Mills <[EMAIL PROTECTED]>  Fri, 28 May 2004 20:18:19 +0100
+
 dpkg (1.10.21) unstable; urgency=low
 
   * Fix incorrect linked list node removal code that caused every second


--- orig/dpkg-deb/build.c
+++ mod/dpkg-deb/build.c
@@ -211,9 +211,11 @@
     parsedb(controlfile, pdb_recordavailable|pdb_rejectstatus,
             &checkedinfo, stderr, &warns);
     assert(checkedinfo->available.valid);
+	/* The name of the package may be libfoo:arch if it's a multiarch
+	 * package. */
     if (strspn(checkedinfo->name,
                "abcdefghijklmnopqrstuvwxyz0123456789+-.")
-        != strlen(checkedinfo->name))
+        < strcspn(checkedinfo->name, ":"))
       ohshit(_("package name has characters that aren't lowercase alphanums or `-+.'"));
     if (checkedinfo->priority == pri_other) {
       fprintf(stderr, _("warning, `%s' contains user-defined Priority value `%s'\n"),


--- orig/lib/database.c
+++ mod/lib/database.c
@@ -86,6 +86,7 @@
   pifp->conffiles= NULL;
   pifp->arbs= NULL;
   pifp->valid= 1;
+  pifp->multiarch= 0;
 }
 
 static int nes(const char *s) { return s && *s; }
@@ -121,6 +122,15 @@
   struct pkginfo **pointerp, *newpkg;
   char *name = strdup(inname), *p;
 
+/*
+  if(strchr(inname, ':') || strncmp(inname, "libfoo", 6) == 0)
+  {
+	  fprintf(stderr,
+			  "Findpackage looking for an interesting package: %s\n", 
+			  inname);
+  }
+*/
+
   if (name == NULL)
     ohshite(_("couldn't allocate memory for strdup in findpackage(%s)"),inname);
   p= name;
@@ -129,7 +139,22 @@
   pointerp= bins + (hash(name) % (BINS));
   while (*pointerp && strcasecmp((*pointerp)->name,name))
     pointerp= &(*pointerp)->next;
-  if (*pointerp) { free(name); return *pointerp; }
+  if (*pointerp) 
+  { 
+	  free(name); 
+
+/*
+	  if(strchr(inname, ':') || strncmp(inname, "libfoo", 6) == 0)
+	  {
+		  fprintf(stderr, "  Found package: multiarch flags are: "
+				  "%d (available) %d (installed)\n",
+				  (*pointerp)->available.multiarch,
+				  (*pointerp)->installed.multiarch);
+	  }
+*/
+
+	  return *pointerp; 
+  }
 
   newpkg= nfmalloc(sizeof(struct pkginfo));
   blankpackage(newpkg);


--- orig/lib/dpkg-db.h
+++ mod/lib/dpkg-db.h
@@ -103,6 +103,7 @@
   struct versionrevision version;
   struct conffile *conffiles;
   struct arbitraryfield *arbs;
+  int multiarch; /* The 'Multi-Arch' flag, 1=yes, 0=no */
 };
 
 struct perpackagestate; /* dselect and dpkg have different versions of this */


--- orig/lib/dpkg.h
+++ mod/lib/dpkg.h
@@ -108,6 +108,7 @@
 #define DEFAULTSHELL        "sh"
 #define PAGERENV            "PAGER"
 #define DEFAULTPAGER        "pager"
+#define ARCHLISTENV         "DPKG_ARCH"
 
 #define IMETHODMAXLEN        50
 #define IOPTIONMAXLEN        IMETHODMAXLEN
@@ -362,6 +363,10 @@
 
 extern volatile int onerr_abort;
 
+/*** from multi-arch.c ***/
+
+int is_allowable_arch(char*);
+
 /*** from showcright.c ***/
 
 struct cmdinfo;


--- orig/lib/dump.c
+++ mod/lib/dump.c
@@ -42,7 +42,11 @@
   assert(pigp->name);
   if (flags&fw_printheader)
     varbufaddstr(vb,"Package: ");
-  varbufaddstr(vb, pigp->name);
+  if (pifp->multiarch) {
+	varbufaddbuf(vb, pigp->name, strcspn(pigp->name, ":"));
+  } else {
+	varbufaddstr(vb, pigp->name);
+  }
   if (flags&fw_printheader)
     varbufaddc(vb,'\n');
 }


--- orig/lib/fields.c
+++ mod/lib/fields.c
@@ -70,9 +70,24 @@
             const char *filename, int lno, FILE *warnto, int *warncount,
             const char *value, const struct fieldinfo *fip) {
   const char *e;
+  char *p;
   if ((e= illegal_packagename(value,NULL)) != NULL)
     parseerr(NULL,filename,lno, warnto,warncount,pigp,0, _("invalid package name (%.250s)"),e);
-  pigp->name= findpackage(value)->name;
+  pigp->name= strdup(value);
+  /* @@@ FIXME Check for return value of the strdup here and bitch
+   * about it if it couldn't allocate memory */
+  /* @@@ Optimisation opportunity: allocate a single static buffer for
+   * this purpose, instead of using strdup() */
+
+  /* @@@ Don't use findpackage here yet -- do the tolower mangling
+   * ourselves. The findpackage will be called after all the fields
+   * have been read in, and the architecture is known.  Also, allocate
+   * our own temporary memory for the name here.
+   */
+  p= pigp->name;
+  while(*p) { *p= tolower(*p); p++; }
+
+/*  pigp->name= findpackage(value)->name; */
   /* We use the new name, as findpackage() may have
      done a tolower for us.
    */
@@ -129,11 +144,10 @@
                enum parsedbflags flags,
                const char *filename, int lno, FILE *warnto, int *warncount,
                const char *value, const struct fieldinfo *fip) {
-  pifp->essential=
-    *value ? convert_string(filename,lno,_("yes/no in boolean field"), -1,
-                            warnto,warncount,pigp,
-                            value,booleaninfos,NULL)
-           : 0;
+  if (!*value) return;
+  PKGPFIELD(pifp,fip->integer,int)= 
+	convert_string(filename,lno,_("yes/no in boolean field"),
+				   -1,warnto,warncount,pigp,value,booleaninfos,NULL);
 }
 
 void f_section(struct pkginfo *pigp, struct pkginfoperfile *pifp,


--- orig/lib/parse.c
+++ mod/lib/parse.c
@@ -69,6 +69,7 @@
   { "MD5sum",           f_filecharf,       w_filecharf,      FILEFOFF(md5sum)         },
   { "MSDOS-Filename",   f_filecharf,       w_filecharf,      FILEFOFF(msdosname)      },
   { "Description",      f_charfield,       w_charfield,      PKGIFPOFF(description)   },
+  { "Multi-Arch",       f_boolean,         w_booleandefno,   PKGIFPOFF(multiarch)     },
   /* Note that aliases are added to the nicknames table in parsehelp.c. */
   {  NULL   /* sentinel - tells code that list is ended */                               }
 };
@@ -98,6 +99,7 @@
   int fieldlen= 0, valuelen= 0;
   int *ip, c;
   struct stat stat;
+  const char *tmp_name;
 
   if (warncount) *warncount= 0;
   newpifp= (flags & pdb_recordavailable) ? &newpig.available : &newpig.installed;
@@ -194,6 +196,7 @@
 	fieldstart= nick->canon;
 	fieldlen= strlen(fieldstart);
       }
+/* @@@ Start of field loading code. Everything above here is basic parsing */
       for (fip= fieldinfos, ip= fieldencountered;
            fip->name && strncasecmp(fieldstart,fip->name, fieldlen);
            fip++, ip++);
@@ -224,6 +227,17 @@
       }
       if (EOF_mmap(dataptr, endptr) || c == '\n' || c == MSDOS_EOF_CHAR) break;
     } /* loop per field */
+/* @@@ Done loading the package info now */
+	/* @@@ Check to see if we have a multiarch package. If so, modify
+	 * its name */
+	if (newpifp->multiarch) {
+		tmp_name= newpig.name;
+		newpig.name= m_malloc(strlen(newpig.name) + strlen(newpifp->architecture) + 2);
+		strcpy(newpig.name, tmp_name);
+		strcat(newpig.name, ":");
+		strcat(newpig.name, newpifp->architecture);
+	}
+
     if (pdone && donep)
       parseerr(NULL,filename,lno, warnto,warncount,&newpig,0,
                _("several package info entries found, only one allowed"));
@@ -270,9 +284,26 @@
       newpifp->conffiles= NULL;
     }
 
+/*
+	if(newpifp->multiarch || strncmp(newpig.name, "libfoo", 6) == 0) {
+		fprintf(stderr, "Found an interesting package: %s %s %d\n",
+				newpig.name,
+				newpifp->architecture,
+				newpifp->multiarch);
+		if(flags & pdb_recordavailable)
+			fprintf(stderr, "  Recording as available\n");
+		else
+			fprintf(stderr, "  Recording as installed?\n");
+	}
+*/
+
     pigp= findpackage(newpig.name);
     pifp= (flags & pdb_recordavailable) ? &pigp->available : &pigp->installed;
     if (!pifp->valid) blankpackageperfile(pifp);
+	/* @@@ Throw away the old temporary name we were using and rewrite
+	 * to use the one that findpackage gave us */
+	free(newpig.name);
+	newpig.name= pigp->name;
 
     /* Copy the priority and section across, but don't overwrite existing
      * values if the pdb_weakclassification flag is set.
@@ -313,7 +344,7 @@
     pdone++;
     if (EOF_mmap(dataptr, endptr)) break;
     if (c == '\n') lno++;
-  }
+  } /* Loop per package */
   pop_cleanup(0);
 #ifdef HAVE_MMAP
   munmap(data, stat.st_size);


--- orig/src/archives.c
+++ mod/src/archives.c
@@ -235,6 +235,7 @@
                           struct pkginfoperfile *newpifp,
                           struct pkginfo *oldpigp) {
   struct dependency *dep;
+  int len;
   
   debug(dbg_depcon,"does_replace new=%s old=%s (%s)",newpigp->name,
         oldpigp->name,versiondescribe(&oldpigp->installed.version,
@@ -247,6 +248,18 @@
     debug(dbg_depcon,"does_replace ... yes");
     return 1;
   }
+
+  /* @@@ Implicit replaces between multiarch and uniarch packages with
+   * the same name. Nasty hackery here. */
+  if (newpifp->multiarch) {
+	  len = strcspn(newpigp->name, ":");
+	  if (strncmp(newpigp->name, oldpigp->name, len) == 0
+		  && oldpigp->name[len] == 0) {
+		  debug(dbg_depcon,"does_replace ... yes (implicit multiarch)");
+		  return 1;
+	  }
+  }
+
   debug(dbg_depcon,"does_replace ... no");
   return 0;
 }
@@ -458,16 +471,50 @@
             forcibleerr(fc_overwritedir, _("trying to overwrite directory `%.250s' "
                         "in package %.250s with nondirectory"),
                         nifd->namenode->name,otherpkg->name);
-          } else {
-            /* WTA: At this point we are replacing something without a Replaces.
-	     * if the new object is a directory and the previous object does not
-	     * exist assume it's also a directory and don't complain
-	     */
-            if (! (statr && ti->Type==Directory))
-              forcibleerr(fc_overwrite,
-                        _("trying to overwrite `%.250s', which is also in package %.250s"),
-                        nifd->namenode->name,otherpkg->name);
+			continue;
+		  }
+		  /* If both packages are multiarch, and we're replacing a link
+		   * with a link */
+		  if (tc->pkg->available.multiarch && otherpkg->installed.multiarch
+			  && !statr && S_ISLNK(stab.st_mode) && ti->Type == SymbolicLink) {
+			/* If both packages have the same name, modulo architecture */
+			if(strncmp(tc->pkg->name, 
+					   otherpkg->name, 
+					   strcspn(tc->pkg->name, ":")
+					   ) == 0) {
+			  /* Bah. readlink() doesn't tell us how much space it
+			   * actually needs, so keep trying until it works */
+			  int bufsize= 250;
+			  char *buf= m_malloc(sizeof(char)*bufsize);
+			  int sizeread= readlink(fnamevb.buf, buf, bufsize);
+
+			  while(sizeread == bufsize) {
+				bufsize *= 2;
+				buf= m_realloc(buf, sizeof(char)*bufsize);
+				sizeread= readlink(fnamevb.buf, buf, bufsize);
+			  }
+
+			  if(sizeread == -1) {
+				perror("readlink() problem: ");
+				ohshite("Had trouble reading link %.250s which previous experience suggests existed not 100 lines above", otherpkg->name);
+			  }
+
+			  /* If both links point to the same place */
+			  if(strncmp(buf, ti->LinkName, sizeread) == 0) {
+				free(buf);
+				continue;
+			  }
+			  free(buf);
+			}
           }
+		  /* WTA: At this point we are replacing something without a Replaces.
+		   * if the new object is a directory and the previous object does not
+		   * exist assume it's also a directory and don't complain
+		   */
+		  if (! (statr && ti->Type==Directory))
+			forcibleerr(fc_overwrite,
+                      _("trying to overwrite `%.250s', which is also in package %.250s"),
+                      nifd->namenode->name,otherpkg->name);
         }
       }
     }


--- orig/src/main.c
+++ mod/src/main.c
@@ -547,6 +547,8 @@
   jmp_buf ejbuf;
   static void (*actionfunction)(const char *const *argv);
 
+  fprintf(stderr, "EXPERIMENTAL BIARCH DPKG 2004-06-01.01\n");
+
   standard_startup(&ejbuf, argc, &argv, DPKG, 1, cmdinfos);
   if (!cipaction) badusage(_("need an action option"));
 


--- orig/src/processarc.c
+++ mod/src/processarc.c
@@ -84,6 +84,8 @@
   struct stat stab;
   struct packageinlist *deconpil, *deconpiltemp;
   
+  char *truncname;
+
   cleanup_pkg_failed= cleanup_conflictor_failed= 0;
   admindirlen= strlen(admindir);
 
@@ -190,6 +192,10 @@
   waitsubproc(c1,BACKEND " --control",0);
   strcpy(cidirrest,CONTROLFILE);
 
+/*
+  fprintf(stderr, "processarc.c: Loading package details from %s\n", cidir);
+*/
+
   parsedb(cidir, pdb_recordavailable|pdb_rejectstatus|pdb_ignorefiles|pdb_weakclassification,
           &pkg,NULL,NULL);
   if (!pkg->files) {
@@ -208,8 +214,7 @@
   }
 
   if (pkg->available.architecture && *pkg->available.architecture &&
-      strcmp(pkg->available.architecture,"all") &&
-      strcmp(pkg->available.architecture,architecture))
+	  ! is_allowable_arch(pkg->available.architecture))
     forcibleerr(fc_architecture,
                 _("package architecture (%s) does not match system (%s)"),
                 pkg->available.architecture,architecture);
@@ -217,6 +222,11 @@
   if (!pkg->installed.valid) blankpackageperfile(&pkg->installed);
   assert(pkg->available.valid);
 
+/*
+  fprintf(stderr, "  Package %s has multiarch flags %d,%d\n",
+		  pkg->name, pkg->available.multiarch, pkg->installed.multiarch);
+*/
+
   for (deconpil= deconfigure;
        deconpil;
        deconpil= deconpiltemp) {
@@ -275,6 +285,7 @@
     if (psearch->up->type != dep_conflicts) continue;
     check_conflict(psearch->up, pkg, pfilename);
   }
+  /* @@@ Implied conflicts checks here? */
   
   ensure_allinstfiles_available();
   filesdbinit();
@@ -809,6 +820,7 @@
   pkg->installed.version= pkg->available.version;
   pkg->installed.origin = pkg->available.origin;                               
   pkg->installed.bugs = pkg->available.bugs;                                   
+  pkg->installed.multiarch = pkg->available.multiarch;
 
   /* We have to generate our own conffiles structure. */
   pkg->installed.conffiles= 0; iconffileslastp= &pkg->installed.conffiles;



--- /dev/null
+++ mod/lib/multi-arch.c
@@ -0,0 +1,46 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * multi-arch.c - support for the Multi-Arch: extensions
+ * 
+ * Copyright (C) 2004 Hugo Mills <[EMAIL PROTECTED]>
+ *
+ * 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 <config.h>
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "dpkg.h"
+
+/* List of acceptable architectures */
+const char *architectures[] = ARCH_LIST;
+
+int is_allowable_arch(char *archtest)
+{
+  const char **ptr;
+
+  if(strcmp(archtest,"all") == 0)
+	return 1;
+
+  ptr = architectures;
+  while(*ptr) {
+	if(strcmp(archtest,*ptr) == 0) return 1;
+	ptr++;
+  }
+
+  return 0;
+}
--- /dev/null
+++ mod/subarchtable
@@ -0,0 +1,2 @@
+amd64	{ "amd64", "i386", NULL }
+i386	{ "amd64", "i386", NULL }

Reply via email to