portability fixes


git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@715 59561ff5-6e30-0410-9f3c-9617f08c8826
diff --git a/libasn1compiler/asn1c_compat.c b/libasn1compiler/asn1c_compat.c
index 1a402bf..ebc6d3f 100644
--- a/libasn1compiler/asn1c_compat.c
+++ b/libasn1compiler/asn1c_compat.c
@@ -1,24 +1,26 @@
 #include "asn1c_internal.h"
-#include <asn1c_compat.h>
-
-#ifdef	HAVE_SYS_PARAM_H
-#include <sys/param.h>	/* For MAXPATHLEN */
-#endif
+#include "asn1c_compat.h"
 
 #ifndef	MAXPATHLEN
 #define	MAXPATHLEN	1024
 #endif
 
 #ifndef	DEFFILEMODE	/* Normally in <sys/stat.h> */
+#ifdef	WIN32
+#define	DEFFILEMODE	0
+#else
 #define	DEFFILEMODE	(S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
 #endif
+#endif
 
 FILE *
 asn1c_open_file(const char *name, const char *ext) {
 	int created = 1;
+#ifndef	WIN32
 	struct stat sb;
+#endif
 	char *fname;
-	int len;
+	size_t len;
 	FILE *fp;
 	int fd;
 
@@ -42,6 +44,7 @@
 		return NULL;
 	}
 
+#ifndef	WIN32
 	/*
 	 * Check sanity.
 	 */
@@ -53,6 +56,9 @@
 	}
 
 	(void)ftruncate(fd, 0);
+#else
+	_chsize(fd, 0);
+#endif	/* WIN32 */
 
 	/*
 	 * Convert file descriptor into file pointer.
diff --git a/libasn1compiler/asn1c_compat.h b/libasn1compiler/asn1c_compat.h
index e80e2e7..44ac438 100644
--- a/libasn1compiler/asn1c_compat.h
+++ b/libasn1compiler/asn1c_compat.h
@@ -1,10 +1,6 @@
 #ifndef	ASN1C_COMPAT_H
 #define	ASN1C_COMPAT_H
 
-#ifdef	HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 /*
  * Open the arbitrary file by its base name and extension.
  */
diff --git a/libasn1compiler/asn1c_internal.h b/libasn1compiler/asn1c_internal.h
index e6b1852..e32187f 100644
--- a/libasn1compiler/asn1c_internal.h
+++ b/libasn1compiler/asn1c_internal.h
@@ -7,16 +7,37 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <sys/stat.h>		/* for fstat(2) */
-#include <unistd.h>		/* for unlink(2) */
-#include <fcntl.h>		/* for open(2) */
-#include <glob.h>		/* for glob(3) */
 #include <string.h>		/* for strlen(3) and memset(3) */
 #include <ctype.h>		/* for isalnum(3) */
+#include <sys/types.h>		/* for fstat(2) */
 #include <stdarg.h>
 #include <errno.h>
 #include <assert.h>
 
+#ifdef	HAVE_SYS_STAT_H
+#include <sys/stat.h>		/* for fstat(2) */
+#endif
+
+#ifdef	HAVE_UNISTD_H
+#include <unistd.h>		/* for unlink(2) */
+#endif
+
+#ifdef	WIN32
+#include <io.h>
+#define	open	_open
+#define	close	_close
+#define	alloca		_alloca
+#define	snprintf	_snprintf
+#define	vsnprintf	_vsnprintf
+#else
+#include <fcntl.h>		/* for open(2) */
+#include <glob.h>		/* for glob(3) */
+#endif
+
+#ifdef	HAVE_SYS_PARAM_H
+#include <sys/param.h>	/* For MAXPATHLEN */
+#endif
+
 #include "asn1compiler.h"
 
 typedef struct arg_s {
diff --git a/libasn1compiler/asn1c_misc.c b/libasn1compiler/asn1c_misc.c
index efdb6c5..51b9d94 100644
--- a/libasn1compiler/asn1c_misc.c
+++ b/libasn1compiler/asn1c_misc.c
@@ -32,7 +32,7 @@
 	va_list ap;
 	char *str;
 	char *nextstr;
-	int size;
+	size_t size;
 	char *p;
 
 	if(arg1 == NULL)
diff --git a/libasn1compiler/asn1c_save.c b/libasn1compiler/asn1c_save.c
index 381404e..1abf242 100644
--- a/libasn1compiler/asn1c_save.c
+++ b/libasn1compiler/asn1c_save.c
@@ -76,11 +76,12 @@
 	if(dlist) {
 		char buf[8129];
 		char *dir_end;
-		int i = strlen(datadir);
+		size_t dlen = strlen(datadir);
+		int i;
 
-		assert(i < (int)(sizeof(buf) / 2 - 2));
-		memcpy(buf, datadir, i);
-		dir_end = buf + i;
+		assert(dlen < (sizeof(buf) / 2 - 2));
+		memcpy(buf, datadir, dlen);
+		dir_end = buf + dlen;
 		*dir_end++ = '/';
 
 		for(i = 0; i < dlist->el_count; i++) {
@@ -254,6 +255,35 @@
 	return 0;
 }
 
+/*
+ * Copy file for real.
+ */
+static int
+real_copy(const char *src, const char *dst) {
+	unsigned char buf[8192];
+	FILE *fpsrc, *fpdst;
+	size_t len;
+	int retval = 0;
+
+	fpsrc = fopen(src, "rb");
+	if(!fpsrc) { errno = EIO; return -1; }
+	fpdst = fopen(src, "wb");
+	if(!fpdst) { fclose(fpsrc); errno = EIO; return -1; }
+
+	while(!feof(fpsrc)) {
+		len = fread(buf, 1, sizeof(buf), fpsrc);
+		if(fwrite(buf, 1, len, fpsrc) != len) {
+			errno = EIO;
+			retval = -1;
+			break;
+		}
+	}
+
+	fclose(fpsrc);
+	fclose(fpdst);
+	return retval;
+}
+
 static int
 asn1c_copy_over(arg_t *arg, char *path) {
 	char *fname;
@@ -261,7 +291,13 @@
 	(void)arg;	/* Unused argument */
 
 	fname = a1c_basename(path);
-	if(!fname || symlink(path, fname)) {
+	if(!fname
+#ifdef	WIN32
+		|| real_copy(path, fname)
+#else
+		|| (1 ? symlink(path, fname) : real_copy(path, fname))
+#endif
+	) {
 		if(errno == EEXIST) {
 			struct stat sb1, sb2;
 			if(stat(path, &sb1) == 0