view common/portpath.c @ 1303:78637257f547

Merged.
author Emanuel Schuetze <emanuel@intevation.de>
date Mon, 29 Sep 2014 16:38:09 +0200
parents 0a803c3fb5a6
children 64333dad503b
line wrap: on
line source
/* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik
 * Software engineering by Intevation GmbH
 *
 * This file is Free Software under the GNU GPL (v>=2)
 * and comes with ABSOLUTELY NO WARRANTY!
 * See LICENSE.txt for details.
 */
#include "portpath.h"
#include "strhelp.h"
#include "util.h"
#include "logging.h"

#include <libgen.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>

#ifdef WIN32
#include <share.h>
#endif

char *
port_dirname(char *path)
{
#ifndef _WIN32
  return dirname(path);
#else
  char drive[_MAX_DRIVE];
  char dir[_MAX_DIR];
  _splitpath(path, drive, dir, NULL, NULL);
  size_t dlen = strlen(dir);
  if ((dlen > 0) &&
      ((dir[dlen-1] == '/') || (dir[dlen-1] == '\\')))
    dir[dlen-1] = '\0';
  /* We assume: drive + dir is shorter than
   * drive + dir + fname + ext */
  sprintf(path, "%s%s", drive, dir);
  return path;
#endif
}

bool
port_mkdir(const char *path, bool propagate_acl)
{
#ifndef _WIN32
  if (propagate_acl)
    {
      DEBUGPRINTF("WARNING: ACL propagation only has an effect on Windows.\n");
    }
  return mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == 0;
#else
  wchar_t *wchar_path = utf8_to_wchar(path, strlen(path));
  bool ret;

  if (!wchar_path)
    {
      return false;
    }
  ret = create_restricted_directory (wchar_path, propagate_acl, NULL);
  xfree (wchar_path);
  return ret;
#endif
}

char *
port_realpath(const char *path)
{
#ifndef _WIN32
  return realpath(path, NULL);
#else
  char *fp = _fullpath(NULL, path, 0);
  if (port_fileexits(fp))
    return fp;
  else
    return NULL;
#endif
}

bool
port_fileexits(char *path)
{
  int ret;
#ifndef _WIN32
  struct stat sb;
  ret = stat(path, &sb);
#else
  struct _stat sb;
  ret = _stat(path, &sb);
#endif

  if (ret == 0)
    return true;
  else
    return false;
}

bool
port_mkdir_p(const char *path, bool propagate_acl)
{
  char *parent_path,
       *p;
  if (!path) {
      return false;
  }
  if (port_isdir(path)) {
      return true;
  }
  parent_path = xstrndup (path, strlen(path));
  p = strrchr(parent_path, '/');
  if (!p)
    {
      p = strrchr(parent_path, '\\');
    }
  if (!p)
    {
      return false;
    }
  *p = '\0';
  if (!port_isdir(parent_path))
    {
      port_mkdir_p(parent_path, false);
    }
  return port_mkdir(path, propagate_acl);
}

bool
port_isdir(const char *path)
{
  int ret;
#ifndef _WIN32
  struct stat sb;
  ret = stat(path, &sb);
#else
  struct _stat sb;
  ret = _stat(path, &sb);
#endif

  if ((ret == 0) && S_ISDIR(sb.st_mode))
    return true;
  else
    return false;
}

FILE*
port_fopen_rb(const char *path, bool exclusive)
{
  FILE *f = NULL;
  if (!path)
    {
      return NULL;
    }
#ifdef WIN32
    {
      wchar_t *wFilename = utf8_to_wchar(path, strlen(path));
      if (!wFilename)
        {
          ERRORPRINTF ("Invalid encoding\n");
          return NULL;
        }
      /* We open and write protect the file here so that
         as long as the file is open we can be sure that
         it was not modified and can use it in subsequent
         calls based on the filename. */
      OutputDebugStringW(wFilename);
      if (exclusive)
        {
          f = _wfsopen(wFilename, L"rb", _SH_DENYWR);
        }
      else
        {
          f = _wfopen(wFilename, L"rb");
        }
      xfree(wFilename);
      if (f == NULL)
        {
          /* Fall back to local8 bit encoding */
          if (exclusive)
            {
              f = _fsopen(path, "rb", _SH_DENYWR);
            }
          else
            {
              f = fopen(path, "rb");
            }
        }
    }
#else
  (void)(exclusive);
  f = fopen(path, "rb");
#endif
  return f;
}

http://wald.intevation.org/projects/trustbridge/