diff -ur C:\FGCVS\tar\lib\canonicalize-lgpl.c C:\Projects\tar\lib\canonicalize-lgpl.c
--- C:\FGCVS\tar\lib\canonicalize-lgpl.c	Fri Feb 08 20:26:12 2008
+++ C:\Projects\tar\lib\canonicalize-lgpl.c	Mon Sep 08 13:57:16 2008
@@ -165,7 +165,7 @@
 #ifdef _LIBC
       struct stat64 st;
 #else
-      struct stat st;
+      struct_stat st;
 #endif
 
       /* Skip sequence of multiple path-separators.  */
diff -ur C:\FGCVS\tar\lib\chown.c C:\Projects\tar\lib\chown.c
--- C:\FGCVS\tar\lib\chown.c	Sun Nov 18 11:46:56 2007
+++ C:\Projects\tar\lib\chown.c	Fri Sep 12 16:15:23 2008
@@ -49,10 +49,10 @@
 #if CHOWN_FAILS_TO_HONOR_ID_OF_NEGATIVE_ONE
   if (gid == (gid_t) -1 || uid == (uid_t) -1)
     {
-      struct stat file_stats;
+      struct_stat file_stats;
 
       /* Stat file to get id(s) that should remain unchanged.  */
-      if (stat (file, &file_stats))
+      if (FNSTAT (file, &file_stats))
 	return -1;
 
       if (gid == (gid_t) -1)
@@ -81,10 +81,10 @@
 
 	/* POSIX says fchown can fail with errno == EINVAL on sockets,
 	   so fall back on chown in that case.  */
-	struct stat sb;
+	struct_stat sb;
 	bool fchown_socket_failure =
 	  (result != 0 && saved_errno == EINVAL
-	   && fstat (fd, &sb) == 0 && S_ISFIFO (sb.st_mode));
+	   && FDSTAT (fd, &sb) == 0 && S_ISFIFO (sb.st_mode));
 
 	close (fd);
 
diff -ur C:\FGCVS\tar\lib\closeout.c C:\Projects\tar\lib\closeout.c
--- C:\FGCVS\tar\lib\closeout.c	Sun Nov 18 11:46:56 2007
+++ C:\Projects\tar\lib\closeout.c	Mon Sep 08 15:19:27 2008
@@ -68,6 +68,12 @@
 void
 close_stdout (void)
 {
+#ifdef _MSC_VER   /* add fflush(NULL) ... to flush ALL open file streams */
+  fflush(NULL);
+#ifndef NDEBUG
+     return;
+#endif /* !NDEBUG */
+#endif /* _MSC_VER */
   if (close_stream (stdout) != 0)
     {
       char const *write_error = _("write error");
diff -ur C:\FGCVS\tar\lib\fchdir.c C:\Projects\tar\lib\fchdir.c
--- C:\FGCVS\tar\lib\fchdir.c	Sun Nov 18 11:46:56 2007
+++ C:\Projects\tar\lib\fchdir.c	Fri Sep 12 16:15:23 2008
@@ -99,7 +99,7 @@
 {
   mode_t mode;
   int fd;
-  struct stat statbuf;
+  struct_stat statbuf;
 
   mode = 0;
   if (flags & O_CREAT)
@@ -125,7 +125,7 @@
     {
       ensure_dirs_slot (fd);
       if (fd < dirs_allocated
-	  && fstat (fd, &statbuf) >= 0 && S_ISDIR (statbuf.st_mode))
+	  && FDSTAT (fd, &statbuf) >= 0 && S_ISDIR (statbuf.st_mode))
 	{
 	  dirs[fd].name = canonicalize_file_name (filename);
 	  if (dirs[fd].name == NULL)
diff -ur C:\FGCVS\tar\lib\ftruncate.c C:\Projects\tar\lib\ftruncate.c
--- C:\FGCVS\tar\lib\ftruncate.c	Sun Nov 18 11:46:56 2007
+++ C:\Projects\tar\lib\ftruncate.c	Fri Sep 12 16:22:23 2008
@@ -78,9 +78,29 @@
 
 #   include <errno.h>
 
-int
-ftruncate (int fd, off_t length)
+off64_t
+ftruncate (int fd, off64_t length)
 {
+#ifdef _MSC_VER   /* a WIN32 work-around for ftruncate - maybe */
+  /* maybe use SetEndOfFile( HANDLE )??? */
+  off64_t position = FDSEEK(fd, length, SEEK_SET);
+#if !defined(NDEBUG)
+  printf( "ftruncate: to %I64d (%I64d)...\n", length, position );
+#endif // EXTRA DEBUG OF TRUNCATE
+  if( ( position != -1 ) && ( position == length ) )
+  {
+     char * perr;
+     DWORD  dw;
+     if( SetEndOfFile( (HANDLE)fd ) )
+        return 0;
+     perr = GetWinError( GetLastError() );
+     if( VFH(win_GetOutHandle()) )
+        WriteFile(win_GetOutHandle(),perr,strlen(perr),&dw,NULL);
+#ifndef NDEBUG
+     fprintf( stderr, "SetEndOfFile FAILED! Indication:\n%s\n", perr );
+#endif /* !NDEBUG */
+  }
+#endif /* _MSC_VER */
   errno = EIO;
   return -1;
 }
diff -ur C:\FGCVS\tar\lib\getcwd.c C:\Projects\tar\lib\getcwd.c
--- C:\FGCVS\tar\lib\getcwd.c	Fri Feb 08 20:26:12 2008
+++ C:\Projects\tar\lib\getcwd.c	Fri Sep 12 16:15:23 2008
@@ -144,7 +144,7 @@
   ino_t rootino, thisino;
   char *dir;
   register char *dirp;
-  struct stat st;
+  struct_stat st;
   size_t allocated = size;
   size_t used;
 
@@ -189,12 +189,12 @@
   dirp = dir + allocated;
   *--dirp = '\0';
 
-  if (__lstat (".", &st) < 0)
+  if (FNSTAT (".", &st) < 0)
     goto lose;
   thisdev = st.st_dev;
   thisino = st.st_ino;
 
-  if (__lstat ("/", &st) < 0)
+  if (FNSTAT ("/", &st) < 0)
     goto lose;
   rootdev = st.st_dev;
   rootino = st.st_ino;
@@ -221,7 +221,7 @@
       dotlist[dotlen++] = '.';
       dotlist[dotlen++] = '.';
       dotlist[dotlen] = '\0';
-      parent_status = __lstat (dotlist, &st);
+      parent_status = FNSTAT (dotlist, &st);
 #endif
       if (parent_status != 0)
 	goto lose;
diff -ur C:\FGCVS\tar\lib\getdate.c C:\Projects\tar\lib\getdate.c
--- C:\FGCVS\tar\lib\getdate.c	Sat Feb 16 13:14:36 2008
+++ C:\Projects\tar\lib\getdate.c	Sat Sep 13 18:27:26 2008
@@ -228,8 +228,9 @@
    wraps around, but there's no portable way to check for that at
    compile-time.  */
 verify (TYPE_IS_INTEGER (time_t));
+#ifndef _MSC_VER  /* can not get 'verify()' to work in some cases */
 verify (LONG_MIN <= TYPE_MINIMUM (time_t) && TYPE_MAXIMUM (time_t) <= LONG_MAX);
-
+#endif /* !_MSC_VER */
 /* An integer value, and the number of digits in its textual
    representation.  */
 typedef struct
@@ -2084,12 +2085,20 @@
 
   case 59:
 #line 555 "getdate.y"
-    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = (yyvsp[(1) - (2)].timespec).tv_sec; (yyval.rel).ns = (yyvsp[(1) - (2)].timespec).tv_nsec; }
+    { 
+       (yyval.rel) = RELATIVE_TIME_0;
+       (yyval.rel).seconds = (long)((yyvsp[(1) - (2)].timespec).tv_sec);
+       (yyval.rel).ns = (yyvsp[(1) - (2)].timespec).tv_nsec;
+    }
     break;
 
   case 60:
 #line 557 "getdate.y"
-    { (yyval.rel) = RELATIVE_TIME_0; (yyval.rel).seconds = (yyvsp[(1) - (2)].timespec).tv_sec; (yyval.rel).ns = (yyvsp[(1) - (2)].timespec).tv_nsec; }
+    {
+       (yyval.rel) = RELATIVE_TIME_0;
+       (yyval.rel).seconds = (long)((yyvsp[(1) - (2)].timespec).tv_sec);
+       (yyval.rel).ns = (yyvsp[(1) - (2)].timespec).tv_nsec;
+    }
     break;
 
   case 61:
@@ -2800,14 +2809,14 @@
 		  s = - value;
 		  if (0 < s)
 		    return '?';
-		  value1 = -s;
+		  value1 = (unsigned long)-s;
 		}
 	      else
 		{
 		  s = value;
 		  if (s < 0)
 		    return '?';
-		  value1 = s;
+		  value1 = (unsigned long)s;
 		}
 	      if (value != value1)
 		return '?';
@@ -3062,6 +3071,9 @@
   pc.dsts_seen = 0;
   pc.zones_seen = 0;
 
+  pc.local_time_zone_table[0].name = NULL; /* _MSC_VER - null these to */
+  pc.local_time_zone_table[1].name = NULL; /* pacify the compiler ;=)) */
+
 #if HAVE_STRUCT_TM_TM_ZONE
   pc.local_time_zone_table[0].name = tmp->tm_zone;
   pc.local_time_zone_table[0].type = tLOCAL_ZONE;
@@ -3106,6 +3118,19 @@
   }
 #else
   pc.local_time_zone_table[0].name = NULL;
+#ifdef _MSC_VER   /* use _get_tzname() function to retrieve name */
+  {
+     static char tzname0[TZNAME_MAX];
+     static char tzname1[TZNAME_MAX];
+     size_t retval;
+     retval = 0;
+     if(( _get_tzname( &retval, tzname0, TZNAME_MAX, 0 ) == 0 ) && retval )
+        pc.local_time_zone_table[0].name = tzname0;
+     retval = 0;
+     if(( _get_tzname( &retval, tzname0, TZNAME_MAX, 1 ) == 0 ) && retval )
+        pc.local_time_zone_table[1].name = tzname0;
+  }
+#endif /* _MSC_VER */
 #endif
 #endif
 
@@ -3140,7 +3165,7 @@
 	  if (tm.tm_hour < 0)
 	    goto fail;
 	  tm.tm_min = pc.minutes;
-	  tm.tm_sec = pc.seconds.tv_sec;
+	  tm.tm_sec = (int)pc.seconds.tv_sec;
 	}
       else
 	{
diff -ur C:\FGCVS\tar\lib\gettime.c C:\Projects\tar\lib\gettime.c
--- C:\FGCVS\tar\lib\gettime.c	Sun Nov 18 11:46:56 2007
+++ C:\Projects\tar\lib\gettime.c	Mon Sep 08 16:18:12 2008
@@ -21,7 +21,9 @@
 
 #include "timespec.h"
 
+#ifndef _MSC_VER /* no such file in WIN32 - timespec through win_time.h from config.h */
 #include <sys/time.h>
+#endif /* _MSC_VER y/n */
 
 /* Get the system time into *TS.  */
 
diff -ur C:\FGCVS\tar\lib\gettimeofday.c C:\Projects\tar\lib\gettimeofday.c
--- C:\FGCVS\tar\lib\gettimeofday.c	Tue Oct 30 21:48:28 2007
+++ C:\Projects\tar\lib\gettimeofday.c	Mon Sep 08 16:18:12 2008
@@ -24,7 +24,9 @@
 #include <config.h>
 
 /* Specification.  */
+#ifndef _MSC_VER /* no such file in WIN32 - timespec through win_time.h from config.h */
 #include <sys/time.h>
+#endif /* _MSC_VER y/n */
 
 #include <time.h>
 
diff -ur C:\FGCVS\tar\lib\hash.c C:\Projects\tar\lib\hash.c
--- C:\FGCVS\tar\lib\hash.c	Sun Nov 18 11:46:56 2007
+++ C:\Projects\tar\lib\hash.c	Mon Sep 08 16:26:25 2008
@@ -565,7 +565,7 @@
       float new_candidate = candidate / tuning->growth_threshold;
       if (SIZE_MAX <= new_candidate)
 	goto fail;
-      candidate = new_candidate;
+      candidate = (size_t)new_candidate;
     }
 
   if (xalloc_oversized (candidate, sizeof *table->bucket))
@@ -966,7 +966,7 @@
 	    return NULL;
 
 	  /* If the rehash fails, arrange to return NULL.  */
-	  if (!hash_rehash (table, candidate))
+	  if (!hash_rehash (table, (size_t)candidate))
 	    entry = NULL;
 	}
     }
@@ -1008,9 +1008,9 @@
 	      const Hash_tuning *tuning = table->tuning;
 	      size_t candidate =
 		(tuning->is_n_buckets
-		 ? table->n_buckets * tuning->shrink_factor
-		 : (table->n_buckets * tuning->shrink_factor
-		    * tuning->growth_threshold));
+		 ? table->n_buckets * (size_t)tuning->shrink_factor
+		 : (table->n_buckets * (size_t)tuning->shrink_factor
+		    * (size_t)tuning->growth_threshold));
 
 	      hash_rehash (table, candidate);
 	    }
diff -ur C:\FGCVS\tar\lib\human.c C:\Projects\tar\lib\human.c
--- C:\FGCVS\tar\lib\human.c	Sun Nov 18 11:46:56 2007
+++ C:\Projects\tar\lib\human.c	Mon Sep 08 17:02:13 2008
@@ -60,8 +60,8 @@
      value alone if it is too large to easily round.  */
   if (inexact_style != human_round_to_nearest && value < UINTMAX_MAX)
     {
-      uintmax_t u = value;
-      value = u + (inexact_style == human_ceiling && u != value);
+      uintmax_t u = (uint64_t)value;
+      value = (long double)(u + (inexact_style == human_ceiling && u != (uint64_t)value));
     }
 
   return value;
@@ -212,7 +212,7 @@
       uintmax_t r10 = (n % divisor) * 10;
       uintmax_t r2 = (r10 % divisor) * 2;
       amt = n / divisor;
-      tenths = r10 / divisor;
+      tenths = (int)(r10 / divisor);
       rounding = r2 < divisor ? 0 < r2 : 2 + (divisor < r2);
       goto use_integer_arithmetic;
     }
@@ -222,8 +222,8 @@
        or from_block_size is zero.  Fall back on floating point.
        FIXME: This can yield answers that are slightly off.  */
 
-    long double dto_block_size = to_block_size;
-    long double damt = n * (from_block_size / dto_block_size);
+    long double dto_block_size = (long double)to_block_size;
+    long double damt = (long double)(n * (from_block_size / dto_block_size));
     size_t buflen;
     size_t nonintegerlen;
 
@@ -283,7 +283,7 @@
 	  {
 	    do
 	      {
-		unsigned int r10 = (amt % base) * 10 + tenths;
+		unsigned int r10 = (unsigned int)((amt % base) * 10 + tenths);
 		unsigned int r2 = (r10 % base) * 2 + (rounding >> 1);
 		amt /= base;
 		tenths = r10 / base;
@@ -346,7 +346,7 @@
 
     do
       {
-	int digit = amt % 10;
+	int digit = (int)(amt % 10);
 	*--p = digit + '0';
       }
     while ((amt /= 10) != 0);
diff -ur C:\FGCVS\tar\lib\inttostr.c C:\Projects\tar\lib\inttostr.c
--- C:\FGCVS\tar\lib\inttostr.c	Sun Nov 18 11:46:56 2007
+++ C:\Projects\tar\lib\inttostr.c	Fri Sep 12 18:53:48 2008
@@ -34,7 +34,7 @@
   if (i < 0)
     {
       do
-	*--p = '0' - i % 10;
+	*--p = (char)('0' - (i % 10));
       while ((i /= 10) != 0);
 
       *--p = '-';
@@ -42,7 +42,7 @@
   else
     {
       do
-	*--p = '0' + i % 10;
+	*--p = (char)('0' + (i % 10));
       while ((i /= 10) != 0);
     }
 
diff -ur C:\FGCVS\tar\lib\inttostr.h C:\Projects\tar\lib\inttostr.h
--- C:\FGCVS\tar\lib\inttostr.h	Sun Nov 18 11:46:56 2007
+++ C:\Projects\tar\lib\inttostr.h	Fri Sep 12 18:29:58 2008
@@ -23,7 +23,11 @@
 
 #include "intprops.h"
 
-char *offtostr (off_t, char *);
+char *offtostr (off64_t, char *);
 char *imaxtostr (intmax_t, char *);
 char *umaxtostr (uintmax_t, char *);
+#ifdef _MSC_VER /* use 64-bits */
+char *uinttostr (uintmax_t, char *);
+#else /* !_MSC_VER */
 char *uinttostr (unsigned int, char *);
+#endif /* _MSC_VER y/n */
\ No newline at end of file
diff -ur C:\FGCVS\tar\lib\lchown.c C:\Projects\tar\lib\lchown.c
--- C:\FGCVS\tar\lib\lchown.c	Sun Nov 18 11:46:56 2007
+++ C:\Projects\tar\lib\lchown.c	Mon Sep 08 12:38:35 2008
@@ -48,7 +48,7 @@
 int
 lchown (const char *file, uid_t uid, gid_t gid)
 {
-#if ! CHOWN_MODIFIES_SYMLINK
+#if ! CHOWN_MODIFIES_SYMLINK && ! _MSC_VER /* remove a 32-bit stat, not needed */
   struct stat stats;
 
   if (lstat (file, &stats) == 0 && S_ISLNK (stats.st_mode))
diff -ur C:\FGCVS\tar\lib\localcharset.c C:\Projects\tar\lib\localcharset.c
--- C:\FGCVS\tar\lib\localcharset.c	Tue Oct 30 21:48:28 2007
+++ C:\Projects\tar\lib\localcharset.c	Thu Aug 14 17:43:44 2008
@@ -68,7 +68,9 @@
 
 /* Get LIBDIR.  */
 #ifndef LIBDIR
+#ifndef _MSC_VER  /* no configmake.h */
 # include "configmake.h"
+#endif /* !_MSC_VER */
 #endif
 
 #if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__
diff -ur C:\FGCVS\tar\lib\lseek.c C:\Projects\tar\lib\lseek.c
--- C:\FGCVS\tar\lib\lseek.c	Fri Feb 08 11:46:36 2008
+++ C:\Projects\tar\lib\lseek.c	Fri Sep 12 16:15:23 2008
@@ -33,8 +33,8 @@
 
 #undef lseek
 
-off_t
-rpl_lseek (int fd, off_t offset, int whence)
+off64_t
+rpl_lseek (int fd, off64_t offset, int whence)
 {
 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
   /* mingw lseek mistakenly succeeds on pipes, sockets, and terminals.  */
@@ -51,8 +51,8 @@
     }
 #else
   /* BeOS lseek mistakenly succeeds on pipes...  */
-  struct stat statbuf;
-  if (fstat (fd, &statbuf) < 0)
+  struct_stat statbuf;
+  if (FDSTAT (fd, &statbuf) < 0)
     return -1;
   if (!S_ISREG (statbuf.st_mode))
     {
@@ -60,5 +60,5 @@
       return -1;
     }
 #endif
-  return lseek (fd, offset, whence);
+  return FDSEEK (fd, offset, whence);
 }
diff -ur C:\FGCVS\tar\lib\lstat.c C:\Projects\tar\lib\lstat.c
--- C:\FGCVS\tar\lib\lstat.c	Sun Nov 18 11:46:56 2007
+++ C:\Projects\tar\lib\lstat.c	Mon Sep 08 12:38:35 2008
@@ -42,6 +42,7 @@
    then use stat() to get more info on the referent of FILE.
    If the referent is a non-directory, then set errno to ENOTDIR
    and return -1.  Otherwise, return stat's result.  */
+#ifndef _MSC_VER /* remove rpl_lstat() */
 
 int
 rpl_lstat (const char *file, struct stat *sbuf)
@@ -73,3 +74,5 @@
   errno = ENOTDIR;
   return -1;
 }
+
+#endif /* !_MSC_VER */
diff -ur C:\FGCVS\tar\lib\lstat.h C:\Projects\tar\lib\lstat.h
--- C:\FGCVS\tar\lib\lstat.h	Sun Nov 18 11:46:56 2007
+++ C:\Projects\tar\lib\lstat.h	Mon Sep 08 12:38:35 2008
@@ -16,7 +16,7 @@
 
 #include <sys/stat.h>
 
-#if !LSTAT_FOLLOWS_SLASHED_SYMLINK
+#if !LSTAT_FOLLOWS_SLASHED_SYMLINK && ! _MSC_VER /* remove rpl_stat() */
 extern int rpl_lstat (const char *name, struct stat *buf);
 # undef lstat
 # define lstat rpl_lstat
diff -ur C:\FGCVS\tar\lib\mkdirat.c C:\Projects\tar\lib\mkdirat.c
--- C:\FGCVS\tar\lib\mkdirat.c	Sun Nov 18 11:46:56 2007
+++ C:\Projects\tar\lib\mkdirat.c	Fri Aug 22 19:01:19 2008
@@ -38,5 +38,11 @@
 #define AT_FUNC_F2 mkdir
 #define AT_FUNC_USE_F1_COND 1
 #define AT_FUNC_POST_FILE_PARAM_DECLS , mode_t mode
+#ifdef _MSC_VER
+/* in WIN32, mkdir only take the name, no mode */
+#define AT_FUNC_POST_FILE_ARGS   /* empty for WIN32 */
+#else
 #define AT_FUNC_POST_FILE_ARGS        , mode
+#endif
+
 #include "at-func.c"
diff -ur C:\FGCVS\tar\lib\mktime.c C:\Projects\tar\lib\mktime.c
--- C:\FGCVS\tar\lib\mktime.c	Tue Oct 30 21:48:30 2007
+++ C:\Projects\tar\lib\mktime.c	Thu Aug 14 17:43:44 2008
@@ -167,8 +167,10 @@
 	    int year0, int yday0, int hour0, int min0, int sec0)
 {
   verify (C99_integer_division, -1 / 2 == 0);
+#ifndef _MSC_VER /* can not get verify() to work in all cases? */
   verify (long_int_year_and_yday_are_wide_enough,
 	  INT_MAX <= LONG_MAX / 2 || TIME_T_MAX <= UINT_MAX);
+#endif /* !_MSC_VER */
 
   /* Compute intervening leap days correctly even if year is negative.
      Take care to avoid integer overflow here.  */
diff -ur C:\FGCVS\tar\lib\modechange.c C:\Projects\tar\lib\modechange.c
--- C:\FGCVS\tar\lib\modechange.c	Sun Nov 18 11:46:56 2007
+++ C:\Projects\tar\lib\modechange.c	Fri Sep 12 16:15:23 2008
@@ -286,9 +286,9 @@
 struct mode_change *
 mode_create_from_ref (const char *ref_file)
 {
-  struct stat ref_stats;
+  struct_stat ref_stats;
 
-  if (stat (ref_file, &ref_stats) != 0)
+  if (FNSTAT (ref_file, &ref_stats) != 0)
     return NULL;
   return make_node_op_equals (ref_stats.st_mode, CHMOD_MODE_BITS);
 }
diff -ur C:\FGCVS\tar\lib\offtostr.c C:\Projects\tar\lib\offtostr.c
--- C:\FGCVS\tar\lib\offtostr.c	Sun Nov 18 11:46:56 2007
+++ C:\Projects\tar\lib\offtostr.c	Sat Sep 13 11:48:46 2008
@@ -1,3 +1,7 @@
 #define inttostr offtostr
+#ifdef _MSC_VER /* use 64-bit offets */
+#define inttype off64_t
+#else /* !_MSC_VER */
 #define inttype off_t
+#endif /* _MSC_VER y/n */
 #include "inttostr.c"
diff -ur C:\FGCVS\tar\lib\openat-proc.c C:\Projects\tar\lib\openat-proc.c
--- C:\FGCVS\tar\lib\openat-proc.c	Sun Nov 18 11:46:56 2007
+++ C:\Projects\tar\lib\openat-proc.c	Sat Aug 16 11:05:35 2008
@@ -54,6 +54,18 @@
 {
   static int proc_status = 0;
 
+#ifdef _MSC_VER /* replace open ("/proc/self/fd", O_RDONLY); with success */
+  if (! proc_status)
+     proc_status = 1;
+  if ( proc_status > 0 )
+  {
+      size_t bufsize = PROC_SELF_FD_NAME_SIZE_BOUND (strlen (file));
+      char *result = (bufsize < OPENAT_BUFFER_SIZE ? buf : xmalloc (bufsize));
+      strcpy (result, file);
+      return result;
+  }
+  return NULL;
+#else /* !_MSC_VER */
   if (! proc_status)
     {
       /* Set PROC_STATUS to a positive value if /proc/self/fd is
@@ -91,4 +103,5 @@
       sprintf (result, PROC_SELF_FD_FORMAT, fd, file);
       return result;
     }
+#endif /* _MSC_VER y/n */
 }
diff -ur C:\FGCVS\tar\lib\openat.c C:\Projects\tar\lib\openat.c
--- C:\FGCVS\tar\lib\openat.c	Sun Nov 18 11:46:56 2007
+++ C:\Projects\tar\lib\openat.c	Sat Sep 13 12:48:00 2008
@@ -56,8 +56,11 @@
 
       va_end (arg);
     }
-
+#ifdef _MSC_VER /* do open, since openat_permissive resolves to openat */
+  return open (file, flags, mode);
+#else /* !_MSC_VER */
   return openat_permissive (fd, file, flags, mode, NULL);
+#endif /* _MSC_VER y/n */
 }
 
 /* Like openat (FD, FILE, FLAGS, MODE), but if CWD_ERRNO is
@@ -71,6 +74,7 @@
    It is the caller's responsibility not to call this function
    in that case.  */
 
+#ifdef __OPENAT_PREFIX
 int
 openat_permissive (int fd, char const *file, int flags, mode_t mode,
 		   int *cwd_errno)
@@ -154,6 +158,7 @@
 
   return needs_fchdir;
 }
+#endif /* ifdef __OPENAT_PREFIX */
 
 #if !HAVE_FDOPENDIR
 
@@ -230,13 +235,21 @@
    If either the save_cwd or the restore_cwd fails (relatively unlikely),
    then give a diagnostic and exit nonzero.
    Otherwise, this function works just like Solaris' fstatat.  */
-
+#ifdef _MSC_VER /* some more stat to __stat64 changes */
+#define AT_FUNC_NAME fstatat
+#define AT_FUNC_F1 lstat
+#define AT_FUNC_F2 __stat64
+#define AT_FUNC_USE_F1_COND flag == AT_SYMLINK_NOFOLLOW
+#define AT_FUNC_POST_FILE_PARAM_DECLS , struct _stat64 *st, int flag
+#define AT_FUNC_POST_FILE_ARGS        , st
+#else /* !_MSC_VER */
 #define AT_FUNC_NAME fstatat
 #define AT_FUNC_F1 lstat
 #define AT_FUNC_F2 stat
 #define AT_FUNC_USE_F1_COND flag == AT_SYMLINK_NOFOLLOW
 #define AT_FUNC_POST_FILE_PARAM_DECLS , struct stat *st, int flag
 #define AT_FUNC_POST_FILE_ARGS        , st
+#endif /* _MSC_VER y/n */
 #include "at-func.c"
 #undef AT_FUNC_NAME
 #undef AT_FUNC_F1
@@ -257,7 +270,11 @@
 #define AT_FUNC_F1 rmdir
 #define AT_FUNC_F2 unlink
 #define AT_FUNC_USE_F1_COND flag == AT_REMOVEDIR
+#ifdef _MSC_VER /* compiler complains about parameter 3, but this still warns??? */
+#define AT_FUNC_POST_FILE_PARAM_DECLS , int flag
+#else /* !_MSC_VER */
 #define AT_FUNC_POST_FILE_PARAM_DECLS , int flag
+#endif /* _MSC_VER y/n */
 #define AT_FUNC_POST_FILE_ARGS        /* empty */
 #include "at-func.c"
 #undef AT_FUNC_NAME
diff -ur C:\FGCVS\tar\lib\paxerror.c C:\Projects\tar\lib\paxerror.c
--- C:\FGCVS\tar\lib\paxerror.c	Wed Jun 27 15:49:46 2007
+++ C:\Projects\tar\lib\paxerror.c	Fri Sep 12 18:07:32 2008
@@ -171,26 +171,26 @@
 }
 
 void
-read_error_details (char const *name, off_t offset, size_t size)
+read_error_details (char const *name, off64_t offset, size64_t size)
 {
   char buf[UINTMAX_STRSIZE_BOUND];
   int e = errno;
   ERROR ((0, e,
-	  ngettext ("%s: Read error at byte %s, while reading %lu byte",
-		    "%s: Read error at byte %s, while reading %lu bytes",
+	  ngettext ("%s: Read error at byte %s, while reading %" PRIu64 " byte",
+		    "%s: Read error at byte %s, while reading %" PRIu64 " bytes",
 		    size),
 	  quotearg_colon (name), STRINGIFY_BIGINT (offset, buf),
 	  (unsigned long) size));
 }
 
 void
-read_warn_details (char const *name, off_t offset, size_t size)
+read_warn_details (char const *name, off64_t offset, size64_t size)
 {
   char buf[UINTMAX_STRSIZE_BOUND];
   int e = errno;
   WARN ((0, e,
-	 ngettext ("%s: Warning: Read error at byte %s, while reading %lu byte",
-		   "%s: Warning: Read error at byte %s, while reading %lu bytes",
+	 ngettext ("%s: Warning: Read error at byte %s, while reading %" PRIu64 " byte",
+		   "%s: Warning: Read error at byte %s, while reading %" PRIu64 " bytes",
 		   size),
 	 quotearg_colon (name), STRINGIFY_BIGINT (offset, buf),
 	 (unsigned long) size));
@@ -203,13 +203,13 @@
 }
 
 void
-read_fatal_details (char const *name, off_t offset, size_t size)
+read_fatal_details (char const *name, off64_t offset, size64_t size)
 {
   char buf[UINTMAX_STRSIZE_BOUND];
   int e = errno;
   FATAL_ERROR ((0, e,
-		ngettext ("%s: Read error at byte %s, while reading %lu byte",
-			  "%s: Read error at byte %s, while reading %lu bytes",
+		ngettext ("%s: Read error at byte %s, while reading %" PRIu64 " byte",
+			  "%s: Read error at byte %s, while reading %" PRIu64 " bytes",
 			  size),
 		quotearg_colon (name), STRINGIFY_BIGINT (offset, buf),
 		(unsigned long) size));
@@ -252,7 +252,7 @@
 }
 
 void
-seek_error_details (char const *name, off_t offset)
+seek_error_details (char const *name, off64_t offset)
 {
   char buf[UINTMAX_STRSIZE_BOUND];
   int e = errno;
@@ -268,7 +268,7 @@
 }
 
 void
-seek_warn_details (char const *name, off_t offset)
+seek_warn_details (char const *name, off64_t offset)
 {
   char buf[UINTMAX_STRSIZE_BOUND];
   int e = errno;
diff -ur C:\FGCVS\tar\lib\paxlib.h C:\Projects\tar\lib\paxlib.h
--- C:\FGCVS\tar\lib\paxlib.h	Wed Jun 27 15:49:46 2007
+++ C:\Projects\tar\lib\paxlib.h	Fri Sep 12 18:07:32 2008
@@ -75,19 +75,19 @@
 void open_fatal (char const *) __attribute__ ((noreturn));
 void open_warn (char const *);
 void read_error (char const *);
-void read_error_details (char const *, off_t, size_t);
+void read_error_details (char const *, off64_t, size64_t);
 void read_fatal (char const *) __attribute__ ((noreturn));
-void read_fatal_details (char const *, off_t, size_t) __attribute__ ((noreturn));
-void read_warn_details (char const *, off_t, size_t);
+void read_fatal_details (char const *, off64_t, size64_t) __attribute__ ((noreturn));
+void read_warn_details (char const *, off64_t, size64_t);
 void readlink_error (char const *);
 void readlink_warn (char const *);
 void rmdir_error (char const *);
 void savedir_error (char const *);
 void savedir_warn (char const *);
 void seek_error (char const *);
-void seek_error_details (char const *, off_t);
+void seek_error_details (char const *, off64_t);
 void seek_warn (char const *);
-void seek_warn_details (char const *, off_t);
+void seek_warn_details (char const *, off64_t);
 void stat_fatal (char const *);
 void stat_error (char const *);
 void stat_warn (char const *);
diff -ur C:\FGCVS\tar\lib\readlink.c C:\Projects\tar\lib\readlink.c
--- C:\FGCVS\tar\lib\readlink.c	Sun Nov 18 11:46:56 2007
+++ C:\Projects\tar\lib\readlink.c	Fri Sep 12 16:15:23 2008
@@ -36,12 +36,12 @@
 int
 readlink (const char *path, char *buf, size_t bufsize)
 {
-  struct stat statbuf;
+  struct_stat statbuf;
 
   /* In general we should use lstat() here, not stat().  But on platforms
      without symbolic links lstat() - if it exists - would be equivalent to
      stat(), therefore we can use stat().  This saves us a configure check.  */
-  if (stat (path, &statbuf) >= 0)
+  if (FNSTAT (path, &statbuf) >= 0)
     errno = EINVAL;
   return -1;
 }
diff -ur C:\FGCVS\tar\lib\regcomp.c C:\Projects\tar\lib\regcomp.c
--- C:\FGCVS\tar\lib\regcomp.c	Sat Feb 16 13:12:20 2008
+++ C:\Projects\tar\lib\regcomp.c	Fri Sep 12 17:11:12 2008
@@ -778,7 +778,7 @@
   __libc_lock_init (dfa->lock);
 
   err = re_string_construct (&regexp, pattern, length, preg->translate,
-			     syntax & RE_ICASE, dfa);
+			     (bool)(syntax & RE_ICASE), dfa);
   if (BE (err != REG_NOERROR, 0))
     {
     re_compile_internal_free_return:
diff -ur C:\FGCVS\tar\lib\regex_internal.h C:\Projects\tar\lib\regex_internal.h
--- C:\FGCVS\tar\lib\regex_internal.h	Tue Oct 30 21:48:30 2007
+++ C:\Projects\tar\lib\regex_internal.h	Mon Sep 08 17:02:13 2008
@@ -752,7 +752,7 @@
 static inline bool
 bitset_contain (const bitset_t set, Idx i)
 {
-  return (set[i / BITSET_WORD_BITS] >> i % BITSET_WORD_BITS) & 1;
+  return (bool)((set[i / BITSET_WORD_BITS] >> i % BITSET_WORD_BITS) & 1);
 }
 
 static inline void
diff -ur C:\FGCVS\tar\lib\regexec.c C:\Projects\tar\lib\regexec.c
--- C:\FGCVS\tar\lib\regexec.c	Tue Oct 30 21:48:30 2007
+++ C:\Projects\tar\lib\regexec.c	Fri Sep 12 17:11:12 2008
@@ -703,7 +703,7 @@
   fl_longest_match = (nmatch != 0 || dfa->nbackref);
 
   err = re_string_allocate (&mctx.input, string, length, dfa->nodes_len + 1,
-			    preg->translate, preg->syntax & RE_ICASE, dfa);
+			    preg->translate, (bool)(preg->syntax & RE_ICASE), dfa);
   if (BE (err != REG_NOERROR, 0))
     goto free_return;
   mctx.input.stop = stop;
diff -ur C:\FGCVS\tar\lib\rmt.h C:\Projects\tar\lib\rmt.h
--- C:\FGCVS\tar\lib\rmt.h	Wed Jun 27 15:49:46 2007
+++ C:\Projects\tar\lib\rmt.h	Tue Sep 09 12:57:51 2008
@@ -19,6 +19,30 @@
 
 extern char *rmt_command;
 extern char *rmt_dev_name__;
+extern bool force_local_option;
+
+#ifdef _MSC_VER /* NO remote seek, and all 64-bits */
+
+/* ***********************************************
+   remote drive NOT supported in WIN32
+   *********************************************** */
+#define _remdev(dev_name) (0)
+#define _isrmt(fd) ((fd) >= 0x7ffffffe)   /* is NEVER remote */
+#define rmtopen(dev_name, oflag, mode, command) open (dev_name, oflag, mode)
+#define rmtaccess(dev_name, amode) access (dev_name, amode)
+#define rmtstat(dev_name, buffer) FNSTAT (dev_name, buffer)
+#define rmtcreat(dev_name, mode, command) creat (dev_name, mode)
+#define rmtlstat(dev_name, muffer) FNSTAT (dev_name, buffer)
+#define rmtread(fd, buffer, length) safe_read (fd, buffer, length)
+#define rmtlseek(fd, offset, wher) FDSEEK( fd, offset, wher )
+#define rmtclose(fd) close (fd)
+#define rmtioctl(fd, request, argument) ioctl (fd, request, argument)
+#define rmtdup(fd) dup (fd)
+#define rmtfstat(fd, buffer) FDSTAT (fd, buffer)
+#define rmtfcntl(cd, command, argument) fcntl (fd, command, argument)
+#define rmtisatty(fd) isatty (fd)
+
+#else /* !_MSC_VER */
 
 int rmt_open__ (const char *, int, int, const char *);
 int rmt_close__ (int);
@@ -27,8 +51,6 @@
 off_t rmt_lseek__ (int, off_t, int);
 int rmt_ioctl__ (int, int, char *);
 
-extern bool force_local_option;
-
 /* A filename is remote if it contains a colon not preceded by a slash,
    to take care of `/:/' which is a shorthand for `/.../<CELL-NAME>/fs'
    on machines running OSF's Distributing Computing Environment (DCE) and
@@ -97,3 +119,5 @@
 
 #define rmtisatty(fd) \
   (_isrmt (fd) ? 0 : isatty (fd))
+
+#endif /* _MSC_VER y/n */
diff -ur C:\FGCVS\tar\lib\rtapelib.c C:\Projects\tar\lib\rtapelib.c
--- C:\FGCVS\tar\lib\rtapelib.c	Sun Aug 12 09:57:16 2007
+++ C:\Projects\tar\lib\rtapelib.c	Thu Aug 14 17:43:44 2008
@@ -60,7 +60,9 @@
 #endif
 
 #include <rmt.h>
+#ifndef _MSC_VER /* no rmt-command.h */
 #include <rmt-command.h>
+#endif /* !_MSC_VER */
 
 /* Exit status if exec errors.  */
 #define EXIT_ON_EXEC_ERROR 128
@@ -118,6 +120,9 @@
 static int
 do_command (int handle, const char *buffer)
 {
+#ifdef _MSC_VER /* remove pipe from do_command() */
+   return -1;
+#else /* !_MSC_VER */
   /* Save the current pipe handler and try to make the request.  */
 
   size_t length = strlen (buffer);
@@ -132,6 +137,7 @@
 
   _rmt_shutdown (handle, EIO);
   return -1;
+#endif /* _MSC_VER y/n */
 }
 
 static char *
@@ -361,6 +367,9 @@
 rmt_open__ (const char *file_name, int open_mode, int bias,
             const char *remote_shell)
 {
+#ifdef _MSC_VER /* remove pipe from rmt_open__ */
+   return -1;
+#else /* !_MSC_VER */
   int remote_pipe_number;	/* pseudo, biased file descriptor */
   char *file_name_copy;		/* copy of file_name string */
   char *remote_host;		/* remote host name */
@@ -541,6 +550,7 @@
 
   free (file_name_copy);
   return remote_pipe_number + bias;
+#endif /* _MSC_VER y/n */
 }
 
 /* Close remote tape connection HANDLE and shut down.  Return 0 if
@@ -591,6 +601,9 @@
 size_t
 rmt_write__ (int handle, char *buffer, size_t length)
 {
+#ifdef _MSC_VER /* remove pipe from rmt_write__ */
+   return 0;
+#else /* !_MSC_VER */
   char command_buffer[COMMAND_BUFFER_SIZE];
   RETSIGTYPE (*pipe_handler) ();
   size_t written;
@@ -616,6 +629,7 @@
 
   _rmt_shutdown (handle, EIO);
   return written;
+#endif /* _MSC_VER y/n */
 }
 
 /* Perform an imitation lseek operation on remote tape connection
diff -ur C:\FGCVS\tar\lib\savedir.c C:\Projects\tar\lib\savedir.c
--- C:\FGCVS\tar\lib\savedir.c	Sun Nov 18 11:46:56 2007
+++ C:\Projects\tar\lib\savedir.c	Sat Aug 16 12:02:35 2008
@@ -129,8 +129,16 @@
    the end is marked by two '\0' characters in a row.
    Return NULL (setting errno) if FD cannot be read or closed.  */
 
+#ifdef _MSC_VER
+char *
+fdsavedir (char * dir_name)
+{
+  return savedirstream (opendir (dir_name));
+}
+#else /* !_MSC_VER */
 char *
 fdsavedir (int fd)
 {
   return savedirstream (fdopendir (fd));
 }
+#endif /* _MSC_VER y/n */
diff -ur C:\FGCVS\tar\lib\savedir.h C:\Projects\tar\lib\savedir.h
--- C:\FGCVS\tar\lib\savedir.h	Sun Nov 18 11:46:56 2007
+++ C:\Projects\tar\lib\savedir.h	Sat Aug 16 12:02:35 2008
@@ -21,6 +21,10 @@
 # define SAVEDIR_H_
 
 char *savedir (char const *dir);
+#ifdef _MSC_VER /* replace fdasvedir(FD) with (struct tar_stat_info *st) */
+char *fdsavedir (char * dir_name);
+#else /* !_MSC_VER */
 char *fdsavedir (int fd);
+#endif /* _MSC_VER y/n */
 
 #endif
diff -ur C:\FGCVS\tar\lib\setenv.c C:\Projects\tar\lib\setenv.c
--- C:\FGCVS\tar\lib\setenv.c	Thu Feb 28 08:40:08 2008
+++ C:\Projects\tar\lib\setenv.c	Sat Aug 23 14:29:44 2008
@@ -107,6 +107,29 @@
 __add_to_environ (const char *name, const char *value, const char *combined,
 		  int replace)
 {
+#ifdef _MSC_VER   /* fix __add_to_environment() for WIN32 */
+   int   rval = -1;
+   char * new_value;
+   if( !name || !value || strlen(name) == 0 || *name == 0 )
+   {
+      return rval;
+   }
+	new_value = (char *) malloc (strlen(name) + strlen(value) + 2);
+   if (new_value == NULL)
+	{
+      __set_errno (ENOMEM);
+      return rval;
+   }
+   strcpy(new_value, name);
+   strcat(new_value, "=");
+   strcat(new_value, value);
+   if( _putenv(new_value) == 0 )
+   {
+      rval = 0;   /* no error */
+   }
+   free(new_value);
+   return rval;
+#else /* !_MSC_VER */
   register char **ep;
   register size_t size;
   const size_t namelen = strlen (name);
@@ -276,6 +299,7 @@
   UNLOCK;
 
   return 0;
+#endif /* _MSC_VER y/n */
 }
 
 int
diff -ur C:\FGCVS\tar\lib\stat-time.h C:\Projects\tar\lib\stat-time.h
--- C:\FGCVS\tar\lib\stat-time.h	Fri Feb 08 20:26:12 2008
+++ C:\Projects\tar\lib\stat-time.h	Mon Sep 08 13:43:21 2008
@@ -47,7 +47,7 @@
 
 /* Return the nanosecond component of *ST's access time.  */
 static inline long int
-get_stat_atime_ns (struct stat const *st)
+get_stat_atime_ns (struct_stat const *st)
 {
 # if defined STAT_TIMESPEC
   return STAT_TIMESPEC (st, st_atim).tv_nsec;
@@ -60,7 +60,7 @@
 
 /* Return the nanosecond component of *ST's status change time.  */
 static inline long int
-get_stat_ctime_ns (struct stat const *st)
+get_stat_ctime_ns (struct_stat const *st)
 {
 # if defined STAT_TIMESPEC
   return STAT_TIMESPEC (st, st_ctim).tv_nsec;
@@ -73,7 +73,7 @@
 
 /* Return the nanosecond component of *ST's data modification time.  */
 static inline long int
-get_stat_mtime_ns (struct stat const *st)
+get_stat_mtime_ns (struct_stat const *st)
 {
 # if defined STAT_TIMESPEC
   return STAT_TIMESPEC (st, st_mtim).tv_nsec;
@@ -86,7 +86,7 @@
 
 /* Return the nanosecond component of *ST's birth time.  */
 static inline long int
-get_stat_birthtime_ns (struct stat const *st)
+get_stat_birthtime_ns (struct_stat const *st)
 {
 # if defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC
   return STAT_TIMESPEC (st, st_birthtim).tv_nsec;
@@ -101,7 +101,7 @@
 
 /* Return *ST's access time.  */
 static inline struct timespec
-get_stat_atime (struct stat const *st)
+get_stat_atime (struct_stat const *st)
 {
 #ifdef STAT_TIMESPEC
   return STAT_TIMESPEC (st, st_atim);
@@ -115,7 +115,7 @@
 
 /* Return *ST's status change time.  */
 static inline struct timespec
-get_stat_ctime (struct stat const *st)
+get_stat_ctime (struct_stat const *st)
 {
 #ifdef STAT_TIMESPEC
   return STAT_TIMESPEC (st, st_ctim);
@@ -129,7 +129,7 @@
 
 /* Return *ST's data modification time.  */
 static inline struct timespec
-get_stat_mtime (struct stat const *st)
+get_stat_mtime (struct_stat const *st)
 {
 #ifdef STAT_TIMESPEC
   return STAT_TIMESPEC (st, st_mtim);
@@ -144,7 +144,7 @@
 /* Return *ST's birth time, if available; otherwise return a value
    with negative tv_nsec.  */
 static inline struct timespec
-get_stat_birthtime (struct stat const *st)
+get_stat_birthtime (struct_stat const *st)
 {
   struct timespec t;
 
diff -ur C:\FGCVS\tar\lib\stdopen.c C:\Projects\tar\lib\stdopen.c
--- C:\FGCVS\tar\lib\stdopen.c	Mon Oct 22 18:48:04 2007
+++ C:\Projects\tar\lib\stdopen.c	Thu Aug 14 17:43:45 2008
@@ -41,7 +41,9 @@
 {
   int fd;
   bool ok = true;
-
+#ifdef _MSC_VER /* stdopen() - are already open in WIN32 */
+  fd = 0;
+#else /* !_MSC_VER */
   for (fd = 0; fd <= 2; fd++)
     {
       if (fcntl (fd, F_GETFD) < 0)
@@ -73,5 +75,6 @@
         }
     }
 
+#endif /* _MSC_VER y/n */
   return ok;
 }
diff -ur C:\FGCVS\tar\lib\strtoimax.c C:\Projects\tar\lib\strtoimax.c
--- C:\FGCVS\tar\lib\strtoimax.c	Sun Nov 18 11:46:56 2007
+++ C:\Projects\tar\lib\strtoimax.c	Tue Sep 09 14:39:46 2008
@@ -50,12 +50,21 @@
 # define Int uintmax_t
 # define Unsigned unsigned
 # define strtoimax strtoumax
+#ifdef _MSC_VER /* use 64-bit version _strtoui64 */
+# define strtol _strtoui64
+# define strtoll _strtoui64
+#else /* !_MSC_VER */
 # define strtol strtoul
 # define strtoll strtoull
+#endif /* _MSC_VER y/n */
 #else
 # define Have_long_long HAVE_LONG_LONG_INT
 # define Int intmax_t
 # define Unsigned
+#ifdef _MSC_VER /* use 64-bit version _strtoi64 */
+# define strtol _strtoi64
+# define strtoll _strtoi64
+#endif /* _MSC_VER */
 #endif
 
 Int
@@ -68,7 +77,9 @@
   if (sizeof (Int) != sizeof (Unsigned long int))
     return strtoll (ptr, endptr, base);
 #else
+#ifndef _MSC_VER /* verify() fails due 64-bit can NOT be same size as 'long int' */
   verify (sizeof (Int) == sizeof (Unsigned long int));
+#endif /* !_MSC_VER */
 #endif
 
   return strtol (ptr, endptr, base);
diff -ur C:\FGCVS\tar\lib\strtol.c C:\Projects\tar\lib\strtol.c
--- C:\FGCVS\tar\lib\strtol.c	Sun Nov 18 11:46:56 2007
+++ C:\Projects\tar\lib\strtol.c	Mon Sep 08 12:24:57 2008
@@ -345,7 +345,7 @@
     end = NULL;
 
   cutoff = STRTOL_ULONG_MAX / (unsigned LONG int) base;
-  cutlim = STRTOL_ULONG_MAX % (unsigned LONG int) base;
+  cutlim = (int)(STRTOL_ULONG_MAX % (unsigned LONG int) base);
 
   overflow = 0;
   i = 0;
diff -ur C:\FGCVS\tar\lib\system.h C:\Projects\tar\lib\system.h
--- C:\FGCVS\tar\lib\system.h	Mon Feb 18 18:44:36 2008
+++ C:\Projects\tar\lib\system.h	Thu Aug 14 13:53:49 2008
@@ -460,7 +460,7 @@
 # include <grp.h>
 #endif
 
-#if MSDOS
+#if MSDOS || WIN32
 # include <process.h>
 # define SET_BINARY_MODE(arc) setmode(arc, O_BINARY)
 # define ERRNO_IS_EACCES errno == EACCES
diff -ur C:\FGCVS\tar\lib\tempname.c C:\Projects\tar\lib\tempname.c
--- C:\FGCVS\tar\lib\tempname.c	Sun Nov 18 11:46:56 2007
+++ C:\Projects\tar\lib\tempname.c	Mon Sep 08 16:18:12 2008
@@ -51,7 +51,9 @@
 #include <string.h>
 
 #include <fcntl.h>
+#ifndef _MSC_VER /* no such file in WIN32 - timespec through win_time.h from config.h */
 #include <sys/time.h>
+#endif /* _MSC_VER y/n */
 #include <stdint.h>
 #include <unistd.h>
 
@@ -62,13 +64,22 @@
 # define small_open __open
 # define large_open __open64
 #else
+#ifdef _MSC_VER /* use __stat64 */ 
+# define struct_stat64 struct _stat64
+#else /* !_MSC_VER */
 # define struct_stat64 struct stat
+#endif /* _MSC_VER y/n */
 # define small_open open
 # define large_open open
 # define __gen_tempname gen_tempname
 # define __getpid getpid
 # define __gettimeofday gettimeofday
+#ifdef _MSC_VER /* mkdir only takes 1 parameter 
+ it will also ONLY create if last is the only missing directory */
+# define __mkdir(a,b) mkdir(a)
+#else /* !_MSC_VER */
 # define __mkdir mkdir
+#endif /* _MSC_VER y/n */
 # define __lxstat64(version, file, buf) lstat (file, buf)
 # define __xstat64(version, file, buf) stat (file, buf)
 #endif
diff -ur C:\FGCVS\tar\lib\uinttostr.c C:\Projects\tar\lib\uinttostr.c
--- C:\FGCVS\tar\lib\uinttostr.c	Sun Nov 18 11:46:56 2007
+++ C:\Projects\tar\lib\uinttostr.c	Sat Sep 13 12:28:03 2008
@@ -1,3 +1,7 @@
 #define inttostr uinttostr
+#ifdef _MSC_VER /* use 64-bit offets */
+#define inttype uintmax_t
+#else /* !_MSC_VER */
 #define inttype unsigned int
+#endif /* _MSC_VER y/n */
 #include "inttostr.c"
diff -ur C:\FGCVS\tar\lib\unsetenv.c C:\Projects\tar\lib\unsetenv.c
--- C:\FGCVS\tar\lib\unsetenv.c	Thu Feb 28 08:40:08 2008
+++ C:\Projects\tar\lib\unsetenv.c	Sat Aug 23 14:09:53 2008
@@ -47,7 +47,25 @@
 # define unsetenv __unsetenv
 #endif
 
+#ifdef _MSC_VER
+int
+unsetenv (const char *name)
+{
+  size_t len;
+  if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
+  {
+      __set_errno (EINVAL);
+      return -1;
+  }
+  if( _putenv(name) )
+  {
+      __set_errno (EINVAL);
+      return -1;
+  }
+  return 0;
+}
 
+#else /* !_MSC_VER */
 int
 unsetenv (const char *name)
 {
@@ -88,3 +106,5 @@
 # undef unsetenv
 weak_alias (__unsetenv, unsetenv)
 #endif
+
+#endif /* _MSC_VER y/n */
diff -ur C:\FGCVS\tar\lib\utime.c C:\Projects\tar\lib\utime.c
--- C:\FGCVS\tar\lib\utime.c	Sun Nov 18 11:46:58 2007
+++ C:\Projects\tar\lib\utime.c	Fri Sep 12 16:15:23 2008
@@ -64,14 +64,14 @@
   int fd;
   char c;
   int status = 0;
-  struct stat st;
+  struct_stat st;
   int saved_errno = 0;
 
   fd = open (file, O_RDWR);
   if (fd < 0
-      || fstat (fd, &st) < 0
+      || FDSTAT (fd, &st) < 0
       || safe_read (fd, &c, sizeof c) == SAFE_READ_ERROR
-      || lseek (fd, (off_t) 0, SEEK_SET) < 0
+      || FDSEEK (fd, (off64_t) 0, SEEK_SET) < 0
       || full_write (fd, &c, sizeof c) != sizeof c
       /* Maybe do this -- it's necessary on SunOS 4.1.3 with some combination
 	 of patches, but that system doesn't use this code: it has utimes.
diff -ur C:\FGCVS\tar\lib\utimens.c C:\Projects\tar\lib\utimens.c
--- C:\FGCVS\tar\lib\utimens.c	Fri Feb 08 20:26:12 2008
+++ C:\Projects\tar\lib\utimens.c	Tue Sep 09 12:57:51 2008
@@ -26,7 +26,9 @@
 
 #include <errno.h>
 #include <fcntl.h>
+#ifndef _MSC_VER /* no such file in WIN32 - timespec through win_time.h from config.h */
 #include <sys/time.h>
+#endif /* _MSC_VER y/n */
 #include <unistd.h>
 
 #if HAVE_UTIME_H
@@ -173,8 +175,21 @@
       }
     else
       ut = NULL;
-
+#ifdef _MSC_VER /* setting time of read only files fails */
+    { /* CAN NOT SET TIME ON READ ONLY FILES, (nor DIRECTORIES) */
+       int res = utime (file, ut);  /* try it ... */
+       int uerr = errno;            /* get errno  */
+       if (( res == -1 )&&(uerr == EACCES)) {   /* if FAILED due to 'access' */
+          res = _chmod( file, _S_IREAD | _S_IWRITE ); /* try removing WRITE block */
+          if( res == 0 ) { /* if that succeeds ... */
+             res = utime (file, ut);   /* try again now ... */
+          }
+       }
+       return res;
+    }
+#else /* !_MSC_VER */
     return utime (file, ut);
+#endif /* _MSC_VER y/n */
   }
 #endif
 }
diff -ur C:\FGCVS\tar\lib\version-etc.c C:\Projects\tar\lib\version-etc.c
--- C:\FGCVS\tar\lib\version-etc.c	Fri Feb 08 20:26:12 2008
+++ C:\Projects\tar\lib\version-etc.c	Thu Aug 28 17:36:17 2008
@@ -144,6 +144,9 @@
       break;
     }
   va_end (authors);
+#ifdef _MSC_VER /* tack my name on to the WIN32 port */
+  vfprintf( stream, _("Messed up for WIN32 by Geoff McLane. ;=))\n"), authors);
+#endif /* _MSC_VER */
 }
 
 
diff -ur C:\FGCVS\tar\rmt\rmt.c C:\Projects\tar\rmt\rmt.c
--- C:\FGCVS\tar\rmt\rmt.c	Wed Jun 27 15:49:46 2007
+++ C:\Projects\tar\rmt\rmt.c	Thu Aug 14 17:43:44 2008
@@ -34,7 +34,9 @@
 #include "system.h"
 #include "system-ioctl.h"
 #include <closeout.h>
+#ifndef _MSC_VER /* no configmake.h */
 #include <configmake.h>
+#endif /* !_MSC_VER */
 #include <safe-read.h>
 #include <full-write.h>
 #include <version-etc.h>
diff -ur C:\FGCVS\tar\src\buffer.c C:\Projects\tar\src\buffer.c
--- C:\FGCVS\tar\src\buffer.c	Mon Feb 04 11:36:52 2008
+++ C:\Projects\tar\src\buffer.c	Sat Sep 13 13:10:12 2008
@@ -53,12 +53,12 @@
 union block *record_end;	/* last+1 block of archive record */
 union block *current_block;	/* current block of archive */
 enum access_mode access_mode;	/* how do we handle the archive */
-off_t records_read;		/* number of records read from this archive */
-off_t records_written;		/* likewise, for records written */
-extern off_t records_skipped;   /* number of records skipped at the start
+off64_t records_read;		/* number of records read from this archive */
+off64_t records_written;		/* likewise, for records written */
+extern off64_t records_skipped;   /* number of records skipped at the start
 				   of the archive, defined in delete.c */   
 
-static off_t record_start_block; /* block ordinal at record_start */
+static off64_t record_start_block; /* block ordinal at record_start */
 
 /* Where we write list messages (not errors, not interactions) to.  */
 FILE *stdlis;
@@ -106,17 +106,28 @@
 /* Used by flush_read and flush_write to store the real info about saved
    names.  */
 static char *real_s_name;
+#ifdef _MSC_VER /* use 64-bit sizes */
+static off64_t real_s_totsize;
+static off64_t real_s_sizeleft;
+#else /* !_MSC_VER */
 static off_t real_s_totsize;
 static off_t real_s_sizeleft;
+#endif /* _MSC_VER y/n */
 
 
 /* Multi-volume tracking support */
 static char *save_name;		/* name of the file we are currently writing */
+#ifdef _MSC_VER /* use 64-bit sizes */
+static off64_t save_totsize;	/* total size of file we are writing, only
+				   valid if save_name is nonzero */
+static off64_t save_sizeleft;	/* where we are in the file we are writing,
+				   only valid if save_name is nonzero */
+#else /* !_MSC_VER */
 static off_t save_totsize;	/* total size of file we are writing, only
 				   valid if save_name is nonzero */
 static off_t save_sizeleft;	/* where we are in the file we are writing,
 				   only valid if save_name is nonzero */
-
+#endif /* _MSC_VER y/n */
 
 static struct tar_stat_info dummy;
 
@@ -144,13 +155,13 @@
 }
 
 void
-mv_total_size (off_t size)
+mv_total_size (off64_t size)
 {
   save_totsize = size;
 }
 
 void
-mv_size_left (off_t size)
+mv_size_left (off64_t size)
 {
   save_sizeleft = size;
 }
@@ -269,7 +280,6 @@
 		     MODE_RW, rsh_command_option);
   if (archive == -1)
     return archive;
-
   if (!multi_volume_option)
     {
       bool shortfile;
@@ -314,9 +324,9 @@
 
   fprintf (fp, "%s: %s (%s, %s/s)\n",
 	   text, bytes,
-	   human_readable (numbytes, abbr, human_opts, 1, 1),
+	   human_readable ((size64_t)numbytes, abbr, human_opts, 1, 1),
 	   (0 < duration && numbytes / duration < (uintmax_t) -1
-	    ? human_readable (numbytes / duration, rate, human_opts, 1, 1)
+	    ? human_readable ((size64_t)(numbytes / duration), rate, human_opts, 1, 1)
 	    : "?"));
 }
 
@@ -338,13 +348,13 @@
       {
 	char buf[UINTMAX_STRSIZE_BOUND];
 	print_stats (stderr, _("Total bytes read"),
-		     records_read * record_size);
+		     (tarlong)(records_read * record_size));
 	print_stats (stderr, _("Total bytes written"),
 		     prev_written + bytes_written);
 	fprintf (stderr, _("Total bytes deleted: %s\n"),
-		 STRINGIFY_BIGINT ((records_read - records_skipped)
+		 STRINGIFY_BIGINT ((size64_t)((records_read - records_skipped)
 				    * record_size
-				   - (prev_written + bytes_written), buf));
+				   - (prev_written + bytes_written)), buf));
       }
       break;
 
@@ -352,7 +362,7 @@
     case LIST_SUBCOMMAND:
     case DIFF_SUBCOMMAND:
       print_stats (stderr, _("Total bytes read"),
-		   records_read * record_size);
+		   (tarlong)(records_read * record_size));
       break;
 
     default:
@@ -361,7 +371,7 @@
 }
 
 /* Compute and return the block ordinal at current_block.  */
-off_t
+off64_t
 current_block_ordinal (void)
 {
   return record_start_block + (current_block - record_start);
@@ -756,7 +766,7 @@
 #endif
 
   {
-    off_t position = rmtlseek (archive, (off_t) 0, SEEK_CUR);
+    off64_t position = rmtlseek (archive, (off64_t) 0, SEEK_CUR);
 
     /* Seek back to the beginning of this record and start writing there.  */
 
@@ -779,13 +789,13 @@
   }
 }
 
-off_t
-seek_archive (off_t size)
+off64_t
+seek_archive (off64_t size)
 {
-  off_t start = current_block_ordinal ();
-  off_t offset;
-  off_t nrec, nblk;
-  off_t skipped = (blocking_factor - (current_block - record_start));
+  off64_t start = current_block_ordinal ();
+  off64_t offset;
+  off64_t nrec, nblk;
+  off64_t skipped = (blocking_factor - (current_block - record_start));
 
   size -= skipped * BLOCKSIZE;
 
@@ -1323,7 +1333,7 @@
 {
   if (archive_format == POSIX_FORMAT)
     {
-      off_t block_ordinal;
+      off64_t block_ordinal;
       union block *blk;
       struct tar_stat_info st;
       static size_t real_s_part_no; /* FIXME */
@@ -1332,8 +1342,8 @@
       memset (&st, 0, sizeof st);
       st.orig_file_name = st.file_name = real_s_name;
       st.stat.st_mode = S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH;
-      st.stat.st_uid = getuid ();
-      st.stat.st_gid = getgid ();
+      st.stat.st_uid = (short)getuid ();
+      st.stat.st_gid = (short)getgid ();
       st.orig_file_name = xheader_format_name (&st,
 					       "%d/GNUFileParts.%p/%f.%n",
 					       real_s_part_no);
@@ -1399,7 +1409,7 @@
 {
   if (archive_format == POSIX_FORMAT)
     {
-      off_t d = real_s_totsize - real_s_sizeleft;
+      off64_t d = real_s_totsize - real_s_sizeleft;
       xheader_store ("GNU.volume.filename", &dummy, real_s_name);
       xheader_store ("GNU.volume.size", &dummy, &real_s_sizeleft);
       xheader_store ("GNU.volume.offset", &dummy, &d);
@@ -1520,6 +1530,9 @@
   for (;;)
     {
       status = rmtread (archive, record_start->buffer, record_size);
+#ifdef DBGV5 /* show debug archive read information */
+      win_debug_read( status, archive, record_start->buffer, stdlis, verbose_option );
+#endif /* DBGV5 */
       if (status == record_size)
 	{
 	  records_read++;
@@ -1674,3 +1687,21 @@
     }
   set_volume_start_time ();
 }
+
+#ifdef NEW_DELETE_FUNCTION /* write a NEW achive, without 'deleted' members */
+void add_bytes_written( int len )
+{
+   bytes_written += len;
+}
+tarlong get_bytes_written( void )
+{
+   return bytes_written;
+}
+tarlong get_prev_written( void )
+{
+   return prev_written;
+}
+#endif /* NEW_DELETE_FUNCTION */
+
+/* eof - buffer.c */
+
diff -ur C:\FGCVS\tar\src\checkpoint.c C:\Projects\tar\src\checkpoint.c
--- C:\FGCVS\tar\src\checkpoint.c	Wed Jan 23 10:19:58 2008
+++ C:\Projects\tar\src\checkpoint.c	Fri Sep 12 17:02:05 2008
@@ -247,7 +247,7 @@
 	  break;
 	  
 	case cop_sleep:
-	  sleep (p->v.time);
+	  sleep ((unsigned int)p->v.time);
 	  break;
 	  
 	case cop_exec:
diff -ur C:\FGCVS\tar\src\common.h C:\Projects\tar\src\common.h
--- C:\FGCVS\tar\src\common.h	Mon Apr 14 14:03:12 2008
+++ C:\Projects\tar\src\common.h	Fri Sep 12 17:48:54 2008
@@ -360,6 +360,11 @@
    set for incremental archives. */
 GLOBAL bool delay_directory_restore_option;
 
+#ifdef NEW_DELETE_FUNCTION
+/* be able to off and on the win delete function, as --windel */
+GLOBAL bool windelete_option;
+#endif /* NEW_DELETE_FUNCTION */
+
 /* Warn about implicit use of the wildcards in command line arguments.
    (Default for tar prior to 1.15.91, but changed afterwards */
 GLOBAL bool warn_regex_usage;
@@ -387,7 +392,7 @@
 extern uintmax_t continued_file_offset;
 
 size_t available_space_after (union block *pointer);
-off_t current_block_ordinal (void);
+off64_t current_block_ordinal (void);
 void close_archive (void);
 void closeout_volume_number (void);
 void compute_duration (void);
@@ -404,13 +409,13 @@
 void xclose (int fd);
 void archive_write_error (ssize_t status) __attribute__ ((noreturn));
 void archive_read_error (void);
-off_t seek_archive (off_t size);
+off64_t seek_archive (off64_t size);
 void set_start_time (void);
 
 void mv_begin (struct tar_stat_info *st);
 void mv_end (void);
-void mv_total_size (off_t size);
-void mv_size_left (off_t size);
+void mv_total_size (off64_t size);
+void mv_size_left (off64_t size);
 
 void buffer_write_global_xheader (void);
 
@@ -434,7 +439,7 @@
 void dump_file (const char *st, int top_level, dev_t parent_device);
 union block *start_header (struct tar_stat_info *st);
 void finish_header (struct tar_stat_info *st, union block *header,
-		    off_t block_ordinal);
+		    off64_t block_ordinal);
 void simple_finish_header (union block *header);
 union block * write_extended (bool global, struct tar_stat_info *st,
 			      union block *old_header);
@@ -462,8 +467,8 @@
 bool major_to_chars (major_t m, char *buf, size_t size);
 bool minor_to_chars (minor_t m, char *buf, size_t size);
 bool mode_to_chars (mode_t m, char *buf, size_t size);
-bool off_to_chars (off_t off, char *buf, size_t size);
-bool size_to_chars (size_t v, char *buf, size_t size);
+bool off_to_chars (off64_t off, char *buf, size_t size);
+bool size_to_chars (size64_t v, char *buf, size_t size);
 bool time_to_chars (time_t t, char *buf, size_t size);
 bool uid_to_chars (uid_t uid, char *buf, size_t size);
 bool uintmax_to_chars (uintmax_t v, char *buf, size_t size);
@@ -525,8 +530,8 @@
 
 extern union block *current_header;
 extern enum archive_format current_format;
-extern size_t recent_long_name_blocks;
-extern size_t recent_long_link_blocks;
+extern size64_t recent_long_name_blocks;
+extern size64_t recent_long_link_blocks;
 
 void decode_header (union block *header, struct tar_stat_info *stat_info,
 		    enum archive_format *format_pointer, int do_user_group);
@@ -546,21 +551,21 @@
 major_t major_from_header (const char *buf, size_t size);
 minor_t minor_from_header (const char *buf, size_t size);
 mode_t mode_from_header (const char *buf, size_t size);
-off_t off_from_header (const char *buf, size_t size);
-size_t size_from_header (const char *buf, size_t size);
+off64_t off_from_header (const char *buf, size_t size);
+size64_t size_from_header (const char *buf, size_t size);
 time_t time_from_header (const char *buf, size_t size);
 uid_t uid_from_header (const char *buf, size_t size);
 uintmax_t uintmax_from_header (const char * buf, size_t size);
 
 void list_archive (void);
 void print_for_mkdir (char *dirname, int length, mode_t mode);
-void print_header (struct tar_stat_info *st, off_t block_ordinal);
+void print_header (struct tar_stat_info *st, off64_t block_ordinal);
 void read_and (void (*do_something) (void));
 enum read_header read_header_primitive (bool raw_extended_headers,
 					struct tar_stat_info *info);
 enum read_header read_header (bool raw_extended_headers);
 enum read_header tar_checksum (union block *header, bool silent);
-void skip_file (off_t size);
+void skip_file (off64_t size);
 void skip_member (void);
 
 /* Module misc.c.  */
@@ -593,17 +598,17 @@
 bool maybe_backup_file (const char *file_name, bool this_is_the_archive);
 void undo_last_backup (void);
 
-int deref_stat (bool deref, char const *name, struct stat *buf);
+int deref_stat (bool deref, char const *name, struct_stat *buf);
 
 int chdir_arg (char const *dir);
 void chdir_do (int dir);
 
 void close_diag (char const *name);
 void open_diag (char const *name);
-void read_diag_details (char const *name, off_t offset, size_t size);
+void read_diag_details (char const *name, off64_t offset, size64_t size);
 void readlink_diag (char const *name);
 void savedir_diag (char const *name);
-void seek_diag_details (char const *name, off_t offset);
+void seek_diag_details (char const *name, off64_t offset);
 void stat_diag (char const *name);
 void write_error_details (char const *name, size_t status, size_t size);
 void write_fatal (char const *name) __attribute__ ((noreturn));
@@ -705,10 +710,10 @@
 void sys_drain_input_pipe (void);
 void sys_wait_for_child (pid_t);
 void sys_spawn_shell (void);
-bool sys_compare_uid (struct stat *a, struct stat *b);
-bool sys_compare_gid (struct stat *a, struct stat *b);
+bool sys_compare_uid (struct_stat *a, struct_stat *b);
+bool sys_compare_gid (struct_stat *a, struct_stat *b);
 bool sys_file_is_archive (struct tar_stat_info *p);
-bool sys_compare_links (struct stat *link_data, struct stat *stat_data);
+bool sys_compare_links (struct_stat *link_data, struct_stat *stat_data);
 int sys_truncate (int fd);
 pid_t sys_child_open_for_compress (void);
 pid_t sys_child_open_for_uncompress (void);
@@ -729,7 +734,7 @@
 bool sparse_fixup_header (struct tar_stat_info *st);
 enum dump_status sparse_dump_file (int, struct tar_stat_info *st);
 enum dump_status sparse_extract_file (int fd, struct tar_stat_info *st,
-				      off_t *size);
+				      off64_t *size);
 enum dump_status sparse_skip_file (struct tar_stat_info *st);
 bool sparse_diff_file (int, struct tar_stat_info *st);
 
diff -ur C:\FGCVS\tar\src\compare.c C:\Projects\tar\src\compare.c
--- C:\FGCVS\tar\src\compare.c	Wed Feb 20 15:16:30 2008
+++ C:\Projects\tar\src\compare.c	Fri Sep 12 17:04:24 2008
@@ -120,9 +120,13 @@
 read_and_process (struct tar_stat_info *st, int (*processor) (size_t, char *))
 {
   union block *data_block;
+#ifdef _MSC_VER /* use 64-bit sizes */
+  size_t data_size;
+  off64_t size = st->stat.st_size;
+#else /* !_MSC_VER */
   size_t data_size;
   off_t size = st->stat.st_size;
-
+#endif /* _MSC_VER y/n */
   mv_begin (st);
   while (size)
     {
@@ -135,7 +139,7 @@
 
       data_size = available_space_after (data_block);
       if (data_size > size)
-	data_size = size;
+	data_size = (size_t)size;
       if (!(*processor) (data_size, data_block->buffer))
 	processor = process_noop;
       set_next_block_after ((union block *)
@@ -150,7 +154,7 @@
    --dereference (-h), for a file which should exist.  Diagnose any
    problem.  Return nonzero for success, zero otherwise.  */
 static int
-get_stat_data (char const *file_name, struct stat *stat_data)
+get_stat_data (char const *file_name, struct_stat *stat_data)
 {
   int status = deref_stat (dereference_option, file_name, stat_data);
 
@@ -171,11 +175,10 @@
 static void
 diff_dir (void)
 {
-  struct stat stat_data;
+  struct_stat stat_data;
 
   if (!get_stat_data (current_stat_info.file_name, &stat_data))
     return;
-
   if (!S_ISDIR (stat_data.st_mode))
     report_difference (&current_stat_info, _("File type differs"));
   else if ((current_stat_info.stat.st_mode & MODE_ALL) !=
@@ -187,7 +190,7 @@
 diff_file (void)
 {
   char const *file_name = current_stat_info.file_name;
-  struct stat stat_data;
+  struct_stat stat_data;
 
   if (!get_stat_data (file_name, &stat_data))
     skip_member ();
@@ -260,8 +263,8 @@
 static void
 diff_link (void)
 {
-  struct stat file_data;
-  struct stat link_data;
+  struct_stat file_data;
+  struct_stat link_data;
 
   if (get_stat_data (current_stat_info.file_name, &file_data)
       && get_stat_data (current_stat_info.link_name, &link_data)
@@ -297,7 +300,7 @@
 static void
 diff_special (void)
 {
-  struct stat stat_data;
+  struct_stat stat_data;
 
   /* FIXME: deal with umask.  */
 
@@ -368,7 +371,7 @@
 {
   const char *dumpdir_buffer;
   dev_t dev = 0;
-  struct stat stat_data;
+  struct_stat stat_data;
 
   if (deref_stat (true, current_stat_info.file_name, &stat_data))
     {
@@ -394,9 +397,9 @@
 static void
 diff_multivol (void)
 {
-  struct stat stat_data;
+  struct_stat stat_data;
   int fd, status;
-  off_t offset;
+  off64_t offset;
 
   if (current_stat_info.had_trailing_slash)
     {
@@ -432,7 +435,7 @@
       return;
     }
 
-  if (lseek (fd, offset, SEEK_SET) < 0)
+  if (FDSEEK (fd, offset, SEEK_SET) < 0)
     {
       seek_error_details (current_stat_info.file_name, offset);
       report_difference (&current_stat_info, NULL);
diff -ur C:\FGCVS\tar\src\create.c C:\Projects\tar\src\create.c
--- C:\FGCVS\tar\src\create.c	Mon Apr 14 14:03:12 2008
+++ C:\Projects\tar\src\create.c	Sat Sep 13 13:10:12 2008
@@ -155,14 +155,14 @@
    The result is undefined if SIZE is 0 or if VALUE is too large to fit.  */
 
 static void
-to_octal (uintmax_t value, char *where, size_t size)
+to_octal (uintmax_t value, char *pwhere, size_t size)
 {
   uintmax_t v = value;
   size_t i = size;
 
   do
     {
-      where[--i] = '0' + (v & ((1 << LG_8) - 1));
+      pwhere[--i] = (char)('0' + (v & ((1 << LG_8) - 1)));
       v >>= LG_8;
     }
   while (i);
@@ -198,7 +198,7 @@
    fit.  */
 
 static void
-to_base256 (int negative, uintmax_t value, char *where, size_t size)
+to_base256 (int negative, uintmax_t value, char *pwhere, size_t size)
 {
   uintmax_t v = value;
   uintmax_t propagated_sign_bits =
@@ -207,7 +207,7 @@
 
   do
     {
-      where[--i] = v & ((1 << LG_256) - 1);
+      pwhere[--i] = (char)(v & ((1 << LG_256) - 1));
       v = propagated_sign_bits | (v >> LG_256);
     }
   while (i);
@@ -427,15 +427,15 @@
 }
 
 bool
-off_to_chars (off_t v, char *p, size_t s)
+off_to_chars (off64_t v, char *p, size_t s)
 {
-  return to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "off_t");
+  return to_chars (v < 0, (uintmax_t) v, sizeof v, 0, p, s, "off64_t");
 }
 
 bool
-size_to_chars (size_t v, char *p, size_t s)
+size_to_chars (size64_t v, char *p, size_t s)
 {
-  return to_chars (0, (uintmax_t) v, sizeof v, 0, p, s, "size_t");
+  return to_chars (0, (uintmax_t) v, sizeof v, 0, p, s, "size64_t");
 }
 
 bool
@@ -528,8 +528,8 @@
   time (&t);
   TIME_TO_CHARS (t, header->header.mtime);
   MODE_TO_CHARS (S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, header->header.mode);
-  UID_TO_CHARS (getuid (), header->header.uid);
-  GID_TO_CHARS (getgid (), header->header.gid);
+  UID_TO_CHARS ((short)getuid (), header->header.uid);
+  GID_TO_CHARS ((short)getgid (), header->header.gid);
   MAJOR_TO_CHARS (0, header->header.devmajor);
   MINOR_TO_CHARS (0, header->header.devminor);
   strncpy (header->header.magic, TMAGIC, TMAGLEN);
@@ -830,14 +830,14 @@
   }
 
   {
-    off_t size = st->stat.st_size;
+    off64_t size = st->stat.st_size;
     if (archive_format == POSIX_FORMAT
 	&& MAX_OCTAL_VAL (header->header.size) < size)
       {
 	xheader_store ("size", st, NULL);
 	size = 0;
       }
-    if (!OFF_TO_CHARS (size, header->header.size))
+    if (!OFF_TO_CHARS ((off_t)size, header->header.size))
       return NULL;
   }
 
@@ -983,7 +983,7 @@
    file, which may be a preceding long name or long link record.  */
 void
 finish_header (struct tar_stat_info *st,
-	       union block *header, off_t block_ordinal)
+	       union block *header, off64_t block_ordinal)
 {
   /* Note: It is important to do this before the call to write_extended(),
      so that the actual ustar header is printed */
@@ -1022,8 +1022,8 @@
 static enum dump_status
 dump_regular_file (int fd, struct tar_stat_info *st)
 {
-  off_t size_left = st->stat.st_size;
-  off_t block_ordinal;
+  off64_t size_left = st->stat.st_size;
+  off64_t block_ordinal;
   union block *blk;
 
   block_ordinal = current_block_ordinal ();
@@ -1051,7 +1051,7 @@
       if (size_left < bufsize)
 	{
 	  /* Last read -- zero out area beyond.  */
-	  bufsize = size_left;
+	  bufsize = (size_t)size_left;
 	  count = bufsize % BLOCKSIZE;
 	  if (count)
 	    memset (blk->buffer + size_left, 0, BLOCKSIZE - count);
@@ -1062,7 +1062,7 @@
 	{
 	  read_diag_details (st->orig_file_name,
 	                     st->stat.st_size - size_left, bufsize);
-	  pad_archive (size_left);
+	  pad_archive ((off_t)size_left);
 	  return dump_status_short;
 	}
       size_left -= count;
@@ -1080,7 +1080,7 @@
 		 STRINGIFY_BIGINT (size_left, buf)));
 	  if (! ignore_failed_read_option) 
 	    exit_status = TAREXIT_DIFFERS;
-	  pad_archive (size_left - (bufsize - count));
+	  pad_archive ((off_t)size_left - (bufsize - count));
 	  return dump_status_short;
 	}
     }
@@ -1098,7 +1098,7 @@
   if (!is_avoided_name (st->orig_file_name))
     {
       union block *blk = NULL;
-      off_t block_ordinal = current_block_ordinal ();
+      off64_t block_ordinal = current_block_ordinal ();
       st->stat.st_size = 0;	/* force 0 size on dir */
 
       blk = start_header (st);
@@ -1251,7 +1251,11 @@
 static bool
 dump_dir (int fd, struct tar_stat_info *st, int top_level, dev_t parent_device)
 {
+#ifdef _MSC_VER /* replace fdsavedir(FD), fdsavedir(char * dir_name) */
+  char *directory = fdsavedir (st->file_name);
+#else /* !_MSC_VER */
   char *directory = fdsavedir (fd);
+#endif /* _MSC_VER y/n */
   if (!directory)
     {
       savedir_diag (st->orig_file_name);
@@ -1343,7 +1347,7 @@
 {
   struct link const *l = entry;
   uintmax_t num = l->dev ^ l->ino;
-  return num % n_buckets;
+  return (size_t)(num % n_buckets);
 }
 
 /* Compare two links for equality.  */
@@ -1381,7 +1385,7 @@
     {
       struct link lp;
       struct link *duplicate;
-      off_t block_ordinal;
+      off64_t block_ordinal;
       union block *blk;
 
       lp.ino = st->stat.st_ino;
@@ -1482,10 +1486,14 @@
 {
   union block *header;
   char type;
+#ifdef _MSC_VER /* use 64-bit size */
+  off64_t original_size;
+#else /* !_MSC_VER */
   off_t original_size;
+#endif /* _MSC_VER y/n */
   struct timespec original_ctime;
   struct timespec restore_times[2];
-  off_t block_ordinal = -1;
+  off64_t block_ordinal = -1;
   bool is_dir;
 
   if (interactive_option && !confirm ("add", p))
@@ -1557,10 +1565,20 @@
     {
       bool ok;
       int fd = -1;
-      struct stat final_stat;
+      struct_stat final_stat;
 
       if (is_dir || file_dumpable_p (st))
 	{
+#ifdef _MSC_VER /* no attempt to open a DIRECTORY in WIN32 */
+      if(is_dir)
+         goto Do_DIR;
+      type = (win_is_sparse_file(p) ? 'S' : 'N');
+#endif /* _MSC_VER */
+#ifdef DBGV5 /* show adding file of size64 to archive */
+     if ( verbose_option >= DBGV5 ) {
+        fprintf( stdlis, "Archiving [%s] file, %I64u bytes ... (%c)\n", p, st->stat.st_size, type );
+     }
+#endif /* DBGV5 */
 	  fd = open (p,
 		     (O_RDONLY | O_BINARY
 		      | (is_dir ? O_DIRECTORY | O_NONBLOCK : 0)
@@ -1578,6 +1596,9 @@
 	    }
 	}
 
+#ifdef _MSC_VER /* jump vector, for open DIR failing */
+Do_DIR:
+#endif /* _MSC_VER */
       if (is_dir)
 	{
 	  const char *tag_file_name;
@@ -1601,8 +1622,14 @@
       else
 	{
 	  enum dump_status status;
-
-	  if (fd != -1 && sparse_option && ST_IS_SPARSE (st->stat))
+	  /* if (fd != -1 && sparse_option && ST_IS_SPARSE (st->stat)) */
+	  if (fd != -1 && sparse_option && 
+#ifdef _MSC_VER /* can NOT tell if sparse from stat win_drive_supports_sparse( ) && */
+        ( type == 'S' )
+#else
+        ST_IS_SPARSE (st->stat)
+#endif 
+        )
 	    {
 	      status = sparse_dump_file (fd, st);
 	      if (status == dump_status_not_implemented)
@@ -1640,7 +1667,7 @@
 
 	  if ((fd < 0
 	       ? deref_stat (dereference_option, p, &final_stat)
-	       : fstat (fd, &final_stat))
+	       : FDSTAT (fd, &final_stat))
 	      != 0)
 	    {
 	      stat_diag (p);
diff -ur C:\FGCVS\tar\src\delete.c C:\Projects\tar\src\delete.c
--- C:\FGCVS\tar\src\delete.c	Wed Jun 27 15:30:32 2007
+++ C:\Projects\tar\src\delete.c	Fri Sep 12 17:49:51 2008
@@ -34,23 +34,31 @@
 extern union block *current_block;
 extern union block *recent_long_name;
 extern union block *recent_long_link;
-extern off_t records_read;
-extern off_t records_written;
+extern off64_t records_read;
+extern off64_t records_written;
 
 /* The number of records skipped at the start of the archive, when
    passing over members that are not deleted.  */
-off_t records_skipped;
+off64_t records_skipped;
 
 /* Move archive descriptor by COUNT records worth.  If COUNT is
    positive we move forward, else we move negative.  If it's a tape,
    MTIOCTOP had better work.  If it's something else, we try to seek
    on it.  If we can't seek, we lose!  */
+
 static void
-move_archive (off_t count)
+move_archive (off64_t count)
 {
   if (count == 0)
     return;
 
+#ifdef _MSC_VER
+  {
+     extern void win_move_archive (off64_t count);
+     win_move_archive( count );
+     return;
+  }
+#endif /* _MSC_VER */
 #ifdef MTIOCTOP
   {
     struct mtop operation;
@@ -74,9 +82,9 @@
 #endif /* MTIOCTOP */
 
   {
-    off_t position0 = rmtlseek (archive, (off_t) 0, SEEK_CUR);
+    off64_t position0 = rmtlseek (archive, (off64_t) 0, SEEK_CUR);
     off_t increment = record_size * (off_t) count;
-    off_t position = position0 + increment;
+    off64_t position = position0 + increment;
 
     if (increment / count != record_size
 	|| (position < position0) != (increment < 0)
@@ -90,6 +98,7 @@
 
 /* Write out the record which has been filled.  If MOVE_BACK_FLAG,
    backspace to where we started.  */
+
 static void
 write_record (int move_back_flag)
 {
@@ -122,9 +131,9 @@
 }
 
 static void
-write_recent_blocks (union block *h, size_t blocks)
+write_recent_blocks (union block *h, size64_t blocks)
 {
-  size_t i;
+  size64_t i;
   for (i = 0; i < blocks; i++)
     {
       new_record[new_blocks++] = h[i];
@@ -160,9 +169,19 @@
   off_t blocks_to_keep = 0;
   int kept_blocks_in_record;
 
+  acting_as_filter = strcmp (archive_name_array[0], "-") == 0;
+
+#ifdef NEW_DELETE_FUNCTION /* write a NEW achive, without 'deleted' members */
+  if ( !acting_as_filter && windelete_option )
+  {
+      extern void win_delete_archive_members (void);
+      win_delete_archive_members();
+      return;
+  }
+#endif /* NEW_DELETE_FUNCTION */
+
   name_gather ();
   open_archive (ACCESS_UPDATE);
-  acting_as_filter = strcmp (archive_name_array[0], "-") == 0;
 
   do
     {
@@ -292,7 +311,7 @@
 		{
 		flush_file:
 		  set_next_block_after (current_header);
-		  blocks_to_skip = (current_stat_info.stat.st_size
+		  blocks_to_skip = (off_t)(current_stat_info.stat.st_size
 				    + BLOCKSIZE - 1) / BLOCKSIZE;
 		  
 		  while (record_end - current_block <= blocks_to_skip)
@@ -320,7 +339,7 @@
 	  new_record[new_blocks] = *current_header;
 	  new_blocks++;
 	  blocks_to_keep
-	    = (current_stat_info.stat.st_size + BLOCKSIZE - 1) / BLOCKSIZE;
+	    = (off_t)(current_stat_info.stat.st_size + BLOCKSIZE - 1) / BLOCKSIZE;
 	  set_next_block_after (current_header);
 	  if (new_blocks == blocking_factor)
 	    write_record (1);
diff -ur C:\FGCVS\tar\src\extract.c C:\Projects\tar\src\extract.c
--- C:\FGCVS\tar\src\extract.c	Sun Aug 26 10:56:56 2007
+++ C:\Projects\tar\src\extract.c	Tue Sep 08 12:45:44 2009
@@ -138,8 +138,8 @@
    TYPEFLAG specifies the type of the file.  */
 static void
 set_mode (char const *file_name,
-	  struct stat const *stat_info,
-	  struct stat const *cur_info,
+	  struct_stat const *stat_info,
+	  struct_stat const *cur_info,
 	  mode_t invert_permissions, enum permstatus permstatus,
 	  char typeflag)
 {
@@ -173,10 +173,10 @@
 	 INVERT_PERMISSIONS happens to be nonzero only for directories
 	 that we created, so there's no point optimizing this code for
 	 other cases.  */
-      struct stat st;
+      struct_stat st;
       if (! cur_info)
 	{
-	  if (stat (file_name, &st) != 0)
+	  if (FNSTAT (file_name, &st) != 0)
 	    {
 	      stat_error (file_name);
 	      return;
@@ -235,7 +235,7 @@
 static void
 set_stat (char const *file_name,
 	  struct tar_stat_info const *st,
-	  struct stat const *cur_info,
+	  struct_stat const *cur_info,
 	  mode_t invert_permissions, enum permstatus permstatus,
 	  char typeflag)
 {
@@ -260,6 +260,10 @@
 	  ts[1] = st->mtime;
 
 	  if (utimens (file_name, ts) != 0)
+#ifdef _MSC_VER /* fail expected if DIR */
+        /* a FAIL is expected if it is a DIRECTORY! */
+         if ( !st->is_dumpdir )
+#endif   /* _MSC_VER */
 	    utime_error (file_name);
 	  else
 	    {
@@ -362,13 +366,13 @@
    links.  *DIR_STAT_INFO is the status of the directory.  */
 static void
 repair_delayed_set_stat (char const *dir,
-			 struct stat const *dir_stat_info)
+			 struct_stat const *dir_stat_info)
 {
   struct delayed_set_stat *data;
   for (data = delayed_set_stat_head;  data;  data = data->next)
     {
-      struct stat st;
-      if (stat (data->file_name, &st) != 0)
+      struct_stat st;
+      if (FNSTAT (data->file_name, &st) != 0)
 	{
 	  stat_error (data->file_name);
 	  return;
@@ -453,13 +457,14 @@
 
       if (errno == EEXIST)
 	continue;	        /* Directory already exists.  */
+#ifndef _MSC_VER /* diff errno in WIN32 */
       else if ((errno == ENOSYS /* Automounted dirs on Solaris return
 				   this. Reported by Warren Hyde
 				   <Warren.Hyde@motorola.com> */
 	       || ERRNO_IS_EACCES)  /* Turbo C mkdir gives a funny errno.  */
 	       && access (file_name, W_OK) == 0)
 	continue;
-
+#endif /* !_MSC_VER */
       /* Some other error in the mkdir.  We return to the caller.  */
       break;
     }
@@ -470,9 +475,9 @@
 static bool
 file_newer_p (const char *file_name, struct tar_stat_info *tar_stat)
 {
-  struct stat st;
+  struct_stat st;
 
-  if (stat (file_name, &st))
+  if (FNSTAT (file_name, &st))
     {
       stat_warn (file_name);
       /* Be on the safe side: if the file does exist assume it is newer */
@@ -561,8 +566,8 @@
     {
       struct delayed_set_stat *data = delayed_set_stat_head;
       bool skip_this_one = 0;
-      struct stat st;
-      struct stat const *cur_info = 0;
+      struct_stat st;
+      struct_stat const *cur_info = 0;
 
       check_for_renamed_directories |= data->after_links;
 
@@ -577,7 +582,7 @@
       if (check_for_renamed_directories)
 	{
 	  cur_info = &st;
-	  if (stat (data->file_name, &st) != 0)
+	  if (FNSTAT (data->file_name, &st) != 0)
 	    {
 	      stat_error (data->file_name);
 	      skip_this_one = 1;
@@ -594,6 +599,16 @@
       if (! skip_this_one)
 	{
 	  struct tar_stat_info sb;
+#ifdef _MSC_VER // FIX20090908 - ensure memory cleared
+      ZeroMemory(&sb, sizeof(struct tar_stat_info));
+      // FIX20090908 - also SET 'is_dumpdir' if a directory
+      // but is does seem all items that come this way 
+      // through the code _ARE_ directories! But to be SURE
+      if ( _stat64( data->file_name, &sb.stat ) == 0 ) {
+          if ( sb.stat.st_mode & _S_IFDIR )
+              sb.is_dumpdir = 1;
+      }
+#endif
 	  sb.stat.st_mode = data->mode;
 	  sb.stat.st_uid = data->uid;
 	  sb.stat.st_gid = data->gid;
@@ -622,7 +637,7 @@
   /* Save 'root device' to avoid purging mount points. */
   if (one_file_system_option && root_device == 0)
     {
-      struct stat st;
+      struct_stat st;
       char *dir = xgetcwd ();
 
       if (deref_stat (true, dir, &st))
@@ -649,8 +664,8 @@
 	      || old_files_option == DEFAULT_OLD_FILES
 	      || old_files_option == OVERWRITE_OLD_FILES))
 	{
-	  struct stat st;
-	  if (stat (file_name, &st) == 0)
+	  struct_stat st;
+	  if (FNSTAT (file_name, &st) == 0)
 	    {
 	      if (interdir_made)
 		{
@@ -725,7 +740,9 @@
 	}
     }
   fd = open (file_name, openflag, mode);
-
+#ifdef DBGV5 /* extraction - show file creation, and status */
+  win_show_file_creation( file_name, openflag, mode, fd, stdlis, verbose_option );
+#endif // DBGV5
 #endif /* not O_CTG */
 
   return fd;
@@ -735,7 +752,7 @@
 extract_file (char *file_name, int typeflag)
 {
   int fd;
-  off_t size;
+  off64_t size;
   union block *data_block;
   int status;
   size_t count;
@@ -794,7 +811,7 @@
 	written = available_space_after (data_block);
 
 	if (written > size)
-	  written = size;
+	  written = (size_t)size;
 	errno = 0;
 	count = full_write (fd, data_block->buffer, written);
 	size -= written;
@@ -845,7 +862,7 @@
 create_placeholder_file (char *file_name, bool is_symlink, int *interdir_made)
 {
   int fd;
-  struct stat st;
+  struct_stat st;
 
   while ((fd = open (file_name, O_WRONLY | O_CREAT | O_EXCL, 0)) < 0)
     if (! maybe_recoverable (file_name, interdir_made))
@@ -853,7 +870,7 @@
 
   if (fd < 0)
     open_error (file_name);
-  else if (fstat (fd, &st) != 0)
+  else if (FDSTAT (fd, &st) != 0)
     {
       stat_error (file_name);
       close (fd);
@@ -894,7 +911,7 @@
 	    {
 	      h->after_links = 1;
 
-	      if (stat (h->file_name, &st) != 0)
+	      if (FNSTAT (h->file_name, &st) != 0)
 		stat_error (h->file_name);
 	      else
 		{
@@ -923,6 +940,16 @@
   if (! absolute_names_option && contains_dot_dot (link_name))
     return create_placeholder_file (file_name, false, &interdir_made);
 
+#ifdef _MSC_VER /* replace link() with stat() for WIN32 */
+  do
+  {
+      struct_stat st1;
+      if( FNSTAT (link_name, &st1) == 0 )
+         errno = EEXIST;
+
+  } while(0);
+
+#else /* !_MSC_VER */
   do
     {
       struct stat st1, st2;
@@ -958,6 +985,7 @@
       errno = e;
     }
   while (maybe_recoverable (file_name, &interdir_made));
+#endif /* _MSC_VER y/n */
 
   if (!(incremental_option && errno == EEXIST))
     {
@@ -1007,6 +1035,9 @@
 static int
 extract_node (char *file_name, int typeflag)
 {
+#ifdef _MSC_VER /* no extract_node() */
+   return -1;
+#else /* !_MSC_VER */
   int status;
   int interdir_made = 0;
   mode_t mode = current_stat_info.stat.st_mode & ~ current_umask;
@@ -1024,6 +1055,7 @@
     set_stat (file_name, &current_stat_info, NULL, invert_permissions,
 	      ARCHIVED_PERMSTATUS, typeflag);
   return status;
+#endif /* _MSC_VER y/n */
 }
 #endif
 
@@ -1263,7 +1295,7 @@
       for (sources = ds->sources; sources; sources = sources->next)
 	{
 	  char const *source = sources->string;
-	  struct stat st;
+	  struct_stat st;
 
 	  /* Make sure the placeholder file is still there.  If not,
 	     don't create a link, as the placeholder was probably
@@ -1273,6 +1305,7 @@
 	      && st.st_ino == ds->ino
 	      && timespec_cmp (get_stat_mtime (&st), ds->mtime) == 0)
 	    {
+#ifndef _MSC_VER /* remove link() and symlink() */
 	      /* Unlink the placeholder, then create a hard link if possible,
 		 a symbolic link otherwise.  */
 	      if (unlink (source) != 0)
@@ -1287,6 +1320,7 @@
 	      else if (symlink (ds->target, source) != 0)
 		symlink_error (ds->target, source);
 	      else
+#endif /* !_MSC_VER */
 		{
 		  struct tar_stat_info st1;
 		  st1.stat.st_uid = ds->uid;
@@ -1333,6 +1367,12 @@
 bool
 rename_directory (char *src, char *dst)
 {
+#ifdef _MSC_VER /* ensure the destination of a RENAME does NOT contain a SLASH */
+   extern char * win_get_unique_destination( char * dst );
+   dst = win_get_unique_destination(dst); /* find a UNIQUE name, closest to desired */
+   if( verbose_option > 0 )
+      WARN((0, 0, _("Re-naming [%s] to [%s], to allow extract to proceed"), src, dst )); /* show */
+#endif /* _MSC_VER */
   if (rename (src, dst))
     {
       int e = errno;
diff -ur C:\FGCVS\tar\src\incremen.c C:\Projects\tar\src\incremen.c
--- C:\FGCVS\tar\src\incremen.c	Mon Apr 14 14:03:14 2008
+++ C:\Projects\tar\src\incremen.c	Mon Sep 08 15:40:37 2008
@@ -345,7 +345,7 @@
   directory = find_directory (p);
   if (directory)
     {
-      struct stat st;
+      struct_stat st;
       if (deref_stat (dereference_option, p, &st) != 0)
 	stat_diag (name);
       else
@@ -355,7 +355,7 @@
 }
 
 static struct directory *
-procdir (char *name_buffer, struct stat *stat_data,
+procdir (char *name_buffer, struct_stat *stat_data,
 	 dev_t device,
 	 enum children children,
 	 bool verbose,
@@ -582,7 +582,7 @@
   char *name_buffer;		/* directory, `/', and directory member */
   size_t name_buffer_size;	/* allocated size of name_buffer, minus 2 */
   size_t name_length;		/* used length in name_buffer */
-  struct stat stat_data;
+  struct_stat stat_data;
   struct directory *directory;
 
   if (! dirp)
@@ -591,9 +591,14 @@
   name_buffer_size = strlen (dir) + NAME_FIELD_SIZE;
   name_buffer = xmalloc (name_buffer_size + 2);
   strcpy (name_buffer, dir);
+#ifdef _MSC_VER   /* can NOT add a slash to a directory before stat */
+  if (ISSLASH (dir[strlen (dir) - 1]))
+     dir[strlen (dir) - 1] = 0;
+#else /* !_MSC_VER */
   if (! ISSLASH (dir[strlen (dir) - 1]))
     strcat (name_buffer, "/");
   name_length = strlen (name_buffer);
+#endif /* _MSC_VER y/n */
 
   if (deref_stat (dereference_option, name_buffer, &stat_data))
     {
@@ -605,6 +610,11 @@
       free (dirp);
       return NULL;
     }
+#ifdef _MSC_VER   /* can NOT add a slash to a directory before stat */
+  if (! ISSLASH (dir[strlen (dir) - 1]))
+    strcat (name_buffer, "/");
+  name_length = strlen (name_buffer);
+#endif /* _MSC_VER y/n */
 
   directory = procdir (name_buffer, &stat_data, device, NO_CHILDREN, false,
 		       NULL);
@@ -851,7 +861,7 @@
 	      sec = TYPE_MINIMUM (time_t);
 	    }
 	  else
-	    nsec = u;
+	    nsec = (long)u;
 	}
       else
 	{
@@ -905,7 +915,7 @@
 	      nsec = -1;
 	    }
 	  else
-	    nsec = u;
+	    nsec = (long)u;
 	  mtime.tv_sec = sec;
 	  mtime.tv_nsec = nsec;
 	  strp = ebuf;
@@ -925,7 +935,7 @@
 	  dev = (dev_t) -1;
 	}
       else
-	dev = u;
+	dev = (dev_t)u;
       strp = ebuf;
 
       errno = 0;
@@ -940,7 +950,7 @@
 	  ino = (ino_t) -1;
 	}
       else
-	ino = u;
+	ino = (ino_t)u;
       strp = ebuf;
 
       strp++;
@@ -1089,7 +1099,7 @@
     FATAL_ERROR ((0, 0, "%s: %s",
 		  quotearg_colon (listed_incremental_option),
 		  _("Unexpected EOF in snapshot file")));
-  pval->tv_nsec = u;
+  pval->tv_nsec = (long)u;
 }
 
 /* Read incremental snapshot format 2 */
@@ -1116,17 +1126,17 @@
       if (read_num (listed_incremental_stream, 1, &u))
 	return; /* Normal return */
 
-      nfs = u;
+      nfs = (char)u;
 
       read_timespec (listed_incremental_stream, &mtime);
 
       if (read_num (listed_incremental_stream, TYPE_MAXIMUM (dev_t), &u))
 	break;
-      dev = u;
+      dev = (dev_t)u;
 
       if (read_num (listed_incremental_stream, TYPE_MAXIMUM (ino_t), &u))
 	break;
-      ino = u;
+      ino = (ino_t)u;
 
       if (read_obstack (listed_incremental_stream, &stk, &s))
 	break;
@@ -1149,6 +1159,10 @@
 		_("Unexpected EOF in snapshot file")));
 }
 
+#ifdef _MSC_VER /* avoid an error when the file does not yet exist */
+int new_list_file = 0;
+#endif /* _MSC_VER
+
 /* Read incremental snapshot file (directory file).
    If the file has older incremental version, make sure that it is processed
    correctly and that tar will use the most conservative backup method among
@@ -1161,7 +1175,10 @@
   int fd;
   char *buf = 0;
   size_t bufsize;
-
+#ifdef _MSC_VER /* avoid an error when the file does not yet exist */
+  static struct_stat _s_sb;
+  new_list_file = FNSTAT(listed_incremental_option, &_s_sb);
+#endif /* _MSC_VER */
   /* Open the file for both read and write.  That way, we can write
      it later without having to reopen it, and don't have to worry if
      we chdir in the meantime.  */
@@ -1180,6 +1197,11 @@
       return;
     }
 
+#ifdef _MSC_VER /* avoid an error when the file does not yet exist */
+  if( new_list_file == -1 )
+      goto Done_READ;
+#endif /* _MSC_VER */
+
   if (0 < getline (&buf, &bufsize, listed_incremental_stream))
     {
       char *ebuf;
@@ -1203,7 +1225,7 @@
 	{
 	case 0:
 	case 1:
-	  read_incr_db_01 (incremental_version, buf);
+	  read_incr_db_01 ((int)incremental_version, buf);
 	  break;
 
 	case TAR_INCREMENTAL_VERSION:
@@ -1217,6 +1239,9 @@
 
     }
 
+#ifdef _MSC_VER /* avoid an error when the file does not yet exist */
+Done_READ:
+#endif /* _MSC_VER */
   if (ferror (listed_incremental_stream))
     read_error (listed_incremental_option);
   if (buf)
@@ -1307,15 +1332,15 @@
 static void
 get_gnu_dumpdir (struct tar_stat_info *stat_info)
 {
-  size_t size;
-  size_t copied;
+  size64_t size;
+  size64_t copied;
   union block *data_block;
   char *to;
   char *archive_dir;
 
   size = stat_info->stat.st_size;
 
-  archive_dir = xmalloc (size);
+  archive_dir = xmalloc ((size_t)size);
   to = archive_dir;
 
   set_next_block_after (current_header);
@@ -1330,7 +1355,7 @@
       copied = available_space_after (data_block);
       if (copied > size)
 	copied = size;
-      memcpy (to, data_block->buffer, copied);
+      memcpy (to, data_block->buffer, (size_t)copied);
       to += copied;
       set_next_block_after ((union block *)
 			    (data_block->buffer + copied - 1));
@@ -1529,7 +1554,7 @@
   for (cur = current_dir; *cur; cur += strlen (cur) + 1)
     {
       const char *entry;
-      struct stat st;
+      struct_stat st;
       if (p)
 	free (p);
       p = new_name (directory_name, cur);
diff -ur C:\FGCVS\tar\src\list.c C:\Projects\tar\src\list.c
--- C:\FGCVS\tar\src\list.c	Mon Oct 29 18:53:06 2007
+++ C:\Projects\tar\src\list.c	Sat Sep 13 13:10:12 2008
@@ -19,20 +19,23 @@
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
 
+#include <config.h>  /* just added TEMPORARILY for a good reason ;=)) */
 #include <system.h>
 #include <inttostr.h>
 #include <quotearg.h>
 
 #include "common.h"
 
+#ifndef max
 #define max(a, b) ((a) < (b) ? (b) : (a))
+#endif /* !max */
 
 union block *current_header;	/* points to current archive header */
 enum archive_format current_format; /* recognized format */
 union block *recent_long_name;	/* recent long name header and contents */
 union block *recent_long_link;	/* likewise, for long link */
-size_t recent_long_name_blocks;	/* number of blocks in recent_long_name */
-size_t recent_long_link_blocks;	/* likewise, for long link */
+size64_t recent_long_name_blocks;	/* number of blocks in recent_long_name */
+size64_t recent_long_link_blocks;	/* likewise, for long link */
 
 static uintmax_t from_header (const char *, size_t, const char *,
 			      uintmax_t, uintmax_t, bool, bool);
@@ -70,7 +73,11 @@
 
   base64_init ();
   name_gather ();
-
+#ifdef DBGV5
+  if ( verbose_option >= DBGV5 ) {
+     fprintf(stdlis, "Openning file [%s] for READ ...\n", archive_name_array[0] );
+  }
+#endif /* DBGV5 */
   open_archive (ACCESS_READ);
   do
     {
@@ -102,6 +109,17 @@
 		      OLDER_TAR_STAT_TIME (current_stat_info, m)))
 	      || excluded_name (current_stat_info.file_name))
 	    {
+#ifdef DBGV5
+          /* this is being excluded, but still show it for debug */
+         if( verbose_option >= DBGV5 )
+         {
+            off64_t block_ordinal = current_block_ordinal ();
+            decode_header (current_header,
+				    &current_stat_info, &current_format, 0);
+            fprintf (stdlis, "v5: ");  /* start output with 'v5: ' ... */
+            print_header (&current_stat_info, block_ordinal);
+         }
+#endif /* DBGV5 */
 	      switch (current_header->header.typeflag)
 		{
 		case GNUTYPE_VOLHDR:
@@ -172,7 +190,7 @@
 	      if (block_number_option)
 		{
 		  char buf[UINTMAX_STRSIZE_BOUND];
-		  off_t block_ordinal = current_block_ordinal ();
+		  off64_t block_ordinal = current_block_ordinal ();
 		  block_ordinal -= recent_long_name_blocks;
 		  block_ordinal -= recent_long_link_blocks;
 		  fprintf (stdlis, _("block %s: "),
@@ -203,7 +221,7 @@
 void
 list_archive (void)
 {
-  off_t block_ordinal = current_block_ordinal ();
+  off64_t block_ordinal = current_block_ordinal ();
   /* Print the header block.  */
 
   decode_header (current_header, &current_stat_info, &current_format, 0);
@@ -270,7 +288,7 @@
   if (parsed_sum == (uintmax_t) -1)
     return HEADER_FAILURE;
 
-  recorded_sum = parsed_sum;
+  recorded_sum = (int)parsed_sum;
 
   if (unsigned_sum != recorded_sum && signed_sum != recorded_sum)
     return HEADER_FAILURE;
@@ -298,18 +316,30 @@
   union block *header_copy;
   char *bp;
   union block *data_block;
-  size_t size, written;
+  size64_t size, written;
   union block *next_long_name = 0;
   union block *next_long_link = 0;
-  size_t next_long_name_blocks = 0;
-  size_t next_long_link_blocks = 0;
+  size64_t next_long_name_blocks = 0;
+  size64_t next_long_link_blocks = 0;
 
   while (1)
     {
       enum read_header status;
 
       header = find_next_block ();
+#ifdef DBGV5
+      if (verbose_option >= DBGV5)
+      {
+         if( current_header != header )
+         {
+            fprintf( stdlis, "read_header_primitive: set 'current_header' to %#x ...(raw=%s)\n",
+               header,
+               (raw_extended_headers ? "Yes" : "No"));
+         }
+      }
+#endif /* DBGV5 */
       current_header = header;
+
       if (!header)
 	return HEADER_END_OF_FILE;
 
@@ -334,16 +364,19 @@
 	  else if (header->header.typeflag == GNUTYPE_LONGNAME
 		   || header->header.typeflag == GNUTYPE_LONGLINK)
 	    {
-	      size_t name_size = info->stat.st_size;
-	      size_t n = name_size % BLOCKSIZE;
+	      size64_t name_size = info->stat.st_size;
+	      size_t n = (size_t)(name_size % BLOCKSIZE);
 	      size = name_size + BLOCKSIZE;
 	      if (n)
 		size += BLOCKSIZE - n;
 
 	      if (name_size != info->stat.st_size || size < name_size)
 		xalloc_die ();
-
-	      header_copy = xmalloc (size + 1);
+#ifdef _MSC_VER /* in WIN32 can NOT allocate more than UINT_MAX */
+         if( size > UINT_MAX )
+      		too_large_for_win32_die ();
+#endif /* _MSC_VER */
+	      header_copy = xmalloc ((size_t)(size + 1));
 
 	      if (header->header.typeflag == GNUTYPE_LONGNAME)
 		{
@@ -376,7 +409,11 @@
 		  if (written > size)
 		    written = size;
 
-		  memcpy (bp, data_block->buffer, written);
+#ifdef _MSC_VER /* in WIN32 can NOT memcpy more than UINT_MAX */
+         if( written > UINT_MAX )
+      		too_large_for_win32_die ();
+#endif /* _MSC_VER */
+		  memcpy (bp, data_block->buffer, (size_t)written);
 		  bp += written;
 		  set_next_block_after ((union block *)
 					(data_block->buffer + written - 1));
@@ -386,14 +423,24 @@
 	    }
 	  else if (header->header.typeflag == XHDTYPE
 		   || header->header.typeflag == SOLARIS_XHDTYPE)
-	    xheader_read (&info->xhdr, header,
-			  OFF_FROM_HEADER (header->header.size));
+     {
+        size64_t len = OFF_FROM_HEADER (header->header.size);
+#if (defined(_MSC_VER) && defined(WIN32)) /* can NOT read more that 32-bits worth */
+         if( len > UINT_MAX )
+      		too_large_for_win32_die ();
+#endif /* (defined(_MSC_VER) && defined(WIN32)) */
+	    xheader_read (&info->xhdr, header, (size_t)len);
+     }
 	  else if (header->header.typeflag == XGLTYPE)
 	    {
 	      struct xheader xhdr;
+        size64_t len = OFF_FROM_HEADER (header->header.size);
+#if (defined(_MSC_VER) && defined(WIN32)) /* can NOT read more that 32-bits worth */
+         if( len > UINT_MAX )
+      		too_large_for_win32_die ();
+#endif /* (defined(_MSC_VER) && defined(WIN32)) */
 	      memset (&xhdr, 0, sizeof xhdr);
-	      xheader_read (&xhdr, header,
-			    OFF_FROM_HEADER (header->header.size));
+	      xheader_read (&xhdr, header, (size_t)len );
 	      xheader_decode_global (&xhdr);
 	      xheader_destroy (&xhdr);
 	    }
@@ -410,7 +457,7 @@
 	  if (recent_long_name)
 	    free (recent_long_name);
 
-	  if (next_long_name)
+     if (next_long_name)
 	    {
 	      name = next_long_name->buffer + BLOCKSIZE;
 	      recent_long_name = next_long_name;
@@ -853,7 +900,7 @@
 gid_t
 gid_from_header (const char *p, size_t s)
 {
-  return from_header (p, s, "gid_t",
+  return (gid_t)from_header (p, s, "gid_t",
 		      - (uintmax_t) TYPE_MINIMUM (gid_t),
 		      (uintmax_t) TYPE_MAXIMUM (gid_t),
 		      false, false);
@@ -862,7 +909,7 @@
 major_t
 major_from_header (const char *p, size_t s)
 {
-  return from_header (p, s, "major_t",
+  return (major_t)from_header (p, s, "major_t",
 		      - (uintmax_t) TYPE_MINIMUM (major_t),
 		      (uintmax_t) TYPE_MAXIMUM (major_t), false, false);
 }
@@ -870,7 +917,7 @@
 minor_t
 minor_from_header (const char *p, size_t s)
 {
-  return from_header (p, s, "minor_t",
+  return (minor_t)from_header (p, s, "minor_t",
 		      - (uintmax_t) TYPE_MINIMUM (minor_t),
 		      (uintmax_t) TYPE_MAXIMUM (minor_t), false, false);
 }
@@ -879,7 +926,7 @@
 mode_from_header (const char *p, size_t s)
 {
   /* Do not complain about unrecognized mode bits.  */
-  unsigned u = from_header (p, s, "mode_t",
+  unsigned u = (unsigned int)from_header (p, s, "mode_t",
 			    - (uintmax_t) TYPE_MINIMUM (mode_t),
 			    TYPE_MAXIMUM (uintmax_t), false, false);
   return ((u & TSUID ? S_ISUID : 0)
@@ -896,20 +943,20 @@
 	  | (u & TOEXEC ? S_IXOTH : 0));
 }
 
-off_t
+off64_t
 off_from_header (const char *p, size_t s)
 {
   /* Negative offsets are not allowed in tar files, so invoke
      from_header with minimum value 0, not TYPE_MINIMUM (off_t).  */
-  return from_header (p, s, "off_t", (uintmax_t) 0,
-		      (uintmax_t) TYPE_MAXIMUM (off_t), false, false);
+  return from_header (p, s, "off64_t", (uintmax_t) 0,
+		      (uintmax_t) TYPE_MAXIMUM (off64_t), false, false);
 }
 
-size_t
+size64_t
 size_from_header (const char *p, size_t s)
 {
-  return from_header (p, s, "size_t", (uintmax_t) 0,
-		      (uintmax_t) TYPE_MAXIMUM (size_t), false, false);
+  return from_header (p, s, "size64_t", (uintmax_t) 0,
+		      (uintmax_t) TYPE_MAXIMUM (size64_t), false, false);
 }
 
 time_t
@@ -923,7 +970,7 @@
 uid_t
 uid_from_header (const char *p, size_t s)
 {
-  return from_header (p, s, "uid_t",
+  return (uid_t)from_header (p, s, "uid_t",
 		      - (uintmax_t) TYPE_MINIMUM (uid_t),
 		      (uintmax_t) TYPE_MAXIMUM (uid_t), false, false);
 }
@@ -1020,7 +1067,7 @@
 static int datewidth = sizeof "YYYY-MM-DD HH:MM" - 1;
 
 void
-print_header (struct tar_stat_info *st, off_t block_ordinal)
+print_header (struct tar_stat_info *st, off64_t block_ordinal)
 {
   char modes[11];
   char const *time_stamp;
@@ -1290,7 +1337,7 @@
 
 /* Skip over SIZE bytes of data in blocks in the archive.  */
 void
-skip_file (off_t size)
+skip_file (off64_t size)
 {
   union block *x;
 
@@ -1298,7 +1345,7 @@
 
   if (seekable_archive)
     {
-      off_t nblk = seek_archive (size);
+      off64_t nblk = seek_archive (size);
       if (nblk >= 0)
 	size -= nblk * BLOCKSIZE;
       else
diff -ur C:\FGCVS\tar\src\misc.c C:\Projects\tar\src\misc.c
--- C:\FGCVS\tar\src\misc.c	Wed Jun 27 15:30:32 2007
+++ C:\Projects\tar\src\misc.c	Tue Sep 09 13:22:58 2008
@@ -341,11 +341,26 @@
       if (unlink (file_name) == 0)
 	return 1;
 
+#ifdef _MSC_VER /* deal with unlink() failed in WIN32 */
+      /* WIN32 specific - unlink FAILS on READ ONLY files */
+      if ( errno == ENOENT ) /* file or path is not found */
+         return 1;   /* or the path specified a directory */
+      if ( errno == EACCES ) /* read-only file */
+      {
+         if( _chmod( file_name, (_S_IREAD | _S_IWRITE) ) == 0 )
+         {
+            /* now try to delete it ...*/
+            if (unlink (file_name) == 0)
+               return 1;
+         }
+      }
+#else /* !_MSC_VER */
       /* POSIX 1003.1-2001 requires EPERM when attempting to unlink a
 	 directory without appropriate privileges, but many Linux
 	 kernels return the more-sensible EISDIR.  */
       if (errno != EPERM && errno != EISDIR)
 	return 0;
+#endif /* _MSC_VER y/n */
     }
 
   if (safer_rmdir (file_name) == 0)
@@ -415,14 +430,14 @@
 bool
 maybe_backup_file (const char *file_name, bool this_is_the_archive)
 {
-  struct stat file_stat;
+  struct_stat file_stat;
 
   /* Check if we really need to backup the file.  */
 
   if (this_is_the_archive && _remdev (file_name))
     return true;
 
-  if (stat (file_name, &file_stat))
+  if (FNSTAT (file_name, &file_stat))
     {
       if (errno == ENOENT)
 	return true;
@@ -493,11 +508,19 @@
 }
 
 /* Depending on DEREF, apply either stat or lstat to (NAME, BUF).  */
+#ifdef _MSC_VER
+int
+deref_stat (bool deref, char const *name, struct_stat *buf)
+{
+  return FNSTAT (name, buf);
+}
+#else /* !_MSC_VER */
 int
 deref_stat (bool deref, char const *name, struct stat *buf)
 {
   return deref ? stat (name, buf) : lstat (name, buf);
 }
+#endif /* _MSC_VER */
 
 /* Set FD's (i.e., FILE's) access time to TIMESPEC[0].  If that's not
    possible to do by itself, set its access and data modification
@@ -651,7 +674,7 @@
 }
 
 void
-read_diag_details (char const *name, off_t offset, size_t size)
+read_diag_details (char const *name, off64_t offset, size64_t size)
 {
   if (ignore_failed_read_option)
     read_warn_details (name, offset, size);
@@ -678,7 +701,7 @@
 }
 
 void
-seek_diag_details (char const *name, off_t offset)
+seek_diag_details (char const *name, off64_t offset)
 {
   if (ignore_failed_read_option)
     seek_warn_details (name, offset);
@@ -706,18 +729,27 @@
 pid_t
 xfork (void)
 {
+#ifdef _MSC_VER /* no fork() in WIN32 */
+   call_arg_fatal ("fork", _("child process - not in WIN32"));
+   return -1;
+#else /* !_MSC_VER */
   pid_t p = fork ();
   if (p == (pid_t) -1)
     call_arg_fatal ("fork", _("child process"));
   return p;
+#endif /* _MSC_VER y/n */
 }
 
 /* Create a pipe, aborting if unsuccessful.  */
 void
 xpipe (int fd[2])
 {
+#ifdef _MSC_VER /* no pipe() in WIN32 */
+   call_arg_fatal ("pipe", _("interprocess channel not in WIN32"));
+#else /* !_MSC_VER */
   if (pipe (fd) < 0)
     call_arg_fatal ("pipe", _("interprocess channel"));
+#endif /* _MSC_VER y/n */
 }
 
 /* Return PTR, aligned upward to the next multiple of ALIGNMENT.
diff -ur C:\FGCVS\tar\src\names.c C:\Projects\tar\src\names.c
--- C:\FGCVS\tar\src\names.c	Wed Feb 20 15:16:52 2008
+++ C:\Projects\tar\src\names.c	Fri Sep 12 18:13:21 2008
@@ -24,6 +24,82 @@
 #include <quotearg.h>
 
 #include "common.h"
+
+#ifdef _MSC_VER   /* struct passwd and group declared */
+/* =================================================================
+   some fill ins for windows
+   ================================================================= */
+
+#ifndef passwd
+/* The passwd structure.  */
+struct passwd
+{
+  char *pw_name;		/* Username.  */
+  char *pw_passwd;		/* Password.  */
+  uid_t pw_uid;		/* User ID.  */
+  gid_t pw_gid;		/* Group ID.  */
+  char *pw_gecos;		/* Real name.  */
+  char *pw_dir;			/* Home directory.  */
+  char *pw_shell;		/* Shell program.  */
+};
+
+#endif /* passwd */
+
+#ifndef group
+/* The group structure.	 */
+struct group
+  {
+    char *gr_name;		/* Group name.	*/
+    char *gr_passwd;		/* Password.	*/
+    gid_t gr_gid;		/* Group ID.	*/
+    char **gr_mem;		/* Member list.	*/
+  };
+
+#endif /* group */
+static int
+dbg_chk( void )
+{
+   int i;
+   i = 0;
+   return i;
+}
+
+static int _s_done_pwd = 0;
+static int _s_done_grp = 0;
+static struct passwd pwd;
+static struct group  grp;
+
+static struct passwd *getpwuid (uid_t uid)
+{
+   dbg_chk();
+   if( !_s_done_pwd )
+   {
+      pwd.pw_name = "user";
+      _s_done_pwd = 1;
+   }
+   return &pwd;
+}
+static struct group *getgrgid (gid_t gid)
+{ 
+   dbg_chk();
+   if( !_s_done_grp )
+   {
+      grp.gr_name = "group";
+      _s_done_grp = 1;
+   }
+   return &grp;
+}
+static struct passwd *getpwnam (char const *uname)
+{
+   dbg_chk();
+   return 0;
+}
+static struct group *getgrnam (char const * gname)
+{ 
+   dbg_chk();
+   return 0;
+}
+#endif /* _MSC_VER */
 
 /* User and group names.  */
 
@@ -229,6 +305,205 @@
     }
 }
 
+#ifdef _MSC_VER   /* expand wild card names */
+/* ===========================================================
+   windows command shell does NOT expand wild card names,
+   so they must be expanded here, to add to the array of names
+   =========================================================== */
+#define DEBUG_ADD_NAMES  /* to add debug output of names added */
+
+static int find_no_wild_one = 0;
+/* this should SKIP the folder name, if any ... but, not yet ... */
+static int has_wild( const char * name )
+{
+   int   iret = 0;
+   int   c;
+   size_t len = strlen(name);
+   size_t i;
+   if( find_no_wild_one ) {
+      find_no_wild_one = 0;
+      return iret;
+   }
+   for( i = 0; i < len; i++ )
+   {
+      c = name[i];
+      if(( c == '*' )||( c == '?' ))
+      {
+         iret = 1;
+         break;
+      }
+   }
+   return iret;
+}
+
+static int not_dot_nor_double_dot( const char * name )
+{
+   int iret = 1;
+   if( name[0] == '.' )
+   {
+      if( name[1] == 0 )
+         iret = 0;
+      else if( name[1] == '.' )
+      {
+         if(name[2] == 0)
+            iret = 0;
+      }
+   }
+   return iret;
+}
+
+/* seem this must be done to avoid say '\t' becoming a TAB character,
+   luckily most windows functions accept either ... */
+void path_2_unix(char * name)
+{
+   size_t i;
+   size_t len = strlen(name);
+   for( i = 0; i < len; i++ )
+   {
+      if( name[i] == '\\' )   /* if BACKSLASH            */
+         name[i] = '/';       /* change to FORWARD slash */
+   }
+}
+
+/* simple structure into which a full path can be split */
+typedef struct tagSPLITTING {
+   char path[_MAX_DIR];
+   char drive[_MAX_DRIVE];
+   char dir[_MAX_DIR];
+   char fname[_MAX_FNAME];
+   char ext[_MAX_EXT];
+   char mask[_MAX_FNAME];
+}SPLITTING, * PSPLITTING;
+
+static int tar_includesubdirs = 1;
+
+static int tar_filesfound = 0;
+static int tar_filesadded = 0;
+static int tar_dirssearched = 0;
+static int tar_dirsfound = 0;
+
+/* ================================================================
+   A test on unbuntu revealed a '*' on the command line will
+   produce a list of files plus directories, in ALPHABETIC order
+   to the program, while a '.' will not.
+
+   So to ADD directories also ... but, at present,
+   that invokes some openat() code,
+   which does NOT (yet) work under windows
+   so it is OFF until this all fixed, if desired.
+   For the present this tar will NOT work with a directory input!!!
+
+   As a temporary work around, expand the directories here.
+   TODO: THIS MUST BE FIXED!
+   The follwoing should be the reverse to emulate unix, and
+   a SORT should be added to fully emulate it!
+   =============================================================== */
+static int tar_adddirectories    = 1;
+static int tar_expanddirectories = 0;
+
+static int expand_wild( const char * file, int matching_flags )
+{
+   PSPLITTING psp;
+   DIR * pdir;
+   struct dirent * dp;
+   int status = 0;
+   char * next_name;
+   size_t len = strlen(file);
+   psp = (PSPLITTING)xmalloc(sizeof(SPLITTING));
+   if( !psp ) {
+      fprintf( stderr, "CRITICAL ERROR: MEMORY FAILED! ABORTING\n" );
+      exit(TAREXIT_FAILURE);
+   }
+   /* wow - all this hokus pokus is to NOT find 'wild', in something
+      like '*.pm' ... this should be with the --wildcards parameter
+      Add it as *.pm, as is */
+   if( (len > 1) && ( file[0] == '\'' ) && ( file[len-1] == '\'' ))
+   {
+      /* file is cased in single quotes! */
+      strncpy( psp->path, &file[1], len - 2 );  /* get without quotes */
+      psp->path[len - 2] = 0; /* and zero terminate */
+      next_name = xstrdup(psp->path);
+      path_2_unix(next_name); 
+      tar_filesadded++;
+      find_no_wild_one = 1;   /* do NOT find wild in this */
+      name_add_name( next_name, matching_flags );
+      free(psp);  /* toss the memory */
+      return status;
+   }
+   _splitpath(file, psp->drive, psp->dir, psp->fname, psp->ext);
+   strcpy( psp->path, psp->drive );
+   strcat( psp->path, psp->dir );
+   if( psp->path[0] == 0 )
+      strcpy( psp->path, "." );
+   strcpy( psp->mask, psp->fname );
+   strcat( psp->mask, psp->ext );
+   /* IFF it is the often used star.star, (*.*), then
+      this match ALL FILES in windows, so convert to
+      single asterick, '*' for fnmatch() to work ... 
+      Specifically '*.*' would MATCH 'Changes' or 'LICENSE', in windows!!!
+      while the present (internal) fnmatch would FAIL this test
+      not finding the '.'!!!
+    */
+   if( strcmp(psp->mask, "*.*") == 0 )
+      strcpy( psp->mask, "*" );
+
+   pdir = opendir( psp->path );
+   if( pdir )
+   {
+      while(( dp = readdir(pdir) ) != 0 )
+      {
+         /* Skip "." and ".." (some NFS filesystems' directories lack them). */
+         if ( not_dot_nor_double_dot( dp->d_name ) )
+         {
+            strcpy( psp->path, psp->drive );
+            strcat( psp->path, psp->dir );
+            strcat( psp->path, dp->d_name );
+            if ( dp->d_type == DT_DIR )
+            {
+               tar_dirsfound++;  /* direcotry entry */
+               /* seems no option to EXCLUDE directories!!! */
+               if( tar_includesubdirs )
+               {
+                  tar_dirssearched++;
+                  if( tar_adddirectories ) {
+                     next_name = xstrdup(psp->path);
+                     path_2_unix(next_name); 
+                     name_add_name( next_name, matching_flags );
+                  }
+                  if( tar_expanddirectories ) {
+                     strcat( psp->path, "\\" );
+                     strcat( psp->path, psp->fname );
+                     strcat( psp->path, psp->ext );
+                     status |= expand_wild (psp->path, matching_flags);
+                  }
+               }
+            }
+            else
+            {
+               tar_filesfound++; /* file entry */
+               {
+                  if ( fnmatch( psp->mask, dp->d_name, FNM_CASEFOLD | FNM_NOESCAPE ) != FNM_NOMATCH )
+                  {
+                     next_name = xstrdup(psp->path);
+                     /* seems this must be done to avoid \t becoming a TAB! */
+                     path_2_unix(next_name); 
+                     tar_filesadded++;
+                     name_add_name( next_name, matching_flags );
+                  }
+               }
+            }  /* directory or file entry */
+         }  /* skip '.' and '..' */
+      }
+      closedir(pdir);
+   } else {
+      status = 2;
+   }
+   free(psp);  /* toss the memory */
+   return status;
+}
+
+#endif /* _MSC_VER */
+
 /* Add to name_array the file NAME with fnmatch options MATCHING_FLAGS */
 void
 name_add_name (const char *name, int matching_flags)
@@ -236,6 +511,13 @@
   static int prev_flags = 0; /* FIXME: Or EXCLUDE_ANCHORED? */
   struct name_elt *ep;
 
+#ifdef _MSC_VER /* expand wild cards in file names */
+   if( has_wild(name) ) {
+      expand_wild(name, matching_flags);
+      return;
+   }
+#endif /* _MSC_VER */
+
   check_name_alloc ();
   ep = &name_array[names++];
   if (prev_flags != matching_flags)
@@ -248,6 +530,9 @@
     }
   ep->type = NELT_NAME;
   ep->v.name = name;
+#if   (defined(_MSC_VER) && !defined(NDEBUG) && defined(DEBUG_ADD_NAMES))
+  printf("Added %d: [%s]\n", (names - 1), name ); /* DEBUG OUTPUT ONLY */
+#endif /* DEBUG OUTPUT ONLY */
 }
 
 /* Add to name_array a chdir request for the directory NAME */
@@ -531,7 +816,7 @@
 	  chdir_do (cursor->change_dir);
 
 	  /* We got a match.  */
-	  return ISFOUND (cursor);
+	  return (bool)(ISFOUND (cursor));
 	}
 
       /* Filename from archive not found in namelist.  If we have the whole
@@ -722,7 +1007,7 @@
 static int
 compare_names (struct name const *n1, struct name const *n2)
 {
-  int found_diff = WASFOUND(n2) - WASFOUND(n1);
+  int found_diff = (int)(WASFOUND(n2) - WASFOUND(n1));
   return found_diff ? found_diff : strcmp (n1->name, n2->name);
 }
 
@@ -797,7 +1082,7 @@
   struct name *name;
   struct name *next_name;
   int num_names;
-  struct stat statbuf;
+  struct_stat statbuf;
 
   name_gather ();
 
@@ -913,6 +1198,18 @@
     name->found_count = 0;
 }
 
+#ifdef _MSC_VER
+int
+name_list_count (void)
+{
+  struct name *name;
+  int count = 0;
+  for (name = namelist; name; name = name->next)
+     count++;
+  return count;
+}
+#endif /* _MSC_VER */
+
 /* Yield a newly allocated file name consisting of FILE_NAME concatenated to
    NAME, with an intervening slash if FILE_NAME does not already end in one. */
 char *
@@ -958,7 +1255,7 @@
 static void
 register_individual_file (char const *name)
 {
-  struct stat st;
+  struct_stat st;
 
   if (deref_stat (dereference_option, name, &st) != 0)
     return; /* Will be complained about later */
diff -ur C:\FGCVS\tar\src\sparse.c C:\Projects\tar\src\sparse.c
--- C:\FGCVS\tar\src\sparse.c	Wed Jun 27 15:30:32 2007
+++ C:\Projects\tar\src\sparse.c	Sat Sep 13 12:02:47 2008
@@ -49,9 +49,9 @@
 {
   int fd;                           /* File descriptor */
   bool seekable;                    /* Is fd seekable? */
-  off_t offset;                     /* Current offset in fd if seekable==false.
+  off64_t offset;                     /* Current offset in fd if seekable==false.
 				       Otherwise unused */
-  off_t dumped_size;                /* Number of bytes actually written
+  off64_t dumped_size;                /* Number of bytes actually written
 				       to the archive */
   struct tar_stat_info *stat_info;  /* Information about the file */
   struct tar_sparse_optab const *optab; /* Operation table */
@@ -62,7 +62,7 @@
 /* Dump zeros to file->fd until offset is reached. It is used instead of
    lseek if the output file is not seekable */
 static bool
-dump_zeros (struct tar_sparse_file *file, off_t offset)
+dump_zeros (struct tar_sparse_file *file, off64_t offset)
 {
   static char const zero_buf[BLOCKSIZE];
 
@@ -74,7 +74,7 @@
 
   while (file->offset < offset)
     {
-      size_t size = (BLOCKSIZE < offset - file->offset
+      size_t size = (size_t)(BLOCKSIZE < offset - file->offset
 		     ? BLOCKSIZE
 		     : offset - file->offset);
       ssize_t wrbytes;
@@ -173,10 +173,10 @@
 
 
 static bool
-lseek_or_error (struct tar_sparse_file *file, off_t offset)
+lseek_or_error (struct tar_sparse_file *file, off64_t offset)
 {
   if (file->seekable
-      ? lseek (file->fd, offset, SEEK_SET) < 0
+      ? FDSEEK (file->fd, offset, SEEK_SET) < 0
       : ! dump_zeros (file, offset))
     {
       seek_diag_details (file->stat_info->orig_file_name, offset);
@@ -201,10 +201,17 @@
 sparse_add_map (struct tar_stat_info *st, struct sp_array const *sp)
 {
   struct sp_array *sparse_map = st->sparse_map;
-  size_t avail = st->sparse_map_avail;
+  size64_t avail = st->sparse_map_avail;
   if (avail == st->sparse_map_size)
+  {
+     size_t alloc = (size_t)avail;
+#ifdef _MSC_VER /* can not allocate more than 32-bits */
+     if( avail > UINT_MAX )
+        too_large_for_win32_die ();
+#endif /* _MSC_VER */
     st->sparse_map = sparse_map =
-      x2nrealloc (sparse_map, &st->sparse_map_size, sizeof *sparse_map);
+      x2nrealloc (sparse_map, &alloc, sizeof *sparse_map);
+  }
   sparse_map[avail] = *sp;
   st->sparse_map_avail = avail + 1;
 }
@@ -217,7 +224,7 @@
   int fd = file->fd;
   char buffer[BLOCKSIZE];
   size_t count;
-  off_t offset = 0;
+  off64_t offset = 0; /* this can be a BIG file ... ensure 64-bits */
   struct sp_array sp = {0, 0};
 
   if (!lseek_or_error (file, 0))
@@ -299,14 +306,14 @@
 sparse_dump_region (struct tar_sparse_file *file, size_t i)
 {
   union block *blk;
-  off_t bytes_left = file->stat_info->sparse_map[i].numbytes;
+  off64_t bytes_left = file->stat_info->sparse_map[i].numbytes;
 
   if (!lseek_or_error (file, file->stat_info->sparse_map[i].offset))
     return false;
 
   while (bytes_left > 0)
     {
-      size_t bufsize = (bytes_left > BLOCKSIZE) ? BLOCKSIZE : bytes_left;
+      size_t bufsize = (size_t)((bytes_left > BLOCKSIZE) ? BLOCKSIZE : bytes_left);
       size_t bytes_read;
 
       blk = find_next_block ();
@@ -334,7 +341,7 @@
 static bool
 sparse_extract_region (struct tar_sparse_file *file, size_t i)
 {
-  size_t write_size;
+  size64_t write_size;
 
   if (!lseek_or_error (file, file->stat_info->sparse_map[i].offset))
     return false;
@@ -350,7 +357,7 @@
   else while (write_size > 0)
     {
       size_t count;
-      size_t wrbytes = (write_size > BLOCKSIZE) ? BLOCKSIZE : write_size;
+      size_t wrbytes = (size_t)((write_size > BLOCKSIZE) ? BLOCKSIZE : write_size);
       union block *blk = find_next_block ();
       if (!blk)
 	{
@@ -405,7 +412,7 @@
 	}
     }
 
-  pad_archive (file.stat_info->archive_file_size - file.dumped_size);
+  pad_archive ((size_t)(file.stat_info->archive_file_size - file.dumped_size));
   return (tar_sparse_done (&file) && rc) ? dump_status_ok : dump_status_short;
 }
 
@@ -432,7 +439,7 @@
 }
 
 enum dump_status
-sparse_extract_file (int fd, struct tar_stat_info *st, off_t *size)
+sparse_extract_file (int fd, struct tar_stat_info *st, off64_t *size)
 {
   bool rc = true;
   struct tar_sparse_file file;
@@ -441,9 +448,12 @@
   if (!tar_sparse_init (&file))
     return dump_status_not_implemented;
 
+#ifdef _MSC_VER /* setp sparse attribute on file descriptor */
+   win_set_sparse_attribute_on_descriptor( st->file_name, fd );
+#endif /* _MSC_VER */
   file.stat_info = st;
   file.fd = fd;
-  file.seekable = lseek (fd, 0, SEEK_SET) == 0;
+  file.seekable = FDSEEK (fd, 0, SEEK_SET) == 0;
   file.offset = 0;
 
   rc = tar_sparse_decode_header (&file);
@@ -472,7 +482,7 @@
 
 
 static bool
-check_sparse_region (struct tar_sparse_file *file, off_t beg, off_t end)
+check_sparse_region (struct tar_sparse_file *file, off64_t beg, off64_t end)
 {
   if (!lseek_or_error (file, beg))
     return false;
@@ -480,7 +490,7 @@
   while (beg < end)
     {
       size_t bytes_read;
-      size_t rdsize = BLOCKSIZE < end - beg ? BLOCKSIZE : end - beg;
+      size_t rdsize = (size_t)(BLOCKSIZE < end - beg ? BLOCKSIZE : end - beg);
       char diff_buffer[BLOCKSIZE];
 
       bytes_read = safe_read (file->fd, diff_buffer, rdsize);
@@ -506,9 +516,9 @@
 }
 
 static bool
-check_data_region (struct tar_sparse_file *file, size_t i)
+check_data_region (struct tar_sparse_file *file, size64_t i)
 {
-  size_t size_left;
+  size64_t size_left;
 
   if (!lseek_or_error (file, file->stat_info->sparse_map[i].offset))
     return false;
@@ -518,7 +528,7 @@
   while (size_left > 0)
     {
       size_t bytes_read;
-      size_t rdsize = (size_left > BLOCKSIZE) ? BLOCKSIZE : size_left;
+      size_t rdsize = (size_t)((size_left > BLOCKSIZE) ? BLOCKSIZE : size_left);
       char diff_buffer[BLOCKSIZE];
 
       union block *blk = find_next_block ();
@@ -555,8 +565,8 @@
 {
   bool rc = true;
   struct tar_sparse_file file;
-  size_t i;
-  off_t offset = 0;
+  size64_t i;
+  off64_t offset = 0;
 
   if (!tar_sparse_init (&file))
     return dump_status_not_implemented;
@@ -703,7 +713,7 @@
 static bool
 oldgnu_dump_header (struct tar_sparse_file *file)
 {
-  off_t block_ordinal = current_block_ordinal ();
+  off64_t block_ordinal = current_block_ordinal ();
   union block *blk;
   size_t i;
 
@@ -918,7 +928,7 @@
 static bool
 pax_dump_header_0 (struct tar_sparse_file *file)
 {
-  off_t block_ordinal = current_block_ordinal ();
+  off64_t block_ordinal = current_block_ordinal ();
   union block *blk;
   size_t i;
   char nbuf[UINTMAX_STRSIZE_BOUND];
@@ -979,7 +989,7 @@
 static bool
 pax_dump_header_1 (struct tar_sparse_file *file)
 {
-  off_t block_ordinal = current_block_ordinal ();
+  off64_t block_ordinal = current_block_ordinal ();
   union block *blk;
   char *p, *q;
   size_t i;
@@ -1124,14 +1134,18 @@
       blk = find_next_block ();
       p = blk->buffer;
       COPY_BUF (blk,nbuf,p);
-      if (!decode_num (&u, nbuf, TYPE_MAXIMUM (size_t)))
+      if (!decode_num (&u, nbuf, TYPE_MAXIMUM (size64_t)))
 	{
 	  ERROR ((0, 0, _("%s: malformed sparse archive member"), 
 		  file->stat_info->orig_file_name));
 	  return false;
 	}
       file->stat_info->sparse_map_size = u;
-      file->stat_info->sparse_map = xcalloc (file->stat_info->sparse_map_size,
+#ifdef _MSC_VER /* limits of 32-bits */
+      if( u > UINT_MAX )
+         too_large_for_win32_die ();
+#endif /* _MSC_VER */
+      file->stat_info->sparse_map = xcalloc ((size_t)file->stat_info->sparse_map_size,
 					     sizeof (*file->stat_info->sparse_map));
       file->stat_info->sparse_map_avail = 0;
       for (i = 0; i < file->stat_info->sparse_map_size; i++)
@@ -1139,7 +1153,7 @@
 	  struct sp_array sp;
 	  
 	  COPY_BUF (blk,nbuf,p);
-	  if (!decode_num (&u, nbuf, TYPE_MAXIMUM (off_t)))
+	  if (!decode_num (&u, nbuf, TYPE_MAXIMUM (off64_t)))
 	    {
 	      ERROR ((0, 0, _("%s: malformed sparse archive member"), 
 		      file->stat_info->orig_file_name));
@@ -1147,7 +1161,7 @@
 	    }
 	  sp.offset = u;
 	  COPY_BUF (blk,nbuf,p);
-	  if (!decode_num (&u, nbuf, TYPE_MAXIMUM (size_t)))
+	  if (!decode_num (&u, nbuf, TYPE_MAXIMUM (size64_t)))
 	    {
 	      ERROR ((0, 0, _("%s: malformed sparse archive member"), 
 		      file->stat_info->orig_file_name));
diff -ur C:\FGCVS\tar\src\system.c C:\Projects\tar\src\system.c
--- C:\FGCVS\tar\src\system.c	Mon Apr 14 14:03:14 2008
+++ C:\Projects\tar\src\system.c	Fri Sep 12 16:15:23 2008
@@ -22,12 +22,17 @@
 #include <rmt.h>
 #include <signal.h>
 
-#if MSDOS
+#if MSDOS || WIN32   /* MSDOS and WIN32 - _MSC_VER */
+
+/* alternate functions */
+extern union block *record_start; /* FIXME */
+
+static struct_stat archive_stat; /* stat block for archive file */
 
 bool
 sys_get_archive_stat (void)
 {
-  return 0;
+  return FDSTAT (archive, &archive_stat) == 0;
 }
 
 bool
@@ -44,10 +49,14 @@
 void
 sys_detect_dev_null_output (void)
 {
+#ifdef _MSC_VER /* no null device like this for windows! */
+   dev_null_output = 0;
+#else /* !_MSC_VER */
   static char const dev_null[] = "nul";
 
   dev_null_output = (strcmp (archive_name_array[0], dev_null) == 0
 		     || (! _isrmt (archive)));
+#endif /* _MSC_VER y/n */
 }
 
 void
@@ -71,19 +80,19 @@
    unpack would fail on MSDOS.  */
 
 bool
-sys_compare_uid (struct stat *a, struct stat *b)
+sys_compare_uid (struct_stat *a, struct_stat *b)
 {
   return true;
 }
 
 bool
-sys_compare_gid (struct stat *a, struct stat *b)
+sys_compare_gid (struct_stat *a, struct_stat *b)
 {
   return true;
 }
 
-void
-sys_compare_links (struct stat *link_data, struct stat *stat_data)
+bool
+sys_compare_links (struct_stat *link_data, struct_stat *stat_data)
 {
   return true;
 }
@@ -101,19 +110,52 @@
 }
 
 /* Set ARCHIVE for writing, then compressing an archive.  */
-void
+pid_t
 sys_child_open_for_compress (void)
 {
   FATAL_ERROR ((0, 0, _("Cannot use compressed or remote archives")));
+  return -1;
 }
 
 /* Set ARCHIVE for uncompressing, then reading an archive.  */
-void
+pid_t
 sys_child_open_for_uncompress (void)
 {
+#ifdef _MSC_VER
+   extern int try_to_ungzip_it(int ro);
+   int res = try_to_ungzip_it(1);
+   return res;
+#else /* _MSC_VER */
   FATAL_ERROR ((0, 0, _("Cannot use compressed or remote archives")));
+  return -1;
+#endif /* _MSC_VER */
 }
 
+int
+sys_exec_info_script (const char **archive_name, int volume_number)
+{
+   return -1;
+}
+
+void
+sys_exec_checkpoint_script (const char *script_name,
+			    const char *archive_name,
+			    int checkpoint_number)
+{
+}
+
+void
+sys_wait_command (void)
+{
+}
+
+int
+sys_exec_command (char *file_name, int typechar, struct tar_stat_info *st)
+{
+   return -1;
+}
+
+
 #else
 
 extern union block *record_start; /* FIXME */
@@ -891,4 +933,4 @@
   exec_fatal (script_name);
 }
 
-#endif /* not MSDOS */
+#endif /* not MSDOS or WIN32 */
diff -ur C:\FGCVS\tar\src\tar.c C:\Projects\tar\src\tar.c
--- C:\FGCVS\tar\src\tar.c	Mon Apr 14 14:03:14 2008
+++ C:\Projects\tar\src\tar.c	Fri Sep 12 20:05:29 2008
@@ -40,16 +40,23 @@
 
 #include <argmatch.h>
 #include <closeout.h>
+#ifndef _MSC_VER /* no configmake.h */
 #include <configmake.h>
+#endif /* !_MSC_VER */
 #include <exitfail.h>
 #include <getdate.h>
 #include <rmt.h>
+#ifndef _MSC_VER /* no rmt-command.h */
 #include <rmt-command.h>
+#endif /* !_MSC_VER */
 #include <prepargs.h>
 #include <quotearg.h>
 #include <version-etc.h>
 #include <xstrtol.h>
 #include <stdopen.h>
+#ifdef _MSC_VER   /* deal with gzipping */
+#include "win_gzip.h"
+#endif /* _MSC_VER */
 
 /* Local declarations.  */
 
@@ -215,6 +222,7 @@
     default:
       abort ();
     }
+  return "uncased";  /* just to shutup (MSC_VER) the compiler warning */
 }
 
 void
@@ -255,6 +263,9 @@
   DELAY_DIRECTORY_RESTORE_OPTION,
   HARD_DEREFERENCE_OPTION,
   DELETE_OPTION,
+#ifdef NEW_DELETE_FUNCTION
+  WINDELETE_OPTION,
+#endif /* NEW_DELETE_FUNCTION */
   EXCLUDE_CACHES_OPTION,
   EXCLUDE_CACHES_UNDER_OPTION,
   EXCLUDE_CACHES_ALL_OPTION,
@@ -387,6 +398,10 @@
   {"concatenate", 0, 0, OPTION_ALIAS, NULL, GRID+1 },
   {"delete", DELETE_OPTION, 0, 0,
    N_("delete from the archive (not on mag tapes!)"), GRID+1 },
+#ifdef NEW_DELETE_FUNCTION
+  {"windel", WINDELETE_OPTION, 0, 0,
+   N_("delete from the archive, and potentially truncate"), GRID+1 },
+#endif /* NEW_DELETE_FUNCTION */
   {"test-label", TEST_LABEL_OPTION, NULL, 0,
    N_("test the archive volume label and exit"), GRID+1 },
 #undef GRID
@@ -469,7 +484,11 @@
   {"group", GROUP_OPTION, N_("NAME"), 0,
    N_("force NAME as group for added files"), GRID+1 },
   {"mtime", MTIME_OPTION, N_("DATE-OR-FILE"), 0,
+#ifdef _MSC_VER /* advise file must start with '.' or 'd:' ... */
+   N_("set mtime for added files from DATE-OR-FILE - file must start with '.', or drive"), GRID+1 },
+#else /* !_MSC_VER */
    N_("set mtime for added files from DATE-OR-FILE"), GRID+1 },
+#endif /* _MSC_VER y/n */
   {"mode", MODE_OPTION, N_("CHANGES"), 0,
    N_("force (symbolic) mode CHANGES for added files"), GRID+1 },
   {"atime-preserve", ATIME_PRESERVE_OPTION,
@@ -870,6 +889,19 @@
   printer (stream, "\n");                                                 \
 }
 #else
+#ifdef _MSC_VER /* add defaults for WIN32 */
+/* add in force-local ... */
+# define DECL_SHOW_DEFAULT_SETTINGS(stream, printer)                      \
+{                                                                         \
+  printer (stream,                                                        \
+	   "--format=%s -f%s -b%d --quoting-style=%s --rmt-command=%s --force-local",   \
+	   archive_format_string (DEFAULT_ARCHIVE_FORMAT),                \
+	   DEFAULT_ARCHIVE, DEFAULT_BLOCKING,                             \
+	   quoting_style_args[DEFAULT_QUOTING_STYLE],                     \
+	   DEFAULT_RMT_COMMAND);                                          \
+  printer (stream, "\n");                                                 \
+}
+#else /* !_MSC_VER */
 # define DECL_SHOW_DEFAULT_SETTINGS(stream, printer)                      \
 {                                                                         \
   printer (stream,                                                        \
@@ -880,6 +912,7 @@
 	   DEFAULT_RMT_COMMAND);                                          \
   printer (stream, "\n");                                                 \
 }
+#endif /* _MSC_VER y/n */
 #endif
 
 static void
@@ -919,6 +952,7 @@
 #ifndef HAVE_SIGACTION
   signal (signo, sigstat);
 #endif
+  return 0;
 }
 
 static void
@@ -943,6 +977,10 @@
     char *name;
     int signo;
   } sigtab[] = {
+#ifdef _MSC_VER /* only SIGINT, no SIGUSR1, etc */
+    { "SIGINT", SIGINT },
+    { "INT", SIGINT }
+#else /* !_MSC_VER */
     { "SIGUSR1", SIGUSR1 },
     { "USR1", SIGUSR1 },
     { "SIGUSR2", SIGUSR2 },
@@ -953,6 +991,7 @@
     { "INT", SIGINT },
     { "SIGQUIT", SIGQUIT },
     { "QUIT", SIGQUIT }
+#endif /* _MSC_VER y/n */
   };
   struct sigtab *p;
 
@@ -982,7 +1021,7 @@
       || ISSLASH (*str)
       || *str == '.')
     {
-      struct stat st;
+      struct_stat st;
       if (deref_stat (dereference_option, str, &st) != 0)
 	{
 	  stat_error (str);
@@ -1054,6 +1093,13 @@
 	     zero-separated */
 	  return file_list_zero;
 	}
+#ifdef _MSC_VER /* ignore trailing spaces from file read */
+      else if(counter && (( c == ' ' )||( c == '\r' )||( c == '\t' )))
+      {
+         // ignore these trailing chars
+         continue;
+      }
+#endif /* _MSC_VER */
       obstack_1grow (stk, c);
       counter++;
     }
@@ -1257,9 +1303,9 @@
       {
 	uintmax_t u;
 	if (! (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK
-	       && u == (blocking_factor = u)
+	       && u == (blocking_factor = (int)u)
 	       && 0 < blocking_factor
-	       && u == (record_size = u * BLOCKSIZE) / BLOCKSIZE))
+	       && u == (record_size = (size_t)(u * BLOCKSIZE)) / BLOCKSIZE))
 	  USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
 			_("Invalid blocking factor")));
       }
@@ -1504,6 +1550,18 @@
       break;
 
     case 'V':
+#ifdef _MSC_VER /* since this argument can be a PATTERN, it may have '...'! */
+       {
+          size_t len = strlen(arg);
+          if(( len > 1 )&& (arg[0] == '\'') && (arg[len-1] == '\''))
+          { /* must duplicate, and remove encasing '...' */
+             char * p = xstrdup(arg);
+             strncpy(p,&arg[1], len-2);
+             p[len-2] = 0;
+             arg = p;
+          }
+       }
+#endif /* _MSC_VER */
       volume_label_option = arg;
       break;
 
@@ -1602,6 +1660,13 @@
       set_subcommand_option (DELETE_SUBCOMMAND);
       break;
 
+#ifdef NEW_DELETE_FUNCTION
+    case WINDELETE_OPTION:
+      windelete_option = true;
+      set_subcommand_option (DELETE_SUBCOMMAND);
+      break;
+#endif /* NEW_DELETE_FUNCTION */
+
     case EXCLUDE_OPTION:
       add_exclude (excluded, arg, MAKE_EXCL_OPTIONS (args));
       break;
@@ -1672,7 +1737,7 @@
 	  uintmax_t g;
 	  if (xstrtoumax (arg, 0, 10, &g, "") == LONGINT_OK
 	      && g == (gid_t) g)
-	    group_option = g;
+	    group_option = (short)g;
 	  else
 	    FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
 			  _("%s: Invalid group")));
@@ -1754,7 +1819,7 @@
 	  uintmax_t u;
 	  if (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK
 	      && u == (uid_t) u)
-	    owner_option = u;
+	    owner_option = (short)u;
 	  else
 	    FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
 			  _("Invalid owner")));
@@ -1792,7 +1857,7 @@
 	       && u == (size_t) u))
 	  USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
 			_("Invalid record size")));
-	record_size = u;
+	record_size = (size_t)u;
 	if (record_size % BLOCKSIZE != 0)
 	  USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."),
 			BLOCKSIZE));
@@ -1832,7 +1897,7 @@
 	       && u == (size_t) u))
 	  USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
 			_("Invalid number of elements")));
-	strip_name_components = u;
+	strip_name_components = (size_t)u;
       }
       break;
 
@@ -2070,6 +2135,9 @@
   group_option = -1;
 
   check_device_option = true;
+#ifdef _MSC_VER /* set force_local_option true for WIN32 */
+  force_local_option = true;  /* a windows path will 'look' remote - C:\DTEMP\temp1.tar! */
+#endif /* _MSC_VER */
   
   /* Convert old-style tar call by exploding option element and rearranging
      options accordingly.  */
@@ -2131,6 +2199,12 @@
   /* Parse all options and non-options as they appear.  */
 
   prepend_default_options (getenv ("TAR_OPTIONS"), &argc, &argv);
+#ifdef _MSC_VER /* allow utilisation of @input.file.txt */
+  input_response_file ( &argc,&argv );
+#endif /* _MSC_VER */
+#if (defined(_MSC_VER) && !defined(NDEBUG))
+  show_arguments( argc, argv );
+#endif /* _MSC_VER and !NDEBUG */
 
   if (argp_parse (&argp, argc, argv, ARGP_IN_ORDER|ARGP_NO_HELP,
 		  &idx, &args))
@@ -2376,20 +2450,56 @@
   
   if (verbose_option)
     report_textual_dates (&args);
+#if (defined(_MSC_VER) && !defined(NDEBUG))
+  printf( "Verbosity level (verbose_option) is %d ...\n", verbose_option );
+#endif /* DEBUG ONLY */
+
 }
 
 
 /* Tar proper.  */
 
+void test_stat( void )
+{
+   struct _stat buf;
+   struct_stat buf64;
+   long lg;
+   long long llg;
+   __int64 i64;
+   unsigned __int64 ui64 = 0xffffffffffffffff;
+   int   i;
+   size_t   st;
+   size64_t   st64;
+   unsigned int ui = 0xffffffff;
+
+   printf( "Size of int = %d\n", sizeof(i) );
+   printf( "Size of long = %d\n", sizeof(lg) );
+   printf( "Size of long long = %d\n", sizeof(llg) );
+   printf( "Size of size_t = %d\n", sizeof(st) );
+   printf( "Size of size64_t = %d\n", sizeof(st64) );
+   printf( "Size of __int64 = %d\n", sizeof(i64) );
+   printf( "Size of unsigned __int64 = %d\n", sizeof(ui64) );
+   printf( "Size of 32-bit time_t = %d\n", sizeof(buf.st_mtime) );
+   printf( "Size of 64-bit time_t = %d\n", sizeof(buf64.st_mtime) );
+   printf( "Size of 32-bit st_size = %d\n", sizeof(buf.st_size) );
+   printf( "Size of 64-bit st_size = %d\n", sizeof(buf64.st_size) );
+   printf( "Maximum unsigned int = %lu bytes.\n", ui );
+   printf( "Maximum unsigned __int64 = %I64u bytes.\n", ui64 );
+   win_exit(2);
+}
+
 /* Main routine for tar.  */
 int
 main (int argc, char **argv)
 {
+   //test_stat();
   set_start_time ();
   program_name = argv[0];
 
   setlocale (LC_ALL, "");
+#ifndef _MSC_VER /* no bindtextdomain() */
   bindtextdomain (PACKAGE, LOCALEDIR);
+#endif /* _MSC_VER y/n */
   textdomain (PACKAGE);
 
   exit_failure = TAREXIT_FAILURE;
@@ -2420,6 +2530,13 @@
 
   name_init ();
 
+#ifdef _MSC_VER   /* deal with gzipping, after archive written */
+  if (use_compress_program_option &&
+     (subcommand_option == EXTRACT_SUBCOMMAND)) {
+     /* if the user HAS gzip available, then use it */
+     try_to_ungzip_it(0);
+  }
+#endif /* _MSC_VER - gzipping */
   /* Main command execution.  */
 
   if (volno_file_option)
@@ -2474,8 +2591,16 @@
   if (volno_file_option)
     closeout_volume_number ();
 
-  /* Dispose of allocated memory, and return.  */
+#ifdef _MSC_VER   /* deal with gzipping, after archive written */
+  if (use_compress_program_option &&
+     (subcommand_option == CREATE_SUBCOMMAND) &&
+     (exit_status == TAREXIT_SUCCESS) ) {
+     /* if the user HAS gzip available, then use it */
+     try_to_gzip_it();
+  }
+#endif /* _MSC_VER - gzipping */
 
+  /* Dispose of allocated memory, and return.  */
   free (archive_name_array);
   name_term ();
 
@@ -2486,6 +2611,13 @@
     close_stdout ();
   else if (ferror (stderr) || fclose (stderr) != 0)
     exit_status = TAREXIT_FAILURE;
+#ifdef _MSC_VER   /* cleanup any memory allocated on exit */
+  term_response_file();
+#ifndef NDEBUG
+  printf( "Exit status is %d ...\n", exit_status );
+#endif /* !NDEBUG */
+#endif /* _MSC_VER */
+
 
   return exit_status;
 }
diff -ur C:\FGCVS\tar\src\tar.h C:\Projects\tar\src\tar.h
--- C:\FGCVS\tar\src\tar.h	Wed Jun 27 15:30:32 2007
+++ C:\Projects\tar\src\tar.h	Mon Sep 08 13:57:15 2008
@@ -264,8 +264,13 @@
 /* Information about a sparse file.  */
 struct sp_array
 {
+#ifdef _MSC_VER /* sp_array structure to 64-bits */
+  off64_t offset;
+  size64_t numbytes;
+#else /* !_MSC_VER */
   off_t offset;
   size_t numbytes;
+#endif /* _MSC_VER y/n */
 };
 
 struct xheader
@@ -287,26 +292,37 @@
 
   char          *uname;     /* user name of owner */
   char          *gname;     /* group name of owner */
-  struct stat   stat;       /* regular filesystem stat */
-
+  struct_stat   stat;       /* regular filesystem stat */
   /* STAT doesn't always have access, data modification, and status
      change times in a convenient form, so store them separately.  */
   struct timespec atime;
   struct timespec mtime;
   struct timespec ctime;
 
+#ifdef _MSC_VER /* use struct _stat64 to get 64-bit size */
+  off64_t archive_file_size;  /* Size of file as stored in the archive.
+			       Equals stat.st_size for non-sparse files */
+#else /* !_MSC_VER */
   off_t archive_file_size;  /* Size of file as stored in the archive.
 			       Equals stat.st_size for non-sparse files */
+#endif /* _MSC_VER y/n */
 
   bool   is_sparse;         /* Is the file sparse */
 
   /* For sparse files: */
   unsigned sparse_major;
   unsigned sparse_minor;
+#ifdef _MSC_VER /* sparse_map ... to 64 bits */
+  size64_t sparse_map_avail;  /* Index to the first unused element in
+			       sparse_map array. Zero if the file is
+			       not sparse */
+  size64_t sparse_map_size;   /* Size of the sparse map */
+#else /* !_MSC_VER */
   size_t sparse_map_avail;  /* Index to the first unused element in
 			       sparse_map array. Zero if the file is
 			       not sparse */
   size_t sparse_map_size;   /* Size of the sparse map */
+#endif /* _MSC_VER y/n */
   struct sp_array *sparse_map;
 
   /* Extended headers */
diff -ur C:\FGCVS\tar\src\update.c C:\Projects\tar\src\update.c
--- C:\FGCVS\tar\src\update.c	Wed Jun 27 15:30:32 2007
+++ C:\Projects\tar\src\update.c	Fri Sep 12 16:20:38 2008
@@ -48,7 +48,7 @@
 append_file (char *file_name)
 {
   int handle = open (file_name, O_RDONLY | O_BINARY);
-  struct stat stat_data;
+  struct_stat stat_data;
 
   if (handle < 0)
     {
@@ -56,11 +56,11 @@
       return;
     }
 
-  if (fstat (handle, &stat_data) != 0)
+  if (FDSTAT (handle, &stat_data) != 0)
     stat_error (file_name);
   else
     {
-      off_t bytes_left = stat_data.st_size;
+      off64_t bytes_left = stat_data.st_size;
 
       while (bytes_left > 0)
 	{
@@ -71,15 +71,15 @@
 
 	  if (bytes_left < buffer_size)
 	    {
-	      buffer_size = bytes_left;
-	      status = buffer_size % BLOCKSIZE;
+	      buffer_size = (size_t)bytes_left;
+	      status = (size_t)(buffer_size % BLOCKSIZE);
 	      if (status)
 		memset (start->buffer + bytes_left, 0, BLOCKSIZE - status);
 	    }
 
 	  status = safe_read (handle, start->buffer, buffer_size);
 	  if (status == SAFE_READ_ERROR)
-	    read_fatal_details (file_name, stat_data.st_size - bytes_left,
+	    read_fatal_details (file_name, (off_t)(stat_data.st_size - bytes_left),
 				buffer_size);
 	  if (status == 0)
 	    FATAL_ERROR ((0, 0,
@@ -133,7 +133,7 @@
 	    if (subcommand_option == UPDATE_SUBCOMMAND
 		&& (name = name_scan (current_stat_info.file_name)) != NULL)
 	      {
-		struct stat s;
+		struct_stat s;
 
 		chdir_do (name->change_dir);
 		if (deref_stat (dereference_option,
diff -ur C:\FGCVS\tar\src\xheader.c C:\Projects\tar\src\xheader.c
--- C:\FGCVS\tar\src\xheader.c	Wed Jun 27 15:30:32 2007
+++ C:\Projects\tar\src\xheader.c	Tue Sep 09 14:46:09 2008
@@ -483,7 +483,7 @@
   char *start = *ptr;
   char *p = start;
   uintmax_t u;
-  size_t len;
+  size64_t len;
   char *len_lim;
   char const *keyword;
   char *nextp;
@@ -773,7 +773,7 @@
   while (n != p);
 
   p = strlen (keyword) + n + 2;
-  size = p;
+  size = (size_t)p;
   if (size != p)
     {
       ERROR ((0, 0,
@@ -782,10 +782,10 @@
       obstack_free (xhdr->stk, obstack_finish (xhdr->stk));
       return false;
     }
-  x_obstack_blank (xhdr, p);
+  x_obstack_blank (xhdr, (size_t)p);
   x_obstack_1grow (xhdr, '\n');
   cp = obstack_next_free (xhdr->stk) - xhdr->string_length - p - 1;
-  memmove (cp + p, cp, xhdr->string_length);
+  memmove (cp + p, cp, (size_t)xhdr->string_length);
   cp = stpcpy (cp, np);
   *cp++ = ' ';
   cp = stpcpy (cp, keyword);
@@ -1034,7 +1034,7 @@
 {
   uintmax_t u;
   if (decode_num (&u, arg, TYPE_MAXIMUM (gid_t), keyword))
-    st->stat.st_gid = u;
+    st->stat.st_gid = (short)u;
 }
 
 static void
@@ -1138,7 +1138,7 @@
 	      size_t size __attribute__((unused)))
 {
   uintmax_t u;
-  if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
+  if (decode_num (&u, arg, TYPE_MAXIMUM (off64_t), keyword))
     st->stat.st_size = u;
 }
 
@@ -1157,7 +1157,7 @@
 {
   uintmax_t u;
   if (decode_num (&u, arg, TYPE_MAXIMUM (uid_t), keyword))
-    st->stat.st_uid = u;
+    st->stat.st_uid = (short)u;
 }
 
 static void
@@ -1190,7 +1190,7 @@
 		     size_t size __attribute__((unused)))
 {
   uintmax_t u;
-  if (decode_num (&u, arg, TYPE_MAXIMUM (off_t), keyword))
+  if (decode_num (&u, arg, TYPE_MAXIMUM (off64_t), keyword))
     st->stat.st_size = u;
 }
 
@@ -1212,7 +1212,7 @@
   if (decode_num (&u, arg, SIZE_MAX, keyword))
     {
       st->sparse_map_size = u;
-      st->sparse_map = xcalloc (u, sizeof st->sparse_map[0]);
+      st->sparse_map = xcalloc ((size_t)u, sizeof st->sparse_map[0]);
       st->sparse_map_avail = 0;
     }
 }
@@ -1433,7 +1433,7 @@
 {
   uintmax_t u;
   if (decode_num (&u, arg, TYPE_MAXIMUM (unsigned), keyword))
-    st->sparse_major = u;
+    st->sparse_major = (size_t)u;
 }
 
 static void
@@ -1451,7 +1451,7 @@
 {
   uintmax_t u;
   if (decode_num (&u, arg, TYPE_MAXIMUM (unsigned), keyword))
-    st->sparse_minor = u;
+    st->sparse_minor = (size_t)u;
 }
 
 struct xhdr_tab const xhdr_tab[] = {
Only in C:\Projects\tar: tempd112.tar
Only in C:\Projects\tar: tempd1122.tar
Only in C:\Projects\tar: tempsa
diff -ur C:\FGCVS\tar\tests\argcv.c C:\Projects\tar\tests\argcv.c
--- C:\FGCVS\tar\tests\argcv.c	Wed Jun 27 15:49:46 2007
+++ C:\Projects\tar\tests\argcv.c	Sat Aug 23 16:53:59 2008
@@ -15,9 +15,14 @@
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA  */
 
+# include <config.h>
 #include <ctype.h>
 
 #include <argcv.h>
+
+#ifdef _MSC_VER /* fold snprintf into _snprintf */
+#define  snprintf _snprintf
+#endif
 
 /*
  * takes a string and splits it into several strings, breaking at ' '
Only in C:\Projects\tar\tests: genfile-test.c
diff -ur C:\FGCVS\tar\tests\genfile.c C:\Projects\tar\tests\genfile.c
--- C:\FGCVS\tar\tests\genfile.c	Mon Feb 18 09:23:24 2008
+++ C:\Projects\tar\tests\genfile.c	Sat Sep 13 18:10:23 2008
@@ -22,6 +22,7 @@
    Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
 
+#include <config.h>  /* get this in FIRST */
 #include <system.h>
 #include <signal.h>
 #include <stdarg.h>
@@ -36,7 +37,9 @@
 #define obstack_chunk_alloc malloc
 #define obstack_chunk_free free
 #include <obstack.h>
-
+#ifdef _MSC_VER /* add thread support, to sort of replace fork() */
+#include "win_thread.h"
+#endif /* _MSC_VER */
 #ifndef EXIT_SUCCESS
 # define EXIT_SUCCESS 0
 #endif
@@ -48,6 +51,10 @@
 # define SIGCHLD SIGCLD
 #endif
 
+#ifdef _MSC_VER
+#define  fseeko   _fseeki64
+#endif
+
 enum pattern
 {
   DEFAULT_PATTERN,
@@ -65,8 +72,8 @@
 static char filename_terminator = '\n';
 
 /* Length of file to generate.  */
-static off_t file_length = 0;
-static off_t seek_offset = 0;
+static off64_t file_length = 0;
+static off64_t seek_offset = 0;
 
 /* Pattern to generate.  */
 static enum pattern pattern = DEFAULT_PATTERN;
@@ -91,7 +98,11 @@
 static char *stat_format = DEFAULT_STAT_FORMAT;
 
 /* Size of a block for sparse file */
+#ifdef _MSC_VER /* use size64_t */
+size64_t block_size = 512;
+#else /* !_MSC_VER */
 size_t block_size = 512;
+#endif /* _MSC_VER y/n */
 
 /* Block buffer for sparse file */
 char *buffer;
@@ -196,6 +207,65 @@
 static char const * const pattern_args[] = { "default", "zeros", 0 };
 static enum pattern const pattern_types[] = {DEFAULT_PATTERN, ZEROS_PATTERN};
 
+
+#ifdef _MSC_VER
+static int
+xlat_suffix (off64_t *vp, const char *p)
+{
+  off64_t val = *vp;
+
+  if (p[1])
+    return 1;
+  switch (p[0])
+    {
+    case 'g':
+    case 'G':
+      *vp *= 1024;
+
+    case 'm':
+    case 'M':
+      *vp *= 1024;
+
+    case 'k':
+    case 'K':
+      *vp *= 1024;
+      break;
+
+    default:
+      return 1;
+    }
+  return *vp <= val;
+}
+
+
+static off64_t
+get_size (const char *str, int allow_zero)
+{
+  const char *p;
+  off64_t v = 0;
+
+  for (p = str; *p; p++)
+    {
+      int digit = *p - '0';
+      off64_t x = v * 10;
+      if (9 < (unsigned) digit)
+	{
+	  if (xlat_suffix (&v, p))
+	    error (EXIT_FAILURE, 0, _("Invalid size: %s"), str);
+	  else
+	    break;
+	}
+      else if (x / 10 != v)
+	error (EXIT_FAILURE, 0, _("Number out of allowed range: %s"), str);
+      v = x + digit;
+      if (v < 0)
+	error (EXIT_FAILURE, 0, _("Negative size: %s"), str);
+    }
+  return v;
+}
+
+#else /* !_MSC_VER */
+
 static int
 xlat_suffix (off_t *vp, const char *p)
 {
@@ -249,25 +319,34 @@
     }
   return v;
 }
+#endif /* _MSC_VER y/n */
 
 void
 verify_file (char *file_name)
 {
   if (file_name)
     {
-      struct stat st;
+      struct __stat64 st;
 
-      if (stat (file_name, &st))
+      if (_stat64 (file_name, &st))
 	error (0, errno, _("stat(%s) failed"), file_name);
 
       if (st.st_size != file_length + seek_offset)
 	{
-	  printf ("%lu %lu\n", (unsigned long)st.st_size , (unsigned long)file_length);
+      printf ("Error: Got size %lum expected %lu\n", (unsigned long)st.st_size , (unsigned long)file_length);
 	  exit (1);
 	}
 
+#ifdef _MSC_VER
+      if (mode == mode_sparse)
+      {
+         if( !win_verify_sparse( file_name, &st ) )
+            exit(1);
+      }
+#else
       if (mode == mode_sparse && !ST_IS_SPARSE (st))
 	exit (1);
+#endif
     }
 }
 
@@ -277,7 +356,11 @@
   size_t checkpoint;
   int action;
   char *name;
+#ifdef _MSC_VER /* use off64_t for size */
+  off64_t size;
+#else /* !_MSC_VER */
   off_t size;
+#endif /* _MSC_VER y/n */
   enum pattern pattern;
   struct timespec ts;
 };
@@ -390,15 +473,15 @@
 
 
 void
-fill (FILE *fp, off_t length, enum pattern pattern)
+fill (FILE *fp, off64_t length, enum pattern pattern)
 {
-  off_t i;
+  off64_t i;
 
   switch (pattern)
     {
     case DEFAULT_PATTERN:
       for (i = 0; i < length; i++)
-	fputc (i & 255, fp);
+	fputc ((int)(i & 255), fp);
       break;
 
     case ZEROS_PATTERN:
@@ -424,8 +507,11 @@
     fp = stdout;
 
   if (fseeko (fp, seek_offset, 0))
+  {
+     printf( "Can NOT ssek on [%s] file ...\n",
+        filename ? filename : "stdout" );
     error (EXIT_FAILURE, errno, "%s", _("cannot seek"));
-
+  }
   fill (fp, file_length, pattern);
 
   fclose (fp);
@@ -476,16 +562,58 @@
 /* Generate Mode: sparse files */
 
 static void
-mkhole (int fd, off_t displ)
+mkhole (int fd, off64_t displ)
 {
+#ifdef _MSC_VER /* must use file HANDLE */
+   LARGE_INTEGER lir, lit;
+   lir.QuadPart = displ;
+#if !defined(NDEBUG)
+  printf( "mkhole: did seek to %d ...\n", displ );
+#endif // EXTRA DEBUG OF SEEK
+   if( !SetFilePointerEx( (HANDLE)fd,   // HANDLE hFile,
+      lir,
+      &lit,
+      FILE_CURRENT ) )   // DWORD dwMoveMethod
+       error (EXIT_FAILURE, GetLastError(), "SetFilePointer");
+   if( !SetEndOfFile( (HANDLE)fd ) )
+       error (EXIT_FAILURE, GetLastError(), "SetEndOfFile");
+
+#else /* !_MSC_VER */
   if (lseek (fd, displ, SEEK_CUR) == -1)
     error (EXIT_FAILURE, errno, "lseek");
+
   ftruncate (fd, lseek (fd, 0, SEEK_CUR));
+
+#endif /* _MSC_VER y/n */
+
 }
 
 static void
-mksparse (int fd, off_t displ, char *marks)
+mksparse (int fd, off64_t displ, char *marks)
 {
+#ifdef _MSC_VER   /* Use windows native file IO */
+   LARGE_INTEGER lid;
+   LARGE_INTEGER lim;
+   lid.QuadPart = displ;
+#if !defined(NDEBUG)
+   printf( "mksparse: fd %d, offset %I64d, marks [%s]\n",
+      fd, displ, (( marks && *marks ) ? marks : "<null>"));
+#endif // EXTRA DEBUG
+   if ( !SetFilePointerEx( (HANDLE)fd,   // HANDLE hFile,
+      lid,   // LONG lDistanceToMove,
+      &lim,  // PLONG lpDistanceToMoveHigh,
+      FILE_CURRENT ) )   // DWORD dwMoveMethod
+       error (EXIT_FAILURE, GetLastError(), "SetFilePointer");
+   for (; *marks; marks++)
+   {
+      DWORD dww;
+      size_t bs = (size_t)block_size;
+      memset (buffer, *marks, bs);
+      if( !WriteFile( (HANDLE)fd, buffer, bs, &dww, NULL ) )
+         error (EXIT_FAILURE, errno, "WriteFile");
+   }
+
+#else /* !_MSC_VER */
   if (lseek (fd, displ, SEEK_CUR) == -1)
     error (EXIT_FAILURE, errno, "lseek");
 
@@ -495,11 +623,79 @@
       if (write (fd, buffer, block_size) != block_size)
 	error (EXIT_FAILURE, errno, "write");
     }
+#endif // _MSC_VER y/n */
 }
 
 static void
 generate_sparse_file (int argc, char **argv)
 {
+#ifdef _MSC_VER
+   HANDLE fd;
+   DWORD  dwflags = CREATE_ALWAYS;
+   DWORD  dwatts  = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN;
+   int i = win_drive_supports_sparse( file_name );
+
+   if (!file_name)
+      error (EXIT_FAILURE, 0,
+	   _("cannot generate sparse files on standard output, use --file option"));
+
+   if ( !i )
+      error (EXIT_FAILURE, 0,
+	   _("drive does NOT support sparse file creation"));
+
+#ifdef _MSC_VER /* check block size - must be less than UINT_MAX ... */
+   if( block_size > UINT_MAX )
+      too_large_for_win32_die();
+#endif /* _MSC_VER */
+
+   if (seek_offset)
+      dwflags = OPEN_EXISTING;
+
+   fd = CreateFile(file_name, GENERIC_WRITE, FILE_SHARE_READ, NULL, dwflags, dwatts, NULL);
+   if( !VFH(fd) )
+      error (EXIT_FAILURE, errno, _("cannot open '%s'"), file_name);
+
+   /* from : ms-help://MS.VSExpressCC.v80/MS.VSIPCC.v80/MS.PSDKSVR2003R2.1033/fileio/fs/sparse_files.htm,
+      and from : http://www.flexhex.com/docs/articles/sparse-files.phtml */
+   if ( !DeviceIoControl(fd, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &dwatts, NULL) )
+      error (EXIT_FAILURE, errno, _("cannot set sparse attribute on '%s'"), file_name);
+
+#ifdef _MSC_VER /* advise file openned ... */
+#if !defined(NDEBUG)
+   printf( "Openned file [%s], handle = %d\n", file_name, fd );
+#endif // EXTRA DEBUG
+#endif /* _MSC_VER */
+
+   buffer = xmalloc ((size_t)block_size);
+
+   file_length = 0;
+
+#if (defined(_MSC_VER) && !defined(NDEBUG))
+   printf( "Arguments remaining %d ...\n", argc );
+   for( i = 0; i < argc; i++ )
+      printf( "CMD %d: %s\n", (i + 1), (argv[i] ? argv[i] : "<null>") );
+#endif // EXTRA DEBUG OF ARGUMENTS FOUND
+   for (i = 0; i < argc; i += 2)
+   {
+      off64_t displ = get_size (argv[i], 1);
+      file_length += displ;
+      if (i == argc-1)
+      {
+         mkhole ((int)fd, displ);
+         break;
+      }
+      else
+      {
+         file_length += block_size * strlen (argv[i+1]);
+         mksparse ((int)fd, displ, argv[i+1]);
+      }
+   }
+
+#if (defined(_MSC_VER) && !defined(NDEBUG))
+   printf( "Close file [%s], fd = %d\n", file_name, fd );
+#endif // EXTRA DEBUG OF SHOW FILE
+   CloseHandle(fd);
+#else /* !_MSC_VER */
   int i;
   int fd;
   int flags = O_CREAT | O_RDWR | O_BINARY;
@@ -516,7 +712,13 @@
   buffer = xmalloc (block_size);
 
   file_length = 0;
-
+#if (defined(_MSC_VER) && !defined(NDEBUG))
+   printf( "Arguments remaining %d ...\n", argc );
+   for( i = 0; i < argc; i++ )
+   {
+      printf( "CMD %d: %s\n", (i + 1), (argv[i] ? argv[i] : "<null>") );
+   }
+#endif // EXTRA DEBUG OF ARGUMENTS FOUND
   for (i = 0; i < argc; i += 2)
     {
       off_t displ = get_size (argv[i], 1);
@@ -534,7 +736,12 @@
 	}
     }
 
+#if (defined(_MSC_VER) && !defined(NDEBUG))
+  printf( "Close file [%s], fd = %d\n", file_name, fd );
+#endif // EXTRA DEBUG OF SHOW FILE
   close (fd);
+#endif /* _MSC_VER y/n */
+
 }
 
 
@@ -552,10 +759,10 @@
 print_stat (const char *name)
 {
   char *fmt, *p;
-  struct stat st;
+  struct_stat st;
   char buf[UINTMAX_STRSIZE_BOUND];
 
-  if (stat (name, &st))
+  if (FNSTAT (name, &st))
     {
       error (0, errno, _("stat(%s) failed"), name);
       return;
@@ -602,10 +809,15 @@
 	printf ("%lu", (unsigned long) st.st_gid);
       else if (strcmp (p, "size") == 0)
 	printf ("%s", umaxtostr (st.st_size, buf));
+#ifdef _MSC_VER /* add 'ssize' output */
+      else if (strcmp (p, "ssize") == 0)
+	printf ("%s", umaxtostr (win_get_sparse_file_size(name), buf));
+#else /* !_MSC_VER */
       else if (strcmp (p, "blksize") == 0)
 	printf ("%s", umaxtostr (st.st_blksize, buf));
       else if (strcmp (p, "blocks") == 0)
 	printf ("%s", umaxtostr (st.st_blocks, buf));
+#endif /* !_MSC_VER */
       else if (strcmp (p, "atime") == 0)
 	printf ("%lu", (unsigned long) st.st_atime);
       else if (strcmp (p, "atimeH") == 0)
@@ -619,7 +831,15 @@
       else if (strcmp (p, "ctimeH") == 0)
 	print_time (st.st_ctime);
       else if (strcmp (p, "sparse") == 0)
-	printf ("%d", ST_IS_SPARSE (st));
+      {
+	printf ("%d",
+#ifdef _MSC_VER
+      win_is_sparse_file( name )
+#else /* !_MSC_VER */
+   ST_IS_SPARSE (st)
+#endif /* _MSC_VER y/n */
+   );
+      }
       else
 	{
 	  printf ("\n");
@@ -630,6 +850,8 @@
 	printf (" ");
     }
   printf ("\n");
+
+
   free (fmt);
 }
 
@@ -672,6 +894,11 @@
 
     case OPT_TRUNCATE:
       {
+#ifdef _MSC_VER
+         char * perr = win_truncate_file( p->name, p->size );
+         if(perr)
+            error (0, EIO, perr);
+#else /* !_MSC_VER */
 	int fd = open (p->name, O_RDWR | O_BINARY);
 	if (fd == -1)
 	  {
@@ -680,6 +907,7 @@
 	  }
 	ftruncate (fd, p->size);
 	close (fd);
+#endif /* _MSC_VER */
       }
       break;
 
@@ -738,6 +966,33 @@
   memmove (exec_argv+2, exec_argv+1, (exec_argc - 1) * sizeof (*exec_argv));
   exec_argv[1] = "--checkpoint";
 
+#ifdef _MSC_VER /* replace pipe and fork for WIN32 */
+  //p = win_genfile_thread ( exec_argv[0], exec_argv, THREAD_USE_EXECVP );
+  //p = win_genfile_thread ( exec_argv[0], exec_argv, THREAD_USE_SYSTEM );
+  //p = win_genfile_thread ( exec_argv[0], exec_argv, USE_SYSTEM_DIRECT );
+  p = win_genfile_thread ( exec_argv[0], exec_argv, USE_CREATE_PROCESS );
+  if( p )
+  {
+     int i = errno;
+     status = (exec_error ? exec_error : errno);
+#ifndef NDEBUG
+     fprintf(stderr, "Thread FAILED! Error indication -\n"
+        "%s (%d)\n", p, status );
+     fprintf(stderr, "Arguments passed:\n" );
+     for( i = 0; ; i++ )
+     {
+        p = exec_argv[i];
+        if(p) {
+           fprintf(stderr, "%d: %s\n", (i+1), p );
+        } else {
+           break;
+        }
+     }
+#endif /* !NDEBUG */
+     status = (exec_error ? exec_error : errno);
+     error (EXIT_FAILURE, status, "thread/fork");
+  }
+#else /* !_MSC_VER */
 #ifdef SIGCHLD
   /* System V fork+wait does not work if SIGCHLD is ignored.  */
   signal (SIGCHLD, SIG_DFL);
@@ -824,8 +1079,36 @@
   if (WIFEXITED (status))
     exit (WEXITSTATUS (status));
   exit (EXIT_FAILURE);
+#endif /* _MSC_VER y/n */
+
 }
 
+#ifdef _MSC_VER
+void show_command_args( int * pargc, char * * * pargv )
+{
+   int i;
+   char * arg;
+   char **argv = *pargv;
+   int argc = *pargc;
+   size_t   len;
+
+   len = 0;
+   for(i = 0; i < argc; i++)
+   {
+      arg = argv[i];
+      if( arg )
+      {
+#ifndef NDEBUG
+         printf( "%d CMD: %s\n", (i + 1), arg );
+#endif
+         len += strlen(arg) + 2;
+      }
+   }
+   // ok got the total length
+   i = 0;
+}
+#endif
+
 int
 main (int argc, char **argv)
 {
@@ -833,12 +1116,22 @@
 
   program_name = argv[0];
   setlocale (LC_ALL, "");
+#ifndef _MSC_VER
   bindtextdomain (PACKAGE, LOCALEDIR);
   textdomain (PACKAGE);
+#endif
 
   get_date (&touch_time, "now", NULL);
 
   /* Decode command options.  */
+#if (defined(_MSC_VER) && !defined(NDEBUG))
+   show_command_args( &argc, &argv );
+   if( argc < 2 )
+   {
+      printf( "No arguments given ... try --help ...\n" );
+      exit(2);
+   }
+#endif
 
   if (argp_parse (&argp, argc, argv, 0, &index, NULL))
     exit (EXIT_FAILURE);
@@ -849,6 +1142,10 @@
   switch (mode)
     {
     case mode_stat:
+#if (defined(_MSC_VER) && !defined(NDEBUG))
+      printf( "Mode stat ... %s ...\n",
+         (argc ? *argv : "no file 1 ...") );
+#endif
       if (argc == 0)
 	error (EXIT_FAILURE, 0, _("--stat requires file names"));
 
@@ -857,11 +1154,19 @@
       break;
 
     case mode_sparse:
+#if (defined(_MSC_VER) && !defined(NDEBUG))
+      printf( "Mode sparse ...\n" );
+#endif
       generate_sparse_file (argc, argv);
       verify_file (file_name);
       break;
 
     case mode_generate:
+#if (defined(_MSC_VER) && !defined(NDEBUG))
+       printf( "Mode generate, %s, length %I64u\n",
+          (files_from ? "from list" : file_name),
+          file_length );
+#endif
       if (argc)
 	error (EXIT_FAILURE, 0, _("too many arguments"));
       if (files_from)
@@ -874,12 +1179,22 @@
       break;
 
     case mode_exec:
+#if (defined(_MSC_VER) && !defined(NDEBUG))
+      printf( "Mode exec ...\n" );
+#endif
       exec_command ();
       break;
 
     default:
+#if (defined(_MSC_VER) && !defined(NDEBUG))
+      printf( "Mode default ...\n" );
+#endif
       /* Just in case */
       abort ();
     }
+
+#if (defined(_MSC_VER) && !defined(NDEBUG))
+  printf( "Exit with 0 = success ...\n" );
+#endif
   exit (EXIT_SUCCESS);
 }
Only in C:\Projects\tar: Win32
