// winport.c
// provide some GLUE code for Windows port

#include <config.h>
#include <system.h>
#include <common.h>

#ifdef _MSC_VER
static char _s_zipbuf[264];
static char _s_outbuf[264];
static char _s_arcbuf[264];
static struct stat _s_sbuf;

void try_to_gzip_it( void )
{
  char * zb = _s_zipbuf;
  char * ob = _s_outbuf;
  const char * arcname = archive_name_array[0];
  int res;
  if( arcname && *arcname )
  {
     sprintf(zb, "gzip %s", arcname );
     res = system(zb);
     if(res) {
        sprintf(ob, "ERROR: CMD: [%s] returned %d!\n"
           "gzip may not be in PATH?\n", zb, res );
        fprintf(stderr,ob);
     } else {
        strcpy(zb, arcname );
        strcat(zb, ".gz" );
        if( stat( zb, &_s_sbuf ) != 0 )
        {
           sprintf(ob, "WARNING: gzip failed, as file [%s] does not seem to exist!\n", zb );
           fprintf(stderr,ob);
        }
     }
  }
}

void try_to_ungzip_it( void )
{
  char * zb = _s_zipbuf;
  char * ob = _s_outbuf;
  char * ab = _s_arcbuf;
  char * tmp;
  const char * arcname = archive_name_array[0];
  int res, sres;
  size_t len;

  *ab = 0;
  if( arcname && *arcname )
  {
     len = strlen(arcname);
     strcpy(ob,arcname);
     sres = stat(ob, &_s_sbuf);
     if(sres)
     {  /* failed to find archive file name!
           maybe because '.gz' missing */
        tmp = &ob[len-3];
        if((len > 3) &&
           ( _strnicmp(tmp, ".tar", 4) == 0 ))
        {
           strcat(ob,".gz");  /* try adding '.gz' to file */
           sres = stat(ob, &_s_sbuf);
           if(sres)
           {
              /* failed again, so go back to original */
              strcpy(ob,arcname);   /* user given name */
           }
           else
           {
               strcpy(ab,ob); /* found this archive */
           }
        }
     }
     else
     {
         strcpy(ab,ob); /* found this archive */
     }
     sprintf(zb, "gzip -d %s", ob );
     /* let the system fizzle with it */
     res = system(zb);
     /* we're back */
     if(res)
     {
        /* deal with possible error */
        sprintf(ob, "ERROR: CMD: [%s] returned %d!\n"
           "gzip may not be in PATH?\n", zb, res );
        fprintf(stderr,ob);
     }
     else
     {
        strcpy(zb, arcname);
        tmp = &zb[len-3];
        if((len > 3) &&
           ( _strnicmp(tmp, ".gz", 3) == 0 ))
        {
           zb[len-3] = 0;
           if( stat( zb, &_s_sbuf ) != 0 )
           {
              sprintf(ob, "WARNING: gzip failed, as file [%s] does not seem to exist!\n", zb );
              fprintf(stderr,ob);
           } else {
              strcpy((char *)arcname,zb);
           }
        }
     }
  }
}

#endif /* _MSC_VER */



DIR * opendir(const char * dir )
{
	DIR * pdir = (DIR *)malloc( sizeof(DIR) );
	if( pdir ) {
		char * cp = &pdir->search[0]; 
		strcpy( cp, dir );
		strcat( cp, "\\*.*" );
		pdir->hfind = FindFirstFile( cp, &pdir->fd );
		if(pdir->hfind && (pdir->hfind != INVALID_HANDLE_VALUE))
		{
			pdir->is_first = 1;
			return pdir;

		} else {
			free(pdir);
		}
	}



	return NULL;
}

struct dirent * readdir (DIR * pdir)
{
	if(pdir)
	{
		char * dst = &pdir->de.d_name[0];
		char * src = &pdir->fd.cFileName[0];
		if( pdir->is_first )
		{
			pdir->de.d_namlen = (int)strlen(src);
			strcpy( dst, src );
         pdir->de.d_type = 0;
         if( pdir->fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
            pdir->de.d_type = DT_DIR;
			pdir->is_first = 0;
			return &pdir->de;
		}
		else
		{
			if(pdir->hfind && (pdir->hfind != INVALID_HANDLE_VALUE))
			{
				if( FindNextFile( pdir->hfind , &pdir->fd ) )
				{
					pdir->de.d_namlen = (int)strlen(src);
					strcpy( dst, src );
               pdir->de.d_type = 0;
               if( pdir->fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
                  pdir->de.d_type = DT_DIR;
					return &pdir->de;
				}
			}
		}
	}
	return NULL;
}

int closedir(DIR * pdir)
{
	if(pdir)
	{
		if(pdir->hfind && (pdir->hfind != INVALID_HANDLE_VALUE))
		{
			FindClose(pdir->hfind);
		}
		free( pdir );
	}
	return 0;
}

int geteuid( void )
{
   return 0;
}
int
chown (const char *file, uid_t uid, gid_t gid)
{
   // WIN32 NTFS does NOT have FILE OWNER,
   // so just return SUCCESS!!!
   return 0;
}

#include <time.h>

#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
  #define DELTA_EPOCH_IN_MICROSECS  11644473600000000Ui64
#else
  #define DELTA_EPOCH_IN_MICROSECS  11644473600000000ULL
#endif
 
struct timezone 
{
  int  tz_minuteswest; /* minutes W of Greenwich */
  int  tz_dsttime;     /* type of dst correction */
};
 
int gettimeofday(struct timeval *tv, struct timezone *tz)
{
  FILETIME ft;
  unsigned __int64 tmpres = 0;
  static int tzflag;
 
  if (NULL != tv)
  {
    GetSystemTimeAsFileTime(&ft);
 
    tmpres |= ft.dwHighDateTime;
    tmpres <<= 32;
    tmpres |= ft.dwLowDateTime;
 
    /*converting file time to unix epoch*/
    tmpres /= 10;  /*convert into microseconds*/
    tmpres -= DELTA_EPOCH_IN_MICROSECS; 
    tv->tv_sec = (long)(tmpres / 1000000UL);
    tv->tv_usec = (long)(tmpres % 1000000UL);
  }
 
  if (NULL != tz)
  {
    if (!tzflag)
    {
      _tzset();
      tzflag++;
    }
    tz->tz_minuteswest = _timezone / 60;
    tz->tz_dsttime = _daylight;
  }
 
  return 0;
}

// eof - winport.c

