File rpm-mingw.diff of Package mingw32-rpm

--- build/Makefile.am	2009-06-23 13:40:57.000000000 +0200
+++ build/Makefile.am	2009-12-14 10:16:31.000000000 +0100
@@ -10,10 +10,16 @@
 usrlibdir = $(libdir)
 usrlib_LTLIBRARIES = librpmbuild.la
 librpmbuild_la_SOURCES = \
-	build.c buildio.h expression.c files.c misc.c names.c pack.c \
+	buildio.h expression.c misc.c names.c \
 	parseBuildInstallClean.c parseChangelog.c parseDescription.c \
 	parseFiles.c parsePreamble.c parsePrep.c parseReqs.c parseScript.c \
-	parseSpec.c poptBT.c reqprov.c rpmfc.c spec.c
+	parseSpec.c poptBT.c reqprov.c spec.c
+
+if !WIN32
+librpmbuild_la_SOURCES += \
+	build.c files.c pack.c rpmfc.c
+endif
+
 librpmbuild_la_LDFLAGS = -version-info 0:0:0
 librpmbuild_la_LIBADD = \
 	$(top_builddir)/lib/librpm.la \
--- build/names.c	2009-06-23 13:40:57.000000000 +0200
+++ build/names.c	2009-12-14 10:16:31.000000000 +0100
@@ -33,6 +33,7 @@
 
 const char *getUname(uid_t uid)
 {
+#ifndef _WIN32
     struct passwd *pw;
     int x;
 
@@ -51,10 +52,14 @@
     uids[uid_used] = uid;
     unames[uid_used] = xstrdup(pw->pw_name);
     return unames[uid_used++];
+#else
+    return "root";
+#endif
 }
 
 const char *getUnameS(const char *uname)
 {
+#ifndef _WIN32
     struct passwd *pw;
     int x;
 
@@ -76,10 +81,14 @@
 	unames[uid_used] = xstrdup(pw->pw_name);
     }
     return unames[uid_used++];
+#else
+    return "root";
+#endif
 }
 
 uid_t getUidS(const char *uname)
 {
+#ifndef _WIN32
     struct passwd *pw;
     int x;
 
@@ -101,10 +110,14 @@
 	unames[uid_used] = xstrdup(pw->pw_name);
     }
     return uids[uid_used++];
+#else
+    return 0;
+#endif
 }
 
 const char *getGname(gid_t gid)
 {
+#ifndef _WIN32
     struct group *gr;
     int x;
 
@@ -123,10 +136,14 @@
     gids[gid_used] = gid;
     gnames[gid_used] = xstrdup(gr->gr_name);
     return gnames[gid_used++];
+#else
+    return "root";
+#endif
 }
 
 const char *getGnameS(const char *gname)
 {
+#ifndef _WIN32
     struct group *gr;
     int x;
 
@@ -148,10 +165,14 @@
 	gnames[gid_used] = xstrdup(gr->gr_name);
     }
     return gnames[gid_used++];
+#else
+    return "root";
+#endif
 }
 
 gid_t getGidS(const char *gname)
 {
+#ifndef _WIN32
     struct group *gr;
     int x;
 
@@ -173,6 +194,9 @@
 	gnames[gid_used] = xstrdup(gr->gr_name);
     }
     return gids[gid_used++];
+#else
+    return 0;
+#endif
 }
 
 rpm_time_t * getBuildTime(void)
--- configure.ac	2009-12-14 10:15:49.000000000 +0100
+++ configure.ac	2009-12-14 10:16:31.000000000 +0100
@@ -13,6 +13,24 @@
 
 AC_DISABLE_STATIC
 
+AC_CANONICAL_HOST
+
+case $host_os in
+mingw*)
+  HOST_IS_WIN32=yes
+  WITH_INTL_LIB=-lintl
+  WITH_SOCKET_LIB=-lws2_32
+  WITH_REGEX_LIB=-lregex;;
+*)
+  HOST_IS_WIN32=no
+  WITH_PTHREAD_LIB=-lpthread;;
+esac
+AM_CONDITIONAL([WIN32], [test $HOST_IS_WIN32 = yes])
+AC_SUBST(WITH_INTL_LIB)
+AC_SUBST(WITH_SOCKET_LIB)
+AC_SUBST(WITH_REGEX_LIB)
+AC_SUBST(WITH_PTHREAD_LIB)
+
 dnl Checks for programs.
 AC_PROG_CXX
 AC_PROG_AWK
@@ -33,10 +51,16 @@
 AS=${AS-as}
 AC_SUBST(AS)
 if test "$GCC" = yes; then
-    CFLAGS="$CFLAGS -fPIC -DPIC -D_REENTRANT -Wall -Wpointer-arith -Wmissing-prototypes -Wno-char-subscripts"
+    CFLAGS="$CFLAGS -DPIC -Wall -Wpointer-arith -Wmissing-prototypes -Wno-char-subscripts"
+    if test $HOST_IS_WIN32 != yes; then
+        CFLAGS="$CFLAGS -fPIC -D_REENTRANT"
+    fi
     # XXX disabled for now due to noise from NSPR headers
     # CFLAGS="$CFLAGS -Wstrict-prototypes"
-    cflags_to_try="-fno-strict-aliasing -fstack-protector"
+    cflags_to_try="-fno-strict-aliasing"
+    if test $HOST_IS_WIN32 != yes; then
+        cflags_to_try="$cflags_to_try -fstack-protector"
+    fi
     AC_MSG_CHECKING([supported compiler flags])
     old_cflags=$CFLAGS
     echo
@@ -214,10 +238,22 @@
 AC_CHECK_HEADERS([bzlib.h],[
   AC_CHECK_LIB(bz2, bzread, [WITH_BZ2_LIB=-lbz2],
   [
-    AC_CHECK_LIB(bz2, BZ2_bzread,[ 
-      WITH_BZ2_LIB="-lbz2"
-      AC_DEFINE(HAVE_BZ2_1_0, 1, [Define as 1 if you bzip2 1.0])
-    ]) 
+    save_LIBS="$LIBS"
+    LIBS="$LIBS -lbz2"
+    AC_MSG_CHECKING([BZ2_bzread in -lbz2])
+    AC_TRY_LINK([#include <bzlib.h>
+        ],
+        [int main (void)
+         {
+           return BZ2_bzread (NULL, NULL, 0);
+         }
+        ],
+        [WITH_BZ2_LIB="-lbz2"
+         AC_DEFINE(HAVE_BZ2_1_0, 1, [Define as 1 if you have bzip2 1.0])
+         AC_MSG_RESULT([yes])
+        ],
+        [AC_MSG_RESULT([no])])
+    LIBS="$save_LIBS"
   ])
 ])
 AC_SUBST(WITH_BZ2_LIB)
@@ -350,20 +386,22 @@
 AC_SUBST(WITH_NSS_LIB)
 
 #=================
-# Check for magic library.
-WITH_MAGIC_INCLUDE=
-WITH_MAGIC_LIB=
-
-AC_CHECK_HEADER([magic.h], [
-    AC_CHECK_LIB(magic, magic_open, [
-      WITH_MAGIC_INCLUDE=
-      WITH_MAGIC_LIB="-lmagic"
+if test $HOST_IS_WIN32 != yes; then
+    # Check for magic library.
+    WITH_MAGIC_INCLUDE=
+    WITH_MAGIC_LIB=
+
+    AC_CHECK_HEADER([magic.h], [
+	AC_CHECK_LIB(magic, magic_open, [
+	  WITH_MAGIC_INCLUDE=
+	  WITH_MAGIC_LIB="-lmagic"
+	],[
+	  AC_MSG_ERROR([missing required library 'libmagic']) 
+	])
     ],[
-      AC_MSG_ERROR([missing required library 'libmagic']) 
+	  AC_MSG_ERROR([missing required header magic.h]) 
     ])
-],[
-      AC_MSG_ERROR([missing required header magic.h]) 
-])
+fi
 
 AC_SUBST(WITH_MAGIC_INCLUDE)
 AC_SUBST(WITH_MAGIC_LIB)
@@ -486,7 +524,7 @@
 AC_CHECK_HEADERS(limits.h)
 AC_CHECK_HEADERS(fcntl.h getopt.h grp.h memory.h netdb.h pwd.h utime.h)
 
-AC_CHECK_HEADERS(sys/ipc.h sys/socket.h sys/select.h)
+AC_CHECK_HEADERS(sys/ipc.h sys/socket.h sys/select.h sys/signal.h)
 AC_CHECK_HEADERS(sys/types.h sys/stdtypes.h)
 AC_CHECK_HEADERS(sys/mman.h sys/resource.h sys/utsname.h sys/wait.h)
 
@@ -680,7 +718,7 @@
 
 AC_CHECK_FUNCS(ftok)
 
-AC_CHECK_FUNCS([mkstemp], [], [AC_MSG_ERROR([mkstemp() is required by rpm])])
+AC_CHECK_FUNCS([mkstemp], [], [if test $HOST_IS_WIN32 != yes; then AC_MSG_ERROR([mkstemp() is required by rpm]); fi])
 
 dnl XXX Glob *is* broken on linux with libc5, solaris and possibly aix when
 dnl %files gets something like
--- lib/backend/db3.c	2009-11-25 07:53:30.000000000 +0100
+++ lib/backend/db3.c	2009-12-14 10:16:31.000000000 +0100
@@ -197,7 +197,7 @@
     return 0;
 }
 
-#if (DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 5)
+#if (DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 5 && !defined (_WIN32))
 /*
  * dbenv->failchk() callback method for determining is the given pid/tid 
  * is alive. We only care about pid's though. 
@@ -280,7 +280,7 @@
 
  /* dbenv->set_paniccall(???) */
 
-#if (DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 5)
+#if (DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 5 && !defined (_WIN32))
     /* 
      * These enable automatic stale lock removal. 
      * thread_count 8 is some kind of "magic minimum" value...
@@ -374,7 +374,7 @@
     if (rc)
 	goto errxit;
 
-#if (DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 5)
+#if (DB_VERSION_MAJOR >= 4 && DB_VERSION_MINOR >= 5 && !defined (_WIN32))
     /* stale lock removal */
     rc = dbenv->failchk(dbenv, 0);
     rc = cvtdberr(dbi, "dbenv->failchk", rc, _debug);
@@ -1068,6 +1068,7 @@
 		if (!(db->fd(db, &fdno) == 0 && fdno >= 0)) {
 		    rc = 1;
 		} else {
+#ifndef _WIN32
 		    struct flock l;
 		    memset(&l, 0, sizeof(l));
 		    l.l_whence = 0;
@@ -1078,6 +1079,12 @@
 		    l.l_pid = 0;
 
 		    rc = fcntl(fdno, F_SETLK, (void *) &l);
+#else
+		    if ((dbi->dbi_mode & O_ACCMODE) == O_RDONLY)
+			rc = 0;
+		    else
+			rc = (LockFile((HANDLE)_get_osfhandle(fdno), 0, 0, -1, -1) != 0);
+#endif
 		    if (rc) {
 			/* Warning iff using non-private CDB locking. */
 			rc = ((dbi->dbi_use_dbenv &&
--- lib/backend/dbconfig.c	2009-11-25 07:53:30.000000000 +0100
+++ lib/backend/dbconfig.c	2009-12-14 10:16:31.000000000 +0100
@@ -298,7 +298,11 @@
 	    for (oe = o; oe && *oe; oe++) {
 		if (risspace(*oe))
 		    break;
-		if (oe[0] == ':' && !(oe[1] == '/' && oe[2] == '/'))
+		if (oe[0] == ':' && !(oe[1] == '/' && oe[2] == '/')
+#ifdef _WIN32
+		    && !(oe > o && isalpha(oe[-1]) && oe[1] == '/')
+#endif
+								   )
 		    break;
 	    }
 	    if (oe && *oe)
--- lib/fs.c	2009-06-23 13:40:57.000000000 +0200
+++ lib/fs.c	2009-12-14 10:16:31.000000000 +0100
@@ -104,7 +104,9 @@
 	if (stat(filesystems[i].mntPoint, &sb)) {
 	    switch (errno) {
 	    case EACCES: /* fuse mount */
+#ifdef ESTALE
 	    case ESTALE: 
+#endif
 		continue;
 	    default:
 	    	rpmlog(RPMLOG_ERR, _("failed to stat %s: %s\n"), fsnames[i],
@@ -204,7 +206,9 @@
 
 	if (stat(mntdir, &sb)) {
 	    switch (errno) {
+#ifdef ESTALE
 	    case ESTALE:
+#endif
 	    case EACCES:
 		continue;
 	    default:
--- lib/header_internal.h	2009-06-23 13:40:57.000000000 +0200
+++ lib/header_internal.h	2009-12-14 10:16:31.000000000 +0100
@@ -5,7 +5,9 @@
  * \file lib/header_internal.h
  */
 
+#ifndef _WIN32
 #include <netinet/in.h>
+#endif
 
 #include <rpm/header.h>
 
--- lib/Makefile.am	2009-10-26 06:58:01.000000000 +0100
+++ lib/Makefile.am	2009-12-14 10:16:31.000000000 +0100
@@ -11,6 +11,9 @@
 AM_CPPFLAGS += -DSYSCONFDIR="\"$(sysconfdir)\""
 AM_CPPFLAGS += -DLOCALSTATEDIR="\"$(localstatedir)\""
 AM_CPPFLAGS += -DLIBRPMALIAS_FILENAME="\"rpmpopt-${VERSION}\""
+if WIN32
+AM_CPPFLAGS += -DPREFIX="\"$(prefix)\""
+endif
 
 check_PROGRAMS =
 CLEANFILES =
@@ -39,7 +42,7 @@
 librpm_la_SOURCES += backend/sqlite.c
 endif
 
-librpm_la_LDFLAGS = -version-info 0:0:0
+librpm_la_LDFLAGS = -version-info 0:0:0 -no-undefined
 
 librpm_la_LIBADD = \
 	$(top_builddir)/rpmio/librpmio.la \
--- lib/misc.c	2009-06-23 13:40:57.000000000 +0200
+++ lib/misc.c	2009-12-14 10:16:31.000000000 +0100
@@ -22,6 +22,7 @@
 
 int unameToUid(const char * thisUname, uid_t * uid)
 {
+#ifndef _WIN32
 static char * lastUname = NULL;
     static size_t lastUnameLen = 0;
     static size_t lastUnameAlloced;
@@ -60,11 +61,15 @@
 
     *uid = lastUid;
 
+#else
+    *uid = 0;
+#endif
     return 0;
 }
 
 int gnameToGid(const char * thisGname, gid_t * gid)
 {
+#ifndef _WIN32
 static char * lastGname = NULL;
     static size_t lastGnameLen = 0;
     static size_t lastGnameAlloced;
@@ -113,11 +118,15 @@
 
     *gid = lastGid;
 
+#else
+    *gid = 0;
+#endif
     return 0;
 }
 
 const char * uidToUname(uid_t uid)
 {
+#ifndef _WIN32
     static uid_t lastUid = (uid_t) -1;
 static char * lastUname = NULL;
     static size_t lastUnameLen = 0;
@@ -145,10 +154,14 @@
 
 	return lastUname;
     }
+#else
+    return "root";
+#endif
 }
 
 const char * gidToGname(gid_t gid)
 {
+#ifndef _WIN32
     static gid_t lastGid = (gid_t) -1;
 static char * lastGname = NULL;
     static size_t lastGnameLen = 0;
@@ -176,4 +189,7 @@
 
 	return lastGname;
     }
+#else
+    return "root";
+#endif
 }
--- lib/package.c	2009-10-26 06:58:01.000000000 +0100
+++ lib/package.c	2009-12-14 10:16:31.000000000 +0100
@@ -4,7 +4,11 @@
 
 #include "system.h"
 
+#ifndef _WIN32
 #include <netinet/in.h>
+#else
+#include <winsock2.h>
+#endif
 
 #include <rpm/rpmlib.h>			/* XXX RPMSIGTAG, other sig stuff */
 #include <rpm/rpmts.h>
--- lib/poptALL.c	2009-06-23 13:40:57.000000000 +0200
+++ lib/poptALL.c	2009-12-14 10:16:31.000000000 +0100
@@ -222,9 +222,11 @@
  { "nosignature", '\0', 0, 0, RPMCLI_POPT_NOSIGNATURE,
         N_("don't verify package signature(s)"), NULL },
 
+#ifndef _WIN32
  { "pipe", '\0', POPT_ARG_STRING|POPT_ARGFLAG_DOC_HIDDEN, &rpmcliPipeOutput, 0,
 	N_("send stdout to CMD"),
 	N_("CMD") },
+#endif
 #if !defined(POPT_RCFILE)
  { "rcfile", '\0', POPT_ARG_STRING, &rpmcliRcfile, 0,
 	N_("read <FILE:...> instead of default file(s)"),
--- lib/psm.c	2009-06-23 13:40:57.000000000 +0200
+++ lib/psm.c	2009-12-14 10:16:31.000000000 +0100
@@ -406,6 +406,7 @@
     return tag;
 }
 
+#ifndef _WIN32
 /**
  * Wait for child process to be reaped.
  * @param psm		package state machine data
@@ -428,6 +429,7 @@
 
     return psm->sq.reaped;
 }
+#endif
 
 /**
  * Run internal Lua script.
@@ -518,6 +520,7 @@
 
 static const char * ldconfig_path = "/sbin/ldconfig";
 
+#ifndef _WIN32
 static void doScriptExec(rpmts ts, ARGV_const_t argv, rpmtd prefixes,
 			FD_t scriptFd, FD_t out)
 {
@@ -611,6 +614,7 @@
     }
     _exit(127); /* exit 127 for compatibility with bash(1) */
 }
+#endif
 
 /**
  * Run scriptlet with args.
@@ -634,6 +638,7 @@
 static rpmRC runScript(rpmpsm psm, Header h, rpmTag stag, ARGV_t * argvp,
 		const char * script, int arg1, int arg2)
 {
+#ifndef _WIN32
     const rpmts ts = psm->ts;
     char * fn = NULL;
     int xx;
@@ -801,6 +806,9 @@
     free(sname);
 
     return rc;
+#else
+    return RPMRC_FAIL;
+#endif
 }
 
 /**
@@ -1562,7 +1570,7 @@
 	    xx = chdir("/");
 	    if (rootDir != NULL && strcmp(rootDir, "/") && *rootDir == '/')
 	        if (chroot(rootDir) == -1) {
-		    rpmlog(RPMLOG_ERR, _("Unable to change root directory: %m\n"));
+		    rpmlog(RPMLOG_ERR, _("Unable to change root directory: %s\n"), strerror(errno));
 		    return -1;
 		}
 	    psm->chrootDone = 1;
--- lib/query.c	2009-11-25 08:00:29.000000000 +0100
+++ lib/query.c	2009-12-14 10:16:31.000000000 +0100
@@ -71,23 +71,7 @@
     tm = localtime(&when);
     timefield[0] = '\0';
     if (tm != NULL)
-    {	const char *fmt;
-	if (now > when + 6L * 30L * 24L * 60L * 60L ||	/* Old. */
-	    now < when - 60L * 60L)			/* In the future.  */
-	{
-	/* The file is fairly old or in the future.
-	 * POSIX says the cutoff is 6 months old;
-	 * approximate this by 6*30 days.
-	 * Allow a 1 hour slop factor for what is considered "the future",
-	 * to allow for NFS server/client clock disagreement.
-	 * Show the year instead of the time of day.
-	 */        
-	    fmt = "%b %e  %Y";
-	} else {
-	    fmt = "%b %e %H:%M";
-	}
-	(void)strftime(timefield, sizeof(timefield) - 1, fmt, tm);
-    }
+	(void)strftime(timefield, sizeof(timefield) - 1, "%Y-%m-%d %H:%M", tm);
 
     rpmlog(RPMLOG_NOTICE, "%s %4d %-8s%-8s %10s %s %s\n", perms,
 	(int)nlink, ownerfield, groupfield, sizefield, timefield, 
--- lib/rpmchecksig.c	2009-10-26 06:58:01.000000000 +0100
+++ lib/rpmchecksig.c	2009-12-14 10:16:31.000000000 +0100
@@ -21,6 +21,26 @@
 
 #include "debug.h"
 
+#ifdef _WIN32
+static char *
+strndup (const char *s, size_t n)
+{
+    char *retval;
+
+    if (strlen(s) <= n)
+	return strdup(s);
+
+    retval = malloc(n+1);
+    if (retval == NULL)
+	return NULL;
+
+    memcpy(retval, s, n);
+    retval[n] = '\0';
+
+    return retval;
+}
+#endif
+
 int _print_pkts = 0;
 
 static int closeFile(FD_t *fdp)
--- lib/rpmdb.c	2009-11-25 07:50:31.000000000 +0100
+++ lib/rpmdb.c	2009-12-14 10:16:31.000000000 +0100
@@ -641,8 +641,9 @@
 
 int rpmdbCheckTerminate(int terminate)
 {
-    sigset_t newMask, oldMask;
     static int terminating = 0;
+#ifndef _WIN32
+    sigset_t newMask, oldMask;
 
     if (terminating) return 0;
 
@@ -656,6 +657,10 @@
      || rpmsqIsCaught(SIGPIPE) > 0
      || terminate)
 	terminating = 1;
+#else
+    if (terminate)
+	terminating = 1;
+#endif
 
     if (terminating) {
 	rpmdb db;
@@ -673,7 +678,9 @@
 	    (void) rpmdbClose(db);
 	}
     }
+#ifndef _WIN32
     sigprocmask(SIG_SETMASK, &oldMask, NULL);
+#endif
     return terminating;
 }
 
@@ -691,6 +698,7 @@
  */
 static int blockSignals(sigset_t * oldMask)
 {
+#ifndef _WIN32
     sigset_t newMask;
 
     (void) sigfillset(&newMask);		/* block all signals */
@@ -701,6 +709,9 @@
     (void) sigdelset(&newMask, SIGTERM);
     (void) sigdelset(&newMask, SIGPIPE);
     return sigprocmask(SIG_BLOCK, &newMask, NULL);
+#else
+    return 0;
+#endif
 }
 
 /**
@@ -708,8 +719,12 @@
  */
 static int unblockSignals(sigset_t * oldMask)
 {
+#ifndef _WIN32
     (void) rpmdbCheckSignals();
     return sigprocmask(SIG_SETMASK, oldMask, NULL);
+#else
+    return 0;
+#endif
 }
 
 #define	_DB_ROOT	"/"
@@ -856,11 +871,13 @@
     dbiTagsFree();
 
 exit:
+#ifndef _WIN32
     (void) rpmsqEnable(-SIGHUP,	NULL);
     (void) rpmsqEnable(-SIGINT,	NULL);
     (void) rpmsqEnable(-SIGTERM,NULL);
     (void) rpmsqEnable(-SIGQUIT,NULL);
     (void) rpmsqEnable(-SIGPIPE,NULL);
+#endif
     return rc;
 }
 
@@ -921,6 +938,9 @@
 	return NULL;
     }
     db->db_errpfx = rpmExpand( (epfx && *epfx ? epfx : _DB_ERRPFX), NULL);
+#ifdef _WIN32
+    rpmioMapConfigTimeDir(&db->db_home, 1);
+#endif
     /* XXX remove environment after chrooted operations, for now... */
     db->db_remove_env = ((strcmp(db->db_root, "/") != 0)? 1 : 0);
     db->db_filter_dups = _db_filter_dups;
@@ -957,11 +977,13 @@
     if (db == NULL)
 	return 1;
 
+#ifndef _WIN32
     (void) rpmsqEnable(SIGHUP,	NULL);
     (void) rpmsqEnable(SIGINT,	NULL);
     (void) rpmsqEnable(SIGTERM,NULL);
     (void) rpmsqEnable(SIGQUIT,NULL);
     (void) rpmsqEnable(SIGPIPE,NULL);
+#endif
 
     db->db_api = _dbapi;
 
--- lib/rpmlead.c	2009-10-26 06:58:01.000000000 +0100
+++ lib/rpmlead.c	2009-12-14 10:16:31.000000000 +0100
@@ -4,7 +4,11 @@
 
 #include "system.h"
 
+#ifndef _WIN32
 #include <netinet/in.h>
+#else
+#include <winsock2.h>
+#endif
 
 #include <rpm/rpmlib.h>		/* rpmGetOs/ArchInfo() */
 #include <rpm/rpmlog.h>
--- lib/rpmlock.c	2009-10-26 06:58:01.000000000 +0100
+++ lib/rpmlock.c	2009-12-14 10:16:31.000000000 +0100
@@ -44,11 +44,11 @@
     }
     if (lock != NULL) {
 	mode_t oldmask = umask(022);
-	lock->fd = open(rpmlock_path, O_RDWR|O_CREAT, 0644);
+	lock->fd = open(rpmlock_path, O_RDWR|O_CREAT|_O_BINARY, 0644);
 	(void) umask(oldmask);
 
 	if (lock->fd == -1) {
-	    lock->fd = open(rpmlock_path, O_RDONLY);
+	    lock->fd = open(rpmlock_path, O_RDONLY|_O_BINARY);
 	    if (lock->fd == -1) {
 		free(lock);
 		lock = NULL;
@@ -74,6 +74,7 @@
 {
     int res = 0;
     if (lock && (mode & lock->openmode)) {
+#ifndef _WIN32
 	struct flock info;
 	int cmd;
 	if (mode & RPMLOCK_WAIT)
@@ -90,6 +91,25 @@
 	info.l_pid = 0;
 	if (fcntl(lock->fd, cmd, &info) != -1)
 	    res = 1;
+#else
+	OVERLAPPED overlapped;
+
+	overlapped.Offset = 0;
+	overlapped.OffsetHigh = 0;
+	overlapped.hEvent = NULL;
+
+	if (mode & RPMLOCK_READ) {
+	    if (mode & RPMLOCK_WAIT)
+		res = !!LockFileEx((HANDLE)_get_osfhandle(lock->fd), 0, 0, -1, -1, &overlapped);
+	    else
+		res = !!LockFileEx((HANDLE)_get_osfhandle(lock->fd), LOCKFILE_FAIL_IMMEDIATELY, 0, -1, -1, &overlapped);
+	} else {
+	    if (mode & RPMLOCK_WAIT)
+		res = !!LockFileEx((HANDLE)_get_osfhandle(lock->fd), LOCKFILE_EXCLUSIVE_LOCK, 0, -1, -1, &overlapped);
+	    else
+		res = !!LockFileEx((HANDLE)_get_osfhandle(lock->fd), LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY, 0, -1, -1, &overlapped);
+	}
+#endif
     }
     return res;
 }
@@ -97,6 +117,7 @@
 static void rpmlock_release(rpmlock lock)
 {
     if (lock) {
+#ifndef _WIN32
 	struct flock info;
 	info.l_type = F_UNLCK;
 	info.l_whence = SEEK_SET;
@@ -104,6 +125,9 @@
 	info.l_len = 0;
 	info.l_pid = 0;
 	(void) fcntl(lock->fd, F_SETLK, &info);
+#else
+	UnlockFile((HANDLE)_get_osfhandle(lock->fd), 0, 0, -1, -1);
+#endif
      }
 }
 
--- lib/rpmrc.c	2009-10-26 06:58:01.000000000 +0100
+++ lib/rpmrc.c	2009-12-14 10:16:31.000000000 +0100
@@ -417,20 +417,20 @@
 {
     const char *confdir = rpmConfigDir();
     if (!defrcfiles) {
-	defrcfiles = rstrscat(NULL, confdir, "/rpmrc", ":",
-				confdir, "/" RPMCANONVENDOR "/rpmrc", ":",
-				SYSCONFDIR "/rpmrc", ":",
+	defrcfiles = rstrscat(NULL, confdir, "/rpmrc", PATH_SEP_STRING,
+				confdir, "/" RPMCANONVENDOR "/rpmrc", PATH_SEP_STRING,
+				SYSCONFDIR "/rpmrc", PATH_SEP_STRING,
 			  	"~/.rpmrc", NULL);
     }
 
 #ifndef MACROFILES
     if (!macrofiles) {
-	macrofiles = rstrscat(NULL, confdir, "/macros", ":",
-				confdir, "/platform/%{_target}/macros", ":",
-  				confdir, "/" RPMCANONVENDOR "/macros", ":",
-				SYSCONFDIR "/rpm/macros.*", ":",
-				SYSCONFDIR "/rpm/macros", ":",
-				SYSCONFDIR "/rpm/%{_target}/macros", ":",
+	macrofiles = rstrscat(NULL, confdir, "/macros", PATH_SEP_STRING,
+				confdir, "/platform/%{_target}/macros", PATH_SEP_STRING,
+  				confdir, "/" RPMCANONVENDOR "/macros", PATH_SEP_STRING,
+				SYSCONFDIR "/rpm/macros.*", PATH_SEP_STRING,
+				SYSCONFDIR "/rpm/macros", PATH_SEP_STRING,
+				SYSCONFDIR "/rpm/%{_target}/macros", PATH_SEP_STRING,
 				"~/.rpmmacros", NULL);
     }
 #else
@@ -512,8 +512,8 @@
 #endif
 
 		if (doReadRC(s)) {
-		    rpmlog(RPMLOG_ERR, _("cannot open %s at %s:%d: %m\n"),
-			s, fn, linenum);
+		    rpmlog(RPMLOG_ERR, _("cannot open %s at %s:%d: %s\n"),
+			s, fn, linenum, strerror(errno));
 		    goto exit;
 		} else {
 		    continue;	/* XXX don't save include value as var/macro */
@@ -934,6 +934,7 @@
 static void defaultMachine(const char ** arch,
 		const char ** os)
 {
+#ifndef _WIN32
     static struct utsname un;
     static int gotDefaults = 0;
     char * chptr;
@@ -1182,6 +1183,14 @@
 
     if (arch) *arch = un.machine;
     if (os) *os = un.sysname;
+#else
+    if (arch) *arch = "noarch";
+#ifdef _WIN64
+    if (os) *os = "mingw64";
+#else
+    if (os) *os = "mingw32";
+#endif
+#endif
 }
 
 static
@@ -1568,9 +1577,12 @@
 	rcfiles = defrcfiles;
 
     /* Expand any globs in rcfiles. Missing files are ok here. */
-    argvSplit(&globs, rcfiles, ":");
+    argvSplit(&globs, rcfiles, PATH_SEP_STRING);
     for (p = globs; *p; p++) {
 	ARGV_t av = NULL;
+#ifdef _WIN32
+	rpmioMapConfigTimeDir(p, 1);
+#endif
 	if (rpmGlob(*p, NULL, &av) == 0) {
 	    argvAppend(&files, av);
 	    argvFree(av);
@@ -1584,7 +1596,7 @@
 	if (access(*p, R_OK) != 0) {
 	    if (rcfiles == defrcfiles && p != files)
 		continue;
-	    rpmlog(RPMLOG_ERR, _("Unable to open %s for reading: %m.\n"), *p);
+	    rpmlog(RPMLOG_ERR, _("Unable to open %s for reading: %s.\n"), *p, strerror(errno));
 	    goto exit;
 	    break;
 	} else {
--- lib/rpmts.c	2009-11-25 08:01:30.000000000 +0100
+++ lib/rpmts.c	2009-12-14 10:16:31.000000000 +0100
@@ -668,14 +668,14 @@
 
 int rpmtsSetRootDir(rpmts ts, const char * rootDir)
 {
-    if (ts == NULL || (rootDir && rootDir[0] != '/')) {
+    if (ts == NULL || (rootDir && !DIR_IS_ABSOLUTE(rootDir))) {
 	return -1;
     }
 
     ts->rootDir = _free(ts->rootDir);
     /* Ensure clean path with a trailing slash */
     ts->rootDir = rootDir ? rpmGetPath(rootDir, NULL) : xstrdup("/");
-    if (strcmp(ts->rootDir, "/") != 0) {
+    if (ts->rootDir[strlen(ts->rootDir)-1] != '/') {
 	rstrcat(&ts->rootDir, "/");
     }
     return 0;
@@ -774,6 +774,7 @@
 
 int rpmtsInitDSI(const rpmts ts)
 {
+#ifndef _WIN32
     rpmDiskSpaceInfo dsi;
     struct stat sb;
     int rc;
@@ -848,6 +849,22 @@
 		ts->filesystems[i]);
     }
     return rc;
+#else
+    ts->filesystemCount = 0;
+    ts->filesystems = malloc (sizeof (*ts->filesystems));
+    ts->filesystems[0] = "/";
+    ts->dsi = malloc (sizeof (*ts->dsi));
+    ts->dsi->dev = 0;
+    ts->dsi->bneeded = 0;
+    ts->dsi->ineeded = 0;
+    ts->dsi->bsize = 1024;
+    ts->dsi->bavail = 1000000000;
+    ts->dsi->iavail = 1000000000;
+    ts->dsi->obneeded = 0;
+    ts->dsi->oineeded = 0;
+
+    return 0;
+#endif
 }
 
 void rpmtsUpdateDSI(const rpmts ts, dev_t dev,
@@ -1109,7 +1126,7 @@
     ts->installLangs = NULL;
     {	char *tmp = rpmExpand("%{_netsharedpath}", NULL);
 	if (tmp && *tmp != '%') {
-	    argvSplit(&ts->netsharedPaths, tmp, ":");
+	    argvSplit(&ts->netsharedPaths, tmp, PATH_SEP_STRING);
 	}
 	free(tmp);
 
--- lib/signature.c	2009-12-14 10:15:49.000000000 +0100
+++ lib/signature.c	2009-12-14 10:17:24.000000000 +0100
@@ -24,6 +24,23 @@
 
 #include "debug.h"
 
+#ifdef _WIN32
+static char *
+getpass(const char *prompt)
+{
+    static char pass[100];
+
+    printf("%s:\n", prompt);
+    scanf("%.99s", pass);
+
+    return pass;
+}
+#endif
+
+#ifdef environ
+#undef environ
+#endif
+
 #if !defined(__GLIBC__) && !defined(__APPLE__)
 char ** environ = NULL;
 #endif
@@ -366,6 +383,7 @@
 		uint8_t ** pktp, size_t * pktlenp,
 		const char * passPhrase)
 {
+#ifndef _WIN32
     char * sigfile = NULL;
     int pid, status;
     int inpipe[2];
@@ -490,6 +508,10 @@
     free(sigfile);
 
     return rc;
+#else
+    errno = ENOSYS;
+    return -1;
+#endif
 }
 
 /**
@@ -505,6 +527,7 @@
 		uint8_t ** pktp, size_t * pktlenp,
 		const char * passPhrase)
 {
+#ifndef _WIN32
     char * sigfile = NULL;
     int pid, status;
     int inpipe[2];
@@ -640,6 +663,10 @@
     free(sigfile);
 
     return rc;
+#else
+    errno = ENOSYS;
+    return -1;
+#endif
 }
 
 /**
@@ -840,6 +867,7 @@
 
 static int checkPassPhrase(const char * passPhrase, const rpmSigTag sigTag)
 {
+#ifndef _WIN32
     int passPhrasePipe[2];
     int pid, status;
     int rc;
@@ -933,6 +961,9 @@
     (void) waitpid(pid, &status, 0);
 
     return ((!WIFEXITED(status) || WEXITSTATUS(status)) ? 1 : 0);
+#else
+   return 0;
+#endif
 }
 
 char * rpmGetPassPhrase(const char * prompt, const rpmSigTag sigTag)
--- lib/transaction.c	2009-11-25 07:59:11.000000000 +0100
+++ lib/transaction.c	2009-12-14 10:16:31.000000000 +0100
@@ -1036,7 +1036,7 @@
 	    /* opening db before chroot not optimal, see rhbz#103852 c#3 */
 	    xx = rpmdbOpenAll(ts->rdb);
 	    if (chroot(rootDir) == -1) {
-		rpmlog(RPMLOG_ERR, _("Unable to change root directory: %m\n"));
+		rpmlog(RPMLOG_ERR, _("Unable to change root directory: %s\n"), strerror(errno));
 		rc = -1;
 		goto exit;
 	    }
--- lib/verify.c	2009-10-26 06:58:01.000000000 +0100
+++ lib/verify.c	2009-12-14 10:16:31.000000000 +0100
@@ -482,7 +482,7 @@
     rpmdbOpenAll(rpmtsGetRdb(ts));
     if (rootDir && strcmp(rootDir, "/") != 0) {
 	if (chroot(rootDir) == -1) {
-	    rpmlog(RPMLOG_ERR, _("Unable to change root directory: %m\n"));
+	    rpmlog(RPMLOG_ERR, _("Unable to change root directory: %s\n"), strerror(errno));
 	    ec = 1;
 	    goto exit;
 	} else {
--- Makefile.am	2009-12-14 10:15:49.000000000 +0100
+++ Makefile.am	2009-12-14 10:16:31.000000000 +0100
@@ -35,6 +35,9 @@
 AM_CPPFLAGS += @WITH_LIBELF_INCLUDE@
 AM_CPPFLAGS += -DLOCALEDIR="\"$(localedir)\""
 AM_CPPFLAGS += -DLIBRPMALIAS_FILENAME="\"rpmpopt-${VERSION}\""
+if WIN32
+AM_CPPFLAGS += -DPREFIX="\"$(prefix)\""
+endif
 
 pkginclude_HEADERS =
 nodist_pkginclude_HEADERS =
@@ -78,7 +81,11 @@
 rpmbindir = `echo $(bindir) | $(SED) -e s,usr/bin,bin,`
 rpmbin_PROGRAMS = rpm
 
-bin_PROGRAMS =		rpm2cpio rpmbuild
+bin_PROGRAMS =		rpm2cpio
+
+if !WIN32
+bin_PROGRAMS +=	rpmbuild
+endif
 
 rpmlibexec_PROGRAMS =
 rpmconfig_SCRIPTS =	find-provides find-requires mkinstalldirs \
@@ -113,6 +120,7 @@
 endif
 endif
 
+if !WIN32
 rpmlibexec_PROGRAMS +=	javadeps
 javadeps_SOURCES =	tools/javadeps.c
 javadeps_LDADD =
@@ -120,6 +128,7 @@
 rpmlibexec_PROGRAMS +=	rpmdeps
 rpmdeps_SOURCES =	tools/rpmdeps.c
 rpmdeps_LDADD =		lib/librpm.la rpmio/librpmio.la build/librpmbuild.la @WITH_POPT_LIB@
+endif
 
 bin_PROGRAMS +=		rpmgraph
 rpmgraph_SOURCES =	tools/rpmgraph.c
@@ -187,6 +196,7 @@
 rpmvar_DATA =
 
 install-exec-hook:
+if !WIN32
 	rm -f $(DESTDIR)$(bindir)/rpmquery
 	@LN_S@ ../../bin/rpm $(DESTDIR)$(bindir)/rpmquery
 	rm -f $(DESTDIR)$(bindir)/rpmverify
@@ -195,6 +205,7 @@
 	@LN_S@ ../../bin/rpm $(DESTDIR)$(bindir)/rpmsign
 	rm -f $(DESTDIR)$(bindir)/rpmdb
 	@LN_S@ ../../bin/rpm $(DESTDIR)$(bindir)/rpmdb
+endif
 
 install-data-local:
 	@case "@host_os@" in \
@@ -205,10 +216,12 @@
 
 # XXX to appease distcheck we need to remove "stuff" here...
 uninstall-local:
+if !WIN32
 	@rm -f $(DESTDIR)$(bindir)/rpmquery
 	@rm -f $(DESTDIR)$(bindir)/rpmsign
 	@rm -f $(DESTDIR)$(bindir)/rpmverify
 	@rm -f $(DESTDIR)$(bindir)/rpmdb
+endif
 
 MAINTAINERCLEANFILES = ChangeLog
 
--- misc/err.c	2009-06-23 13:40:58.000000000 +0200
+++ misc/err.c	2009-12-14 10:16:31.000000000 +0100
@@ -68,7 +68,7 @@
       fputs_unlocked (": ", stderr);
     }
   __set_errno (error);
-  fprintf (stderr, "%m\n");
+  fprintf (stderr, "%s\n", strerror(errno));
   funlockfile (stderr);
 }
 
--- misc/glob.c	2009-06-23 13:40:58.000000000 +0200
+++ misc/glob.c	2009-12-14 10:16:31.000000000 +0100
@@ -97,7 +97,12 @@
   return cp;
 }
 
-static int __glob_pattern_p (const char *pattern, int quote);
+#ifdef _WIN32
+#define __glob_pattern_p glob_pattern_p
+#else
+static
+#endif
+int __glob_pattern_p (const char *pattern, int quote);
 
 /* Do glob searching for PATTERN, placing results in PGLOB.
    The bits defined above may be set in FLAGS.
@@ -908,7 +913,10 @@
 #if !defined _LIBC || !defined NO_GLOB_PATTERN_P
 /* Return nonzero if PATTERN contains any metacharacters.
    Metacharacters can be quoted with backslashes if QUOTE is nonzero.  */
-static int
+#ifndef _WIN32
+static
+#endif
+int
 __glob_pattern_p (const char *pattern, int quote)
 {
   register const char *p;
--- misc/Makefile.am	2009-06-23 13:40:58.000000000 +0200
+++ misc/Makefile.am	2009-12-14 10:16:31.000000000 +0100
@@ -3,6 +3,10 @@
 AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir) -I$(top_builddir)/include/rpm
 AM_CPPFLAGS += -I$(top_srcdir)/misc
 
+if WIN32
+AM_CPPFLAGS += -DWINDOWS32
+endif
+
 EXTRA_DIST = \
 	basename.c	err.c		err.h \
 	error.c		error.h \
--- misc/realpath.c	2009-06-23 13:40:58.000000000 +0200
+++ misc/realpath.c	2009-12-14 10:16:31.000000000 +0100
@@ -41,14 +41,14 @@
 	path = copy_path;
 	max_path = copy_path + PATH_MAX - 2;
 	/* If it's a relative pathname use getwd for starters. */
-	if (*path != '/') {
+	if (!IS_DIR_SEP(*path)) {
 #ifdef HAVE_GETCWD
 		getcwd(new_path, PATH_MAX - 1);
 #else
 		getwd(new_path);
 #endif
 		new_path += strlen(new_path);
-		if (new_path[-1] != '/')
+		if (!IS_DIR_SEP(new_path[-1]))
 			*new_path++ = '/';
 	}
 	else {
@@ -58,30 +58,31 @@
 	/* Expand each slash-separated pathname component. */
 	while (*path != '\0') {
 		/* Ignore stray "/". */
-		if (*path == '/') {
+		if (IS_DIR_SEP(*path)) {
 			path++;
 			continue;
 		}
 		if (*path == '.') {
 			/* Ignore ".". */
-			if (path[1] == '\0' || path[1] == '/') {
+			if (path[1] == '\0' || IS_DIR_SEP(path[1])) {
 				path++;
 				continue;
 			}
 			if (path[1] == '.') {
-				if (path[2] == '\0' || path[2] == '/') {
+				if (path[2] == '\0' || IS_DIR_SEP(path[2])) {
+					char c;
 					path += 2;
 					/* Ignore ".." at root. */
 					if (new_path == resolved_path + 1)
 						continue;
 					/* Handle ".." by backing up. */
-					while ((--new_path)[-1] != '/');
+					while (c = (--new_path)[-1] && !IS_DIR_SEP(c));
 					continue;
 				}
 			}
 		}
 		/* Safely copy the next pathname component. */
-		while (*path != '\0' && *path != '/') {
+		while (*path != '\0' && !IS_DIR_SEP(*path)) {
 			if (path > max_path) {
 				errno = ENAMETOOLONG;
 				return NULL;
@@ -125,7 +126,7 @@
 		*new_path++ = '/';
 	}
 	/* Delete trailing slash but don't whomp a lone slash. */
-	if (new_path != resolved_path + 1 && new_path[-1] == '/')
+	if (new_path != resolved_path + 1 && IS_DIR_SEP(new_path[-1]))
 		new_path--;
 	/* Make sure it's null terminated. */
 	*new_path = '\0';
--- rpmio/base64.c	2009-12-14 10:15:49.000000000 +0100
+++ rpmio/base64.c	2009-12-14 10:16:31.000000000 +0100
@@ -1,7 +1,9 @@
 /* base64 encoder/decoder based on public domain implementation
  * by Chris Venter */
 
+#ifndef _WIN32
 #include <arpa/inet.h>
+#endif
 #include <stdlib.h>
 
 #include "system.h"
--- rpmio/fts.c	2009-06-23 13:40:59.000000000 +0200
+++ rpmio/fts.c	2009-12-14 10:16:31.000000000 +0100
@@ -60,6 +60,13 @@
 #   define __errno_location()	(__error())
 #   define _STAT_VER		0
 #endif
+#if defined(_WIN32)
+#   define __errno_location() 	(&errno)
+#   define dirfd(dirp)		-1
+#   define stat64		_stati64
+#   define _STAT_VER		0
+#   define __fxstat64(_stat_ver, _fd, _sbp)	_fstati64((_fd), (_sbp))
+#endif
 #include "system.h"
 #include "rpmio/fts.h"
 #include <rpm/rpmio.h>
@@ -182,6 +189,9 @@
 			break;
 		case URL_IS_UNKNOWN:
 		case URL_IS_PATH:
+#ifdef _WIN32
+			SET(FTS_NOCHDIR);
+#endif
 			break;
 		}
 
--- rpmio/fts.h	2009-06-23 13:40:59.000000000 +0200
+++ rpmio/fts.h	2009-12-14 10:16:31.000000000 +0100
@@ -59,8 +59,17 @@
 # define _D_EXACT_NAMLEN(d) (strlen((d)->d_name))
 #endif
 
+#if defined(_WIN32)
+# define _D_EXACT_NAMLEN(d) (strlen((d)->d_name))
+#endif
+
 #endif
 
+#ifdef _MSC_VER
+typedef unsigned short uint16_t;
+#else
+#include <stdint.h>
+#endif
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <dirent.h>
--- rpmio/macro.c	2009-06-23 13:40:59.000000000 +0200
+++ rpmio/macro.c	2009-12-14 10:16:31.000000000 +0100
@@ -26,6 +26,8 @@
 #include "rpmio/rpmlua.h"
 #endif
 
+#include "rpmio/rpmio_internal.h"
+
 #include "debug.h"
 
 /*! The structure used to store a macro. */
@@ -695,6 +697,9 @@
     me->name = (prev ? prev->name : xstrdup(n));
     me->opts = (o ? xstrdup(o) : NULL);
     me->body = xstrdup(b ? b : "");
+#ifdef _WIN32
+    rpmioMapConfigTimeDir(&me->body, 1);
+#endif
     me->used = 0;
     me->level = level;
     if (mep)
@@ -1526,10 +1531,13 @@
     if (macrofiles == NULL)
 	return;
 
-    argvSplit(&globs, macrofiles, ":");
+    argvSplit(&globs, macrofiles, PATH_SEP_STRING);
     for (pattern = globs; *pattern; pattern++) {
 	ARGV_t path, files = NULL;
     
+#ifdef _WIN32
+	rpmioMapConfigTimeDir((const char **) pattern, 1);
+#endif
 	/* Glob expand the macro file path element, expanding ~ to $HOME. */
 	if (rpmGlob(*pattern, NULL, &files) != 0) {
 	    continue;
--- rpmio/Makefile.am	2009-12-14 10:15:49.000000000 +0100
+++ rpmio/Makefile.am	2009-12-14 10:16:31.000000000 +0100
@@ -9,6 +9,12 @@
 AM_CPPFLAGS += @WITH_LIBELF_INCLUDE@
 AM_CPPFLAGS += -DRPMCONFIGDIR="\"@RPMCONFIGDIR@\""
 AM_CPPFLAGS += -DLOCALSTATEDIR="\"$(localstatedir)\""
+if !WITH_INTERNAL_BEECRYPT
+AM_CPPFLAGS += -I$(includedir)/beecrypt
+endif
+if WIN32
+AM_CPPFLAGS += -DPREFIX="\"$(prefix)\""
+endif
 
 usrlibdir = $(libdir)
 usrlib_LTLIBRARIES = librpmio.la
@@ -26,7 +32,7 @@
 librpmio_la_SOURCES += digest_nss.c
 endif
 
-librpmio_la_LDFLAGS = -version-info 0:0:0
+librpmio_la_LDFLAGS = -version-info 0:0:0 -no-undefined
 librpmio_la_LIBADD = \
 	../misc/libmisc.la \
 	@WITH_NSS_LIB@ \
@@ -37,7 +43,10 @@
 	@WITH_LIBELF_LIB@ \
 	@WITH_POPT_LIB@ \
 	@WITH_LZMA_LIB@ \
-	-lpthread
+	@WITH_INTL_LIB@ \
+	@WITH_SOCKET_LIB@ \
+	@WITH_REGEX_LIB@ \
+	@WITH_PTHREAD_LIB@
 
 if WITH_INTERNAL_BEECRYPT
 librpmio_la_LIBADD += $(libbeecrypt_la)
--- rpmio/rpmfileutil.c
+++ rpmio/rpmfileutil.c
@@ -209,6 +209,7 @@
 	break;
     }
 
+#if HAVE_GELF_H && HAVE_LIBELF
     /* Reap the prelink -y helper. */
     if (pid) {
 	int status;
@@ -216,6 +217,7 @@
 	if (!WIFEXITED(status) || WEXITSTATUS(status))
 	    rc = 1;
     }
+#endif
 
 exit:
     if (fsizep)
@@ -232,7 +234,11 @@
     int sfd;
     FD_t tfd = NULL;
 
+#ifdef HAVE_MKSTEMP
     sfd = mkstemp(templ);
+#else
+    sfd = open(mktemp(templ), O_RDWR|O_EXCL|_O_BINARY, 0600);
+#endif
     if (sfd < 0) {
 	goto exit;
     }
@@ -266,7 +272,7 @@
     tfd = rpmMkTemp(tempfn);
 
     if (tfd == NULL || Ferror(tfd)) {
-	rpmlog(RPMLOG_ERR, _("error creating temporary file %s: %m\n"), tempfn);
+	rpmlog(RPMLOG_ERR, _("error creating temporary file %s: %s\n"), tempfn, strerror(errno));
 	goto exit;
     }
 
@@ -291,6 +297,10 @@
 	rstrcat(&d,"/");
     }
     de = d;
+#ifdef _WIN32
+    if (isalpha(d[0]) && d[1] == ':' && d[2] == '/')
+	de = d + 2;
+#endif
     for (;(de=strchr(de+1,'/'));) {
 	struct stat st;
 	*de = '\0';
@@ -384,10 +394,24 @@
     if (path == NULL)
 	return NULL;
 
-/*fprintf(stderr, "*** RCP %s ->\n", path); */
+#ifdef VERBOSE_DEBUGGING
+    fprintf(stderr, "*** RCP %s ->\n", path);
+#endif
+
+#ifdef _WIN32
+    /* Drop prefix slashes in front of drive letter */
+    s = path;
+    while (IS_DIR_SEP(*s))
+	s++;
+    if (DIR_IS_ABSOLUTE(s))
+	memmove(path, s, strlen(s) + 1);
+#endif
+
     s = t = te = path;
     while (*s != '\0') {
-/*fprintf(stderr, "*** got \"%.*s\"\trest \"%s\"\n", (t-path), path, s); */
+#ifdef VERBOSE_DEBUGGING
+	fprintf(stderr, "*** got \"%.*s\"\trest \"%s\"\n", (t-path), path, s);
+#endif
 	switch(*s) {
 	case ':':			/* handle url's */
 	    if (s[1] == '/' && s[2] == '/') {
@@ -403,7 +427,9 @@
 		{};
 	    if (se < t && *se == '/') {
 		te = se;
-/*fprintf(stderr, "*** next pdir \"%.*s\"\n", (te-path), path); */
+#ifdef VERBOSE_DEBUGGING
+		fprintf(stderr, "*** next pdir \"%.*s\"\n", (te-path), path);
+#endif
 	    }
 	    while (s[1] == '/')
 		s++;
@@ -418,7 +444,9 @@
 	    /* as "../.", and the last '.' is stripped.  This   */
 	    /* would not be correct processing.                 */
 	    if (begin && s[1] == '.' && (s[2] == '/' || s[2] == '\0')) {
-/*fprintf(stderr, "    leading \"..\"\n"); */
+#ifdef VERBOSE_DEBUGGING
+		fprintf(stderr, "    leading \"..\"\n");
+#endif
 		*t++ = *s++;
 		break;
 	    }
@@ -446,7 +474,9 @@
 		if (te > path)
 		    for (--te; te > path && *te != '/'; te--)
 			{};
-/*fprintf(stderr, "*** prev pdir \"%.*s\"\n", (te-path), path); */
+#ifdef VERBOSE_DEBUGGING
+		fprintf(stderr, "*** prev pdir \"%.*s\"\n", (te-path), path);
+#endif
 		s++;
 		s++;
 		continue;
@@ -464,7 +494,9 @@
 	t--;
     *t = '\0';
 
-/*fprintf(stderr, "\t%s\n", path); */
+#ifdef VERBOSE_DEBUGGING
+    fprintf(stderr, "\t%s\n", path);
+#endif
     return path;
 }
 
@@ -491,6 +523,11 @@
     }
     if (root == NULL || *root == '\0') root = "/";
 
+#ifdef _WIN32
+    rpmioMapConfigTimeDir(&xmdir, 1);
+    if (DIR_IS_ABSOLUTE(xmdir) && strcmp(root, "/") == 0)
+	root = "";
+#endif
     ut = urlPath(xmdir, &mdir);
     if (url == NULL && ut > URL_IS_DASH) {
 	url = xmdir;
@@ -718,7 +755,7 @@
 {
     ARGV_t dirs = NULL;
     int rc = 0;
-    argvSplit(&dirs, pathstr, ":");
+    argvSplit(&dirs, pathstr, PATH_SEP_STRING);
     
     for (char **d = dirs; *d; d++) {
 	char *path = rpmGetPath(root ? root : "", *d, NULL);
@@ -726,9 +763,9 @@
 	    const char *msg = _("failed to create directory");
 	    /* try to be more informative if the failing part was a macro */
 	    if (**d == '%') {
-	    	rpmlog(RPMLOG_ERR, "%s %s: %s: %m\n", msg, *d, path);
+	    	rpmlog(RPMLOG_ERR, "%s %s: %s: %s\n", msg, *d, path, strerror(errno));
 	    } else {
-	    	rpmlog(RPMLOG_ERR, "%s %s: %m\n", msg, path);
+	    	rpmlog(RPMLOG_ERR, "%s %s: %s\n", msg, path, strerror(errno));
 	    }
 	}
 	free(path);
@@ -738,11 +775,119 @@
     return rc;
 }
 
+#ifdef _WIN32
+
+#include <mbstring.h>
+
+BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID);
+
+static HMODULE dll;
+
+BOOL WINAPI
+DllMain(HINSTANCE hinstDLL,
+        DWORD     fdwReason,
+        LPVOID    lpvReserved)
+{
+  switch (fdwReason)
+    {
+    case DLL_PROCESS_ATTACH:
+      dll = (HMODULE) hinstDLL;
+      break;
+    }
+
+  return TRUE;
+}
+
+/* Check if a pathname starts with a prefix taking case insensitivity,
+ * multi-byte codepage and slash equivalence into consideration.
+ */
+int
+rpmioStartsWithPrefix(const char * a, const char *b)
+{
+	const char *pa = a, *pb = b;
+
+	do {
+		const char *qa, *qb, *q;
+		int na, nb;
+
+		qa = _mbschr(pa, '/');
+		q = _mbschr(pa, '\\');
+		if (q != NULL && (qa == NULL || q < qa))
+			qa = q;
+		if (qa == NULL)
+			na = strlen(pa);
+		else
+			na = qa - pa;
+
+		qb = _mbschr(pb, '/');
+		q = _mbschr(pb, '\\');
+		if (q != NULL && (qb == NULL || q < qb))
+			qb = q;
+		if (qb == NULL)
+			nb = strlen(pb);
+		else
+			nb = qb - pb;
+
+		if (na != nb || _mbsnbicmp(pa, pb, na) != 0)
+			return 0;
+
+		pa += na;
+		if (*pa)
+		    pa++;
+		pb += na;
+		if (*pb)
+		    pb++;
+	} while (pa < a + strlen(b) && *pa && *pb);
+
+	return (!*pb);
+}
+
+void
+rpmioMapConfigTimeDir(const char **fn, int doFreeOld)
+{
+    /* Map compile-time prefix to run-time */
+    if (rpmioStartsWithPrefix(*fn, PREFIX)) {
+	wchar_t wprefix[MAXPATHLEN];
+	wchar_t *wp;
+	char prefix[MAXPATHLEN];
+	char *new_fn;
+
+	GetModuleFileNameW(dll, wprefix, sizeof(wprefix)/sizeof(wprefix[0]));
+
+	while ((wp = wcschr(wprefix, L'\\')) != NULL)
+	    *wp = L'/';
+
+	wp = wcsrchr(wprefix, L'/');
+	*wp = L'\0';
+	wp = wcsrchr(wprefix, L'/');
+
+	if (wcsicmp(wp+1, L"bin") == 0)
+	    *wp = L'\0';
+
+	wcstombs(prefix, wprefix, sizeof(prefix));
+	new_fn = malloc(strlen(prefix) + strlen(*fn + strlen(PREFIX)) + 1);
+	strcpy(new_fn, prefix);
+	if (strlen(*fn) > strlen(PREFIX))
+	    strcat(new_fn, *fn + strlen(PREFIX));
+	if (doFreeOld)
+	    free(*fn);
+   	*fn = new_fn;
+    }
+}
+#endif
+
 const char *rpmConfigDir(void)
 {
     if (rpm_config_dir == NULL) {
 	char *rpmenv = getenv("RPM_CONFIGDIR");
-	rpm_config_dir = rpmenv ? xstrdup(rpmenv) : RPMCONFIGDIR;
+	if (rpmenv != NULL)
+	    rpm_config_dir = xstrdup(rpmenv);
+	else {
+	    rpm_config_dir = RPMCONFIGDIR;
+#ifdef _WIN32
+	    rpmioMapConfigTimeDir(&rpm_config_dir, 0);
+#endif
+	}
     }
     return rpm_config_dir;
 }
--- rpmio/rpmio.c	2009-10-26 06:58:02.000000000 +0100
+++ rpmio/rpmio.c	2009-12-14 10:16:31.000000000 +0100
@@ -29,6 +29,10 @@
 
 #include "debug.h"
 
+#ifndef EWOULDBLOCK
+#define EWOULDBLOCK -1
+#endif
+
 #define FDNREFS(fd)	(fd ? ((FD_t)fd)->nrefs : -9)
 #define FDTO(fd)	(fd ? ((FD_t)fd)->rd_timeoutsecs : -99)
 #define FDCPIOPOS(fd)	(fd ? ((FD_t)fd)->fd_cpioPos : -99)
@@ -391,12 +395,18 @@
     FD_t fd;
     int fdno;
 
+#ifdef _O_NOINHERIT
+    mode |= _O_NOINHERIT;
+#endif
+
     fdno = open(path, flags, mode);
     if (fdno < 0) return NULL;
+#ifdef FD_CLOEXEC
     if (fcntl(fdno, F_SETFD, FD_CLOEXEC)) {
 	(void) close(fdno);
 	return NULL;
     }
+#endif
     fd = fdNew(RPMDBG_M("open (fdOpen)"));
     fdSetFdno(fd, fdno);
     fd->flags = flags;
@@ -412,6 +422,7 @@
 
 int fdWritable(FD_t fd, int secs)
 {
+#ifndef _WIN32
     int fdno;
     int rc;
 #if HAVE_POLL_H
@@ -456,10 +467,14 @@
 	}
 	return rc;
     } while (1);
+#else
+    return 1;
+#endif
 }
 
 int fdReadable(FD_t fd, int secs)
 {
+#ifndef _WIN32
     int fdno;
     int rc;
 #if HAVE_POLL_H
@@ -501,6 +516,9 @@
 	}
 	return rc;
     } while (1);
+#else
+    return 1;
+#endif
 }
 
 int ufdCopy(FD_t sfd, FD_t tfd)
@@ -1720,6 +1738,11 @@
 	break;
     }
 
+#ifdef _WIN32
+    flags |= _O_BINARY;
+    if (--nstdio > 0) *stdio++ = 'b';
+#endif
+
     *stdio = *other = '\0';
     if (end != NULL)
 	*end = (*m != '\0' ? m : NULL);
@@ -1964,11 +1987,13 @@
     return rc;
 }
 
+#ifndef _WIN32
 /* XXX this is naive */
 int Fcntl(FD_t fd, int op, void *lip)
 {
     return fcntl(Fileno(fd), op, lip);
 }
+#endif
 
 rpmop fdOp(FD_t fd, fdOpX opx)
 {
--- rpmio/rpmio_internal.h	2009-10-26 06:58:02.000000000 +0100
+++ rpmio/rpmio_internal.h	2009-12-14 10:16:31.000000000 +0100
@@ -304,6 +304,11 @@
 int rpmioSlurp(const char * fn,
                 uint8_t ** bp, ssize_t * blenp);
 
+#ifdef _WIN32
+int rpmioStartsWithPrefix(const char * a, const char * b);
+void rpmioMapConfigTimeDir(const char ** fn, int doFreeOld);
+#endif
+
 #ifdef __cplusplus
 }
 #endif
--- rpmio/rpmpgp.c	2009-12-14 10:15:49.000000000 +0100
+++ rpmio/rpmpgp.c	2009-12-14 10:16:31.000000000 +0100
@@ -5,7 +5,9 @@
 
 #include "system.h"
 
+#ifdef HAVE_PTHREAD_H
 #include <pthread.h>
+#endif
 
 #include <rpm/rpmstring.h>
 #include <rpm/rpmlog.h>
--- rpmio/rpmsq.c	2009-06-23 13:40:59.000000000 +0200
+++ rpmio/rpmsq.c	2009-12-14 10:16:31.000000000 +0100
@@ -5,10 +5,16 @@
 #include "system.h"
 
 #include <signal.h>
+#ifdef HAVE_SYS_SIGNAL_H
 #include <sys/signal.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
 #include <sys/wait.h>
+#endif
 #include <search.h>
 
+#ifndef _WIN32
+
 #if defined(HAVE_PTHREAD_H)
 
 #include <pthread.h>
@@ -586,3 +592,48 @@
     (void) DO_UNLOCK ();
     return status;
 }
+
+#else
+
+#define	_RPMSQ_DEBUG	0
+int _rpmsq_debug = _RPMSQ_DEBUG;
+
+typedef struct {
+    void *handle;
+    void *(*function)(void *);
+    void *arg;
+} thread_helper_t;
+
+static unsigned __stdcall
+thread_helper(void *a)
+{
+    thread_helper_t *th = a;
+
+    (*th->function)(th->arg);
+
+    return 0;
+}
+
+void * rpmsqThread(void * (*start) (void * arg), void * arg)
+{
+    thread_helper_t *th = malloc(sizeof(*th));
+
+    th->function = start;
+    th->arg = arg;
+    th->handle = (void*)_beginthreadex(NULL, 0, thread_helper, th, 0, NULL);
+
+    return th;
+}
+
+int rpmsqJoin(void * thread)
+{
+    thread_helper_t *th = thread;
+
+    WaitForSingleObject(th->handle, INFINITE);
+    CloseHandle(th->handle);
+    free(th);
+
+    return 0;
+}
+
+#endif
--- rpmio/rpmsq.h	2009-11-25 07:37:25.000000000 +0100
+++ rpmio/rpmsq.h	2009-12-14 10:16:31.000000000 +0100
@@ -9,8 +9,10 @@
 #include <rpm/rpmsw.h>
 #include <signal.h>
 #if defined(_RPMSQ_INTERNAL)
+#ifndef _WIN32
 #include <pthread.h>
 #endif
+#endif
 
 #ifdef __cplusplus
 extern "C" {
@@ -54,8 +56,10 @@
     int reaper;			/*!< Register SIGCHLD handler? */
     int pipes[2];		/*!< Parent/child interlock. */
     void * id;			/*!< Blocking thread id (pthread_t). */
+#ifndef _WIN32
     pthread_mutex_t mutex;	/*!< Signal delivery to thread condvar. */
     pthread_cond_t cond;
+#endif
 };
 #endif /* _RPMSQ_INTERNAL */
 
--- rpmio/rpmutil.h	2009-06-23 13:40:59.000000000 +0200
+++ rpmio/rpmutil.h	2009-12-14 10:16:31.000000000 +0100
@@ -83,7 +83,7 @@
 #define RPM_GNUC_WARN_UNUSED_RESULT
 #endif /* __GNUC__ */
 
-#if    __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
+#if   ( __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) && !defined(_WIN32)
 #  define RPM_GNUC_INTERNAL __attribute__((visibility("hidden")))
 #else
 #  define RPM_GNUC_INTERNAL
--- rpmio/url.c	2009-10-26 06:58:02.000000000 +0100
+++ rpmio/url.c	2009-12-14 10:16:31.000000000 +0100
@@ -5,7 +5,11 @@
 #include "system.h"
 
 #include <assert.h>
+#ifndef _WIN32
 #include <netinet/in.h>
+#else
+#include <winsock2.h>
+#endif
 
 #include <rpm/rpmmacro.h>
 #include <rpm/rpmlog.h>
@@ -265,6 +269,7 @@
     rasprintf(&cmd, "%s %s %s\n", urlhelper, target, url);
     urlhelper = _free(urlhelper);
 
+#ifndef _WIN32
     if ((pid = fork()) == 0) {
         ARGV_t argv = NULL;
         argvSplit(&argv, cmd, " ");
@@ -272,6 +277,9 @@
         exit(127); /* exit with 127 for compatibility with bash(1) */
     }
     wait = waitpid(pid, &rc, 0);
+#else
+    rc = system(cmd);
+#endif
     cmd = _free(cmd);
 
     return rc;
--- rpmqv.c	2009-10-26 06:58:02.000000000 +0100
+++ rpmqv.c	2009-12-14 10:16:31.000000000 +0100
@@ -21,6 +21,10 @@
 #include <rpm/rpmps.h>
 #include <rpm/rpmts.h>
 
+#ifdef _WIN32
+#include "rpmio/rpmio_internal.h"
+#endif
+
 #ifdef	IAM_RPMBT
 #include "build.h"
 #define GETOPT_REBUILD		1003
@@ -188,7 +192,9 @@
     int arg;
 
     const char *optArg, *poptCtx;
+#ifndef _WIN32
     pid_t pipeChild = 0;
+#endif
     poptContext optCon;
     int ec = 0;
     int status;
@@ -243,7 +249,20 @@
     /* set up the correct locale */
     (void) setlocale(LC_ALL, "" );
 
+#ifndef _WIN32
     bindtextdomain(PACKAGE, LOCALEDIR);
+#else
+    {
+	const char *p = LOCALEDIR;
+	rpmioMapConfigTimeDir(&p, 0);
+	bindtextdomain(PACKAGE, p);
+    }
+
+    printf("\n"
+           "WARNING: This port of RPM to Windows is a work in progress and highly experimental.\n"
+           "It is unlikely that you will find it useful for anything yet.\n"
+           "\n");
+#endif
     textdomain(PACKAGE);
 #endif
 
@@ -256,6 +275,11 @@
     poptCtx = "rpm";
 #endif
 
+#ifdef _WIN32xxx
+    rpmcliRootDir = PREFIX;
+    rpmioMapConfigTimeDir(&rpmcliRootDir, 0);
+#endif
+
     /* Make a first pass through the arguments, looking for --rcfile */
     /* We need to handle that before dealing with the rest of the arguments. */
     /* XXX popt argv definition should be fixed instead of casting... */
@@ -489,8 +513,8 @@
 	    if (bigMode & MODES_FOR_ROOT)
 		break;
 	case URL_IS_UNKNOWN:
-	    if (rpmcliRootDir[0] != '/')
-		argerror(_("arguments to --root (-r) must begin with a /"));
+	    if (!DIR_IS_ABSOLUTE(rpmcliRootDir))
+		argerror(_("arguments to --root (-r) must be an absolute path"));
 	    break;
 	}
     }
@@ -575,6 +599,7 @@
     }
 #endif	/* IAM_RPMBT || IAM_RPMK */
 
+#ifndef _WIN32
     if (rpmcliPipeOutput) {
 	if (pipe(p) < 0) {
 	    fprintf(stderr, _("creating a pipe for --pipe failed: %m\n"));
@@ -594,6 +619,7 @@
 	(void) dup2(p[1], STDOUT_FILENO);
 	(void) close(p[1]);
     }
+#endif
 	
     ts = rpmtsCreate();
     (void) rpmtsSetRootDir(ts, rpmcliRootDir);
@@ -835,10 +861,12 @@
 	rpmFreeMacros(rpmCLIMacroContext);
     rpmFreeRpmrc();
 
+#ifndef _WIN32
     if (pipeChild) {
 	(void) fclose(stdout);
 	(void) waitpid(pipeChild, &status, 0);
     }
+#endif
 
     /* keeps memory leak checkers quiet */
     rpmFreeFilesystems();
--- system.h
+++ system.h
@@ -396,6 +396,61 @@
 #endif
 #endif
 
+#ifdef _WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <io.h>
+#include <direct.h>
+#define ELOOP EIO
+#define EOPNOTSUPP ENOSYS
+#define S_ISUID 0
+#define S_ISGID 0
+#define S_ISVTX 0
+#define S_IFLNK -1
+#define S_IRGRP S_IRUSR
+#define S_IWGRP S_IWUSR
+#define S_IXGRP S_IXUSR
+#define S_IROTH S_IRUSR
+#define S_IWOTH S_IWUSR
+#define S_IXOTH S_IXUSR
+typedef int uid_t;
+typedef int gid_t;
+typedef int nlink_t;
+typedef int sigset_t; /* dummy */
+#define chown(path, uid, gid) (((uid) != 0 && (gid) != 0) ? (errno = ENOSYS, -1) : 0)
+#define chroot(path) (fprintf(stderr, "chroot(%s)\n", (path)), errno = ENOSYS, -1)
+#define fchdir(fd) (fprintf(stderr, "fchdir(%d)\n", (fd)), errno = ENOSYS, -1)
+#define getuid() 0
+#define getgid() 0
+#define lstat stat
+#define mkdir(path, mode) _mkdir(path)
+#define mkfifo(path, mode) (fprintf(stderr, "UNIMP: mkfifo(%s, %#o)\n", (path), (mode)), errno = ENOSYS, -1)
+#define mknod(path, mode, dev) (fprintf(stderr, "UNIMP: mknod(%s,%#o,%x)\n", (path), (mode), (dev)), errno = ENOSYS, -1)
+#define link(source, target) (fprintf(stderr, "UNIMP: link(%s,%s)\n", (source), (target)), errno = ENOSYS, -1)
+#define readlink(path, buf, size) (errno = EINVAL, -1)
+#define sleep(secs) Sleep((secs)*1000)
+#define symlink(source, target) (fprintf(stderr, "UNIMP: symlink(%s,%s)\n", (source), (target)), errno = ENOSYS, -1)
+char *realpath(const char *path, char resolved_path []);
+#endif
+
+#ifdef _WIN32
+#define IS_DIR_SEP(c) ((c) == '/' || (c) == '\\')
+#define DIR_IS_ABSOLUTE(d) (IS_DIR_SEP((d)[0]) || (isalpha((d)[0]) && (d)[1] == ':' && IS_DIR_SEP((d)[2])))
+#define PATH_SEP ';'
+#define PATH_SEP_STRING ";"
+#else
+#define IS_DIR_SEP(c) ((c) == '/')
+#define DIR_IS_ABSOLUTE(d) IS_DIR_SEP((d)[0])
+#define PATH_SEP ':'
+#define PATH_SEP_STRING ":"
+#endif
+
+#ifndef _WIN32
+#define _O_BINARY 0
+#endif
+
 /* Solaris <= 2.6 limits getpass return to only 8 chars */
 #if HAVE_GETPASSPHRASE
 #define	getpass	getpassphrase
openSUSE Build Service is sponsored by