added file copy tree for the game packs - lists supported games
[xonotic/netradiant.git] / radiant / missing.cpp
index cf1c5b2d3a83ce0214f509f3998e2fa62898e5fd..522980cdb470a24ee8ef8af1f2122ae6251b86c4 100644 (file)
-/*\r
-Copyright (c) 2001, Loki software, inc.\r
-All rights reserved.\r
-\r
-Redistribution and use in source and binary forms, with or without modification, \r
-are permitted provided that the following conditions are met:\r
-\r
-Redistributions of source code must retain the above copyright notice, this list \r
-of conditions and the following disclaimer.\r
-\r
-Redistributions in binary form must reproduce the above copyright notice, this\r
-list of conditions and the following disclaimer in the documentation and/or\r
-other materials provided with the distribution.\r
-\r
-Neither the name of Loki software nor the names of its contributors may be used \r
-to endorse or promote products derived from this software without specific prior \r
-written permission. \r
-\r
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' \r
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \r
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE \r
-DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY \r
-DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS \r
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \r
-*/\r
-\r
-//\r
-// Missing functions\r
-//\r
-// Leonardo Zide (leo@lokigames.com)\r
-//\r
-\r
-#if defined (__linux__) || defined (__APPLE__)\r
-\r
-#include <stdio.h>\r
-#include <unistd.h>\r
-#include <sys/time.h>\r
-#include <stdlib.h>\r
-#include "missing.h"\r
-\r
-bool CopyFile(const char *lpExistingFileName, const char *lpNewFileName)\r
-{\r
-  FILE *src, *dst;\r
-  void* buf;\r
-  int l, ret = 0;\r
-  char realsrc[PATH_MAX], realdest[PATH_MAX];\r
-\r
-  realpath (lpExistingFileName, realsrc);\r
-  realpath (lpNewFileName, realdest);\r
-\r
-  src = fopen (realsrc, "rb");\r
-  if (!src)\r
-    return 0;\r
-  dst = fopen (realdest, "wb");\r
-  if (!dst)\r
-  {\r
-    fclose (src);\r
-    return 0;\r
-  }\r
\r
-  fseek (src, 0, SEEK_END);\r
-  l = ftell (src);\r
-  rewind (src);\r
-  buf = g_malloc (l);\r
-\r
-  if (buf != NULL)\r
-    if (fread (buf, l, 1, src) == 1)\r
-      if (fwrite (buf, l, 1, dst) == 1)\r
-       ret = 1;\r
-\r
-  g_free (buf);\r
-  fclose (src);\r
-  fclose (dst);\r
-\r
-  return ret;\r
-}\r
-\r
-int GetFullPathName(const char *lpFileName, int nBufferLength, char *lpBuffer, char **lpFilePart)\r
-{\r
-  if (lpFileName[0] == '/')\r
-  {\r
-    strcpy (lpBuffer, lpFileName);\r
-    *lpFilePart = strrchr (lpBuffer, '/');\r
-    return strlen (lpBuffer);\r
-  }\r
-\r
-  if (getcwd (lpBuffer, nBufferLength) == NULL)\r
-    return 0;\r
-\r
-  strcat (lpBuffer, "/");\r
-  *lpFilePart = lpBuffer + strlen (lpBuffer);\r
-  strcat (lpBuffer, lpFileName);\r
-\r
-  char *scr = lpBuffer, *dst = lpBuffer;\r
-  for (int i = 0; (i < nBufferLength) && (*scr != 0); i++)\r
-  {\r
-    if (*scr == '/' && *(scr+1) == '.' && *(scr+2) == '.')\r
-    {\r
-      scr += 4;\r
-      while (dst != lpBuffer && *dst != '/')\r
-      {\r
-       dst--;\r
-       i--;\r
-      }\r
-    }\r
-\r
-    *dst = *scr;\r
-\r
-    scr++; dst++;\r
-  }\r
-  *dst = 0;\r
-\r
-  return strlen (lpBuffer);\r
-}\r
-/*\r
-static void g_string_sprintfa_int (GString *string, const gchar *fmt, va_list args)\r
-{\r
-  gchar *buffer;\r
-\r
-  buffer = g_strdup_vprintf (fmt, args);\r
-  g_string_append (string, buffer);\r
-  g_free (buffer);\r
-}\r
-\r
-const CString& CString::operator=(const char* lpsz)\r
-{\r
-  g_string_assign (m_str, lpsz);\r
-  return *this;\r
-}\r
-\r
-const CString& CString::operator+=(const char* lpsz)\r
-{\r
-  g_string_append (m_str, lpsz);\r
-  return *this;\r
-}\r
-\r
-CString::operator char*() const\r
-{ \r
-  return m_str->str;\r
-}\r
-\r
-void CString::Format(const char* fmt, ...)\r
-{\r
-  va_list args;\r
\r
-  g_string_truncate (m_str, 0);\r
\r
-  va_start (args, fmt);\r
-  g_string_sprintfa_int (m_str, fmt, args);\r
-  va_end (args);\r
-}\r
-\r
-CString CString::Right(int nCount) const\r
-{\r
-  if (nCount < 0)\r
-    nCount = 0;\r
-  else if (nCount > m_str->len)\r
-    nCount = m_str->len;\r
-\r
-  CString dest (&m_str->str[m_str->len-nCount]);\r
-  return dest;\r
-}\r
-\r
-CString CString::Left(int nCount) const\r
-{\r
-  if (nCount < 0)\r
-    nCount = 0;\r
-  else if (nCount > m_str->len)\r
-    nCount = m_str->len;\r
-\r
-  CString dest;\r
-  dest.m_str = g_string_sized_new (nCount);\r
-  memcpy (dest.m_str->str, m_str->str, nCount);\r
-  dest.m_str->str[nCount] = 0;\r
-  return dest;\r
-}\r
-\r
-void CString::SetAt(int nIndex, char ch)\r
-{\r
-  if (nIndex >= 0 && nIndex < m_str->len)\r
-    m_str->str[nIndex] = ch;\r
-}\r
-\r
-char CString::GetAt(int nIndex) const\r
-{\r
-  if (nIndex >= 0 && nIndex < m_str->len)\r
-    return m_str->str[nIndex];\r
-  return 0;\r
-}\r
-\r
-char CString::operator[](int nIndex) const\r
-{\r
-  if (nIndex >= 0 && nIndex < m_str->len)\r
-    return m_str->str[nIndex];\r
-  return 0;\r
-}\r
-*/\r
-\r
-#endif\r
+/*
+Copyright (c) 2001, Loki software, inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, 
+are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list 
+of conditions and the following disclaimer.
+
+Redistributions in binary form must reproduce the above copyright notice, this
+list of conditions and the following disclaimer in the documentation and/or
+other materials provided with the distribution.
+
+Neither the name of Loki software nor the names of its contributors may be used 
+to endorse or promote products derived from this software without specific prior 
+written permission. 
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY 
+DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+*/
+
+//
+// Missing functions
+//
+// Leonardo Zide (leo@lokigames.com)
+//
+
+#if defined (__linux__) || defined (__APPLE__)
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include "missing.h"
+#include "qsysprintf.h"
+
+bool CopyFile(const char *lpExistingFileName, const char *lpNewFileName)
+{
+  FILE *src, *dst;
+  void* buf;
+  int l;
+  bool ret = false;
+  char realsrc[PATH_MAX], realdest[PATH_MAX];
+
+  realpath (lpExistingFileName, realsrc);
+  realpath (lpNewFileName, realdest);
+
+  src = fopen (realsrc, "rb");
+  if ( !src ) {
+    return false;
+  }
+  dst = fopen (realdest, "wb");
+  if (!dst) {
+    fclose (src);
+    return false;
+  }
+  fseek (src, 0, SEEK_END);
+  l = ftell (src);
+  rewind (src);
+  buf = g_malloc (l);
+
+  if (buf != NULL)
+    if (fread (buf, l, 1, src) == 1)
+      if (fwrite (buf, l, 1, dst) == 1)
+       ret = true;
+
+  g_free (buf);
+  fclose (src);
+  fclose (dst);
+
+  return ret;
+}
+
+bool CreateDirectory( const char *directory ) {
+       if ( mkdir( directory, 0777 ) == -1 ) {
+               Sys_Printf( "mkdir %s failed\n", directory );
+               return false;
+       }
+       return true;
+}
+
+bool CopyTree( const char *source, const char *dest ) {
+       DIR                             *dir;
+       struct dirent   *dirlist;
+       struct stat             sbuf;
+       Str                             srcEntry;
+       Str                             dstEntry;
+
+       dir = opendir( source );
+       if ( dir != NULL ) {
+               while ( ( dirlist = readdir( dir ) ) != NULL ) {
+                       if ( strcmp( dirlist->d_name, "." ) == 0 || strcmp( dirlist->d_name, ".." ) == 0 ) {
+                               continue;
+                       }
+                       if ( strcmp( dirlist->d_name, ".svn" ) == 0 ) {
+                               continue;
+                       }
+                       srcEntry = source;
+                       srcEntry += "/";
+                       srcEntry += dirlist->d_name;
+                       dstEntry = dest;
+                       dstEntry += "/";
+                       dstEntry += dirlist->d_name;
+                       if ( stat( srcEntry.GetBuffer(), &sbuf ) == -1 ) {
+                               Sys_Printf( "stat %s failed\n", srcEntry.GetBuffer() );
+                       }
+                       if ( S_ISDIR( sbuf.st_mode ) ) {
+                               bool ret;
+                               if ( stat( dstEntry.GetBuffer(), &sbuf ) == -1 ) {
+                                       ret = CreateDirectory( dstEntry.GetBuffer() );
+                               }
+                               ret = CopyTree( srcEntry.GetBuffer(), dstEntry.GetBuffer() );
+                               if ( !ret ) {
+                                       return false;
+                               }
+                       } else {
+                               Sys_Printf( "copy %s -> %s\n", srcEntry.GetBuffer(), dstEntry.GetBuffer() );
+                               bool ret = CopyFile( srcEntry.GetBuffer(), dstEntry.GetBuffer() );
+                               if ( !ret ) {
+                                       return false;
+                               }
+                       }
+               }
+               closedir( dir );
+       }
+       return true;
+}
+
+int GetFullPathName(const char *lpFileName, int nBufferLength, char *lpBuffer, char **lpFilePart)
+{
+  if (lpFileName[0] == '/')
+  {
+    strcpy (lpBuffer, lpFileName);
+    *lpFilePart = strrchr (lpBuffer, '/');
+    return strlen (lpBuffer);
+  }
+
+  if (getcwd (lpBuffer, nBufferLength) == NULL)
+    return 0;
+
+  strcat (lpBuffer, "/");
+  *lpFilePart = lpBuffer + strlen (lpBuffer);
+  strcat (lpBuffer, lpFileName);
+
+  char *scr = lpBuffer, *dst = lpBuffer;
+  for (int i = 0; (i < nBufferLength) && (*scr != 0); i++)
+  {
+    if (*scr == '/' && *(scr+1) == '.' && *(scr+2) == '.')
+    {
+      scr += 4;
+      while (dst != lpBuffer && *dst != '/')
+      {
+       dst--;
+       i--;
+      }
+    }
+
+    *dst = *scr;
+
+    scr++; dst++;
+  }
+  *dst = 0;
+
+  return strlen (lpBuffer);
+}
+
+#endif