gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r376 - in GNUnet/src: include util/win


From: durner
Subject: [GNUnet-SVN] r376 - in GNUnet/src: include util/win
Date: Sat, 5 Mar 2005 04:55:25 -0800 (PST)

Author: durner
Date: 2005-03-05 04:55:22 -0800 (Sat, 05 Mar 2005)
New Revision: 376

Modified:
   GNUnet/src/include/platform.h
   GNUnet/src/include/winproc.h
   GNUnet/src/util/win/win.cc
   GNUnet/src/util/win/winproc.c
Log:
Improve symlink handling under Windows

Modified: GNUnet/src/include/platform.h
===================================================================
--- GNUnet/src/include/platform.h       2005-03-05 06:56:48 UTC (rev 375)
+++ GNUnet/src/include/platform.h       2005-03-05 12:55:22 UTC (rev 376)
@@ -189,6 +189,8 @@
  #define MMAP(s, l, p, f, d, o) mmap(s, l, p, f, d, o)
  #define MUNMAP(s, l) munmap(s, l);
  #define STRERROR(i) strerror(i)
+ #define READLINK(p, b, s) readlink(p, b, s)
+ #define LSTAT(p, b) lstat(p, b)
  #define ACCEPT(s, a, l) accept(s, a, l)
  #define BIND(s, n, l) bind(s, n, l)
  #define CONNECT(s, n, l) connect(s, n, l)
@@ -231,6 +233,8 @@
  #define MMAP(s, l, p, f, d, o) _win_mmap(s, l, p, f, d, o)
  #define MUNMAP(s, l) _win_munmap(s, l);
  #define STRERROR(i) _win_strerror(i)
+ #define READLINK(p, b, s) _win_readlink(p, b, s)
+ #define LSTAT(p, b) _win_lstat(p, b)
  #define ACCEPT(s, a, l) _win_accept(s, a, l)
  #define BIND(s, n, l) _win_bind(s, n, l)
  #define CONNECT(s, n, l) _win_connect(s, n, l)

Modified: GNUnet/src/include/winproc.h
===================================================================
--- GNUnet/src/include/winproc.h        2005-03-05 06:56:48 UTC (rev 375)
+++ GNUnet/src/include/winproc.h        2005-03-05 12:55:22 UTC (rev 376)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2001 - 2004 Christian Grothoff (and other contributing authors)
+     (C) 2001, 2002, 2003, 2004, 2005 Christian Grothoff (and other 
contributing authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -390,6 +390,7 @@
 void _SetErrnoFromWinError(long lWinError, char *pszCaller, int iLine);
 void SetErrnoFromWinsockError(long lWinError);
 void SetHErrnoFromWinError(long lWinError);
+void SetErrnoFromHRESULT(HRESULT hRes);
 FILE *_win_fopen(const char *filename, const char *mode);
 DIR *_win_opendir(const char *dirname);
 int _win_chdir(const char *path);
@@ -411,6 +412,8 @@
 void *_win_mmap(void *start, size_t len, int access, int flags, int fd,
                 unsigned long long offset);
 int _win_munmap(void *start, size_t length);
+int _win_lstat(const char *path, struct stat *buf);
+int _win_readlink(const char *path, char *buf, size_t bufsize);
 int _win_accept(SOCKET s, struct sockaddr *addr, int *addrlen);
 int _win_bind(SOCKET s, const struct sockaddr *name, int namelen);
 int _win_connect(SOCKET s,const struct sockaddr *name, int namelen);

Modified: GNUnet/src/util/win/win.cc
===================================================================
--- GNUnet/src/util/win/win.cc  2005-03-05 06:56:48 UTC (rev 375)
+++ GNUnet/src/util/win/win.cc  2005-03-05 12:55:22 UTC (rev 376)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2001 - 2004 Christian Grothoff (and other contributing authors)
+     (C) 2001, 2002, 2003, 2004, 2005 Christian Grothoff (and other 
contributing authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -39,12 +39,15 @@
     IPersistFile *pFile;
     WCHAR *pwszDest;
     char *pszFileLnk;
+    HRESULT hRes;
     
     CoInitialize(NULL);
     
     if ((strlen(pszSrc) > _MAX_PATH) || (strlen(pszDest) + 4 > _MAX_PATH))
     {
       CoUninitialize();
+      errno = ENAMETOOLONG;
+      
       return FALSE;
     }
     
@@ -53,6 +56,8 @@
         IID_IShellLink, (void **) &pLink) != S_OK)
     {
       CoUninitialize();
+      errno = ESTALE;
+      
       return FALSE;
     }
   
@@ -65,6 +70,7 @@
       free(pwszDest);
       pLink->Release();
       CoUninitialize();
+      errno = ESTALE;
      
       return FALSE;
     }
@@ -80,12 +86,13 @@
     free(pszFileLnk);
     
     /* Save shortcut */
-    if (pFile->Save((LPCOLESTR) pwszDest, TRUE) != S_OK)
+    if (FAILED(hRes = pFile->Save((LPCOLESTR) pwszDest, TRUE)))
     {
       free(pwszDest);
       pLink->Release();
       pFile->Release();
       CoUninitialize();
+      SetErrnoFromHRESULT(hRes);
   
       return FALSE;
     }
@@ -95,6 +102,7 @@
     pFile->Release();
     pLink->Release();
     CoUninitialize();
+    errno = 0;
       
     return TRUE;
 }
@@ -106,6 +114,7 @@
   WCHAR *pwszShortcut;
   char *pszLnk;
   int iErr, iLen;
+  HRESULT hRes;
 
   CoInitialize(NULL);
   
@@ -114,6 +123,8 @@
       IID_IShellLink, (void **) &pLink) != S_OK)
   {
     CoUninitialize();
+    errno = ESTALE;
+    
     return FALSE;
   }
 
@@ -122,6 +133,7 @@
   {
     pLink->Release();
     CoUninitialize();
+    errno = ESTALE;
     
     return FALSE;
   }
@@ -144,12 +156,13 @@
   free(pszLnk);
   
   /* Open shortcut */
-  if (pFile->Load((LPCOLESTR) pwszShortcut, STGM_READ) != S_OK)
+  if (FAILED(hRes = pFile->Load((LPCOLESTR) pwszShortcut, STGM_READ)))
   {
     pLink->Release();
     pFile->Release();
     free(pwszShortcut);
     CoUninitialize();
+    SetErrnoFromHRESULT(hRes);
     
     return FALSE;
   }
@@ -157,18 +170,24 @@
   free(pwszShortcut);
   
   /* Get target file */
-  if (pLink->GetPath(pszShortcut, _MAX_PATH, NULL, 0) != S_OK)
+  if (FAILED(hRes = pLink->GetPath(pszShortcut, _MAX_PATH, NULL, 0)))
   {
     pLink->Release();
     pFile->Release();
     CoUninitialize();
     
+    if (hRes == E_FAIL)
+      errno = EINVAL; /* Not a symlink */
+    else
+      SetErrnoFromHRESULT(hRes);
+    
     return FALSE;
   }
 
   pFile->Release();
   pLink->Release();
   CoUninitialize();
+  errno = 0;
   
   return TRUE;
 }

Modified: GNUnet/src/util/win/winproc.c
===================================================================
--- GNUnet/src/util/win/winproc.c       2005-03-05 06:56:48 UTC (rev 375)
+++ GNUnet/src/util/win/winproc.c       2005-03-05 12:55:22 UTC (rev 376)
@@ -1253,6 +1253,48 @@
 }
 
 /**
+ * Set errno according to a HRESULT (COM error code)
+ */
+void SetErrnoFromHRESULT(HRESULT hRes)
+{
+  switch(hRes)
+  {
+    case NOERROR:
+      errno = 0;
+      break;
+    case E_UNEXPECTED:
+    case E_FAIL:
+    case S_FALSE:
+      errno = ESTALE;
+    case E_NOTIMPL:
+      errno = ENOSYS;
+      break;
+    case E_OUTOFMEMORY:
+      errno = ENOMEM;
+      break;
+    case E_INVALIDARG:
+    case E_NOINTERFACE:
+      errno = EINVAL;
+      break;
+    case E_POINTER:
+    case E_ABORT:
+      errno = EFAULT;
+      break;
+    case E_HANDLE:
+      errno = EBADF;
+      break;
+    case E_ACCESSDENIED:
+      errno = EACCES;
+      break;
+    case E_PENDING:
+      errno = EBUSY;
+      break;
+    default:
+      SetErrnoFromWinError(HRESULT_CODE(hRes));
+  }
+}
+
+/**
  * Set h_errno according to a Windows error
  * @param lWinError Error code defined in winerror.h
  */
@@ -1584,9 +1626,30 @@
 }
 
 /**
+ * Dereference a symlink recursively
+ */
+int __win_deref(const char *path)
+{
+  int iDepth = 0;
+
+  errno = 0;
+   
+  while (DereferenceShortcut(szFile))
+  {
+    if (iDepth++ > 10)
+    {
+      errno = ELOOP;
+      return -1;
+    }
+  }
+  
+  return errno ? -1 : 0;
+}
+
+/**
  * Get status information on a file
  */
-int _win_stat(const char *path, struct stat *buffer)
+int __win_stat(const char *path, struct stat *buffer, int iDeref)
 {
   char szFile[_MAX_PATH + 1];
   long lRet;
@@ -1604,11 +1667,26 @@
     szFile[lRet] = 0;
   }
   
+  /* Dereference symlinks */
+  if (iDeref)
+  {
+    if (__win_deref(szFile) == -1)
+      return -1;
+  }
+  
   /* stat sets errno */
   return stat(szFile, buffer);
 }
 
 /**
+ * Get status information on a file
+ */
+int _win_stat(const char *path, struct stat *buffer)
+{
+  return __win_stat(szFile, buffer, 1);
+}
+
+/**
  * Delete a file
  * If filename is a link, the link itself it removed.
  */
@@ -1783,9 +1861,8 @@
     return -1;
   }  
   
+  /* CreateShortcut sets errno */
   lRet = CreateShortcut(path1, path2);
-  if (lRet != 1)
-   SetErrnoFromWinError(GetLastError());
   
   return lRet ? 0 : -1;
 }
@@ -1873,6 +1950,44 @@
 }
 
 /**
+ * Get symbolic link status
+ */
+int _win_lstat(const char *path, struct stat *buf)
+{
+  return __win_stat(path, buf, 0);  
+}
+
+/**
+ * Read the contents of a symbolic link
+ */
+int _win_readlink(const char *path, char *buf, size_t bufsize)
+{
+  char szDeref[_MAX_PATH + 1];
+  int iLen;
+
+  if(strlen(path) > _MAX_PATH)
+  {
+    errno = ENAMETOOLONG;
+    return -1;
+  }
+    
+  strcpy(szDeref, path);
+  
+  if (__win_deref(szDeref) == -1)
+    return -1;
+    
+  if ((iLen = strlen(szDeref)) > bufsize)
+  {
+    errno = ENAMETOOLONG;
+    return -1;
+  }
+  
+  errno = 0;
+  return iLen;
+}
+
+
+/**
  * Accepts an incoming connection attempt on a socket
  */
 int _win_accept(SOCKET s, struct sockaddr *addr, int *addrlen)





reply via email to

[Prev in Thread] Current Thread [Next in Thread]