[rename] renamed kdbus related macros
[platform/upstream/dbus.git] / dbus / dbus-sysdeps-util-win.c
index b9ebc82..4678b11 100644 (file)
@@ -22,6 +22,8 @@
  *
  */
 
+#include <config.h>
+
 #define STRSAFE_NO_DEPRECATE
 
 #include "dbus-sysdeps.h"
 #include "dbus-sysdeps-win.h"
 #include "dbus-sockets-win.h"
 #include "dbus-memory.h"
-
-#include <io.h>
-#include <sys/stat.h>
-#include <aclapi.h>
-#include <winsock2.h>
+#include "dbus-pipe.h"
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <fcntl.h>
+#if HAVE_ERRNO_H
 #include <errno.h>
+#endif
 #include <winsock2.h>   // WSA error codes
 
+#ifndef DBUS_WINCE
+#include <io.h>
+#include <lm.h>
+#include <sys/stat.h>
+#endif
+
+
 /**
  * Does the chdir, fork, setsid, etc. to become a daemon process.
  *
  * @param pidfile #NULL, or pidfile to create
- * @param print_pid_fd file descriptor to print daemon's pid to, or -1 for none
+ * @param print_pid_pipe file descriptor to print daemon's pid to, or -1 for none
  * @param error return location for errors
  * @param keep_umask #TRUE to keep the original umask
  * @returns #FALSE on failure
@@ -59,7 +65,9 @@ _dbus_become_daemon (const DBusString *pidfile,
                      DBusError        *error,
                      dbus_bool_t       keep_umask)
 {
-  return TRUE;
+  dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED,
+                  "Cannot daemonize on Windows");
+  return FALSE;
 }
 
 /**
@@ -76,44 +84,70 @@ _dbus_write_pid_file (const DBusString *filename,
                       DBusError        *error)
 {
   const char *cfilename;
-  int fd;
-  FILE *f;
+  HANDLE hnd;
+  char pidstr[20];
+  int total;
+  int bytes_to_write;
+
+  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 
   cfilename = _dbus_string_get_const_data (filename);
-  
-  fd = _open (cfilename, O_WRONLY|O_CREAT|O_EXCL|O_BINARY, 0644);
-  
-  if (fd < 0)
+
+  hnd = CreateFileA (cfilename, GENERIC_WRITE,
+                     FILE_SHARE_READ | FILE_SHARE_WRITE,
+                     NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL,
+                     INVALID_HANDLE_VALUE);
+  if (hnd == INVALID_HANDLE_VALUE)
     {
-      dbus_set_error (error, _dbus_error_from_errno (errno),
-                      "Failed to open \"%s\": %s", cfilename,
-                      strerror (errno));
+      char *emsg = _dbus_win_error_string (GetLastError ());
+      dbus_set_error (error, _dbus_win_error_from_last_error (),
+                      "Could not create PID file %s: %s",
+                      cfilename, emsg);
+      _dbus_win_free_error_string (emsg);
       return FALSE;
     }
 
-  if ((f = fdopen (fd, "w")) == NULL)
+  if (snprintf (pidstr, sizeof (pidstr), "%lu\n", pid) < 0)
     {
-      dbus_set_error (error, _dbus_error_from_errno (errno),
-                      "Failed to fdopen fd %d: %s", fd, strerror (errno));
-      _close (fd);
+      dbus_set_error (error, _dbus_error_from_system_errno (),
+                      "Failed to format PID for \"%s\": %s", cfilename,
+                      _dbus_strerror_from_errno ());
+      CloseHandle (hnd);
       return FALSE;
     }
 
-  if (fprintf (f, "%lu\n", pid) < 0)
+  total = 0;
+  bytes_to_write = strlen (pidstr);;
+
+  while (total < bytes_to_write)
     {
-      dbus_set_error (error, _dbus_error_from_errno (errno),
-                      "Failed to write to \"%s\": %s", cfilename,
-                      strerror (errno));
+      DWORD bytes_written;
+      BOOL res;
 
-      fclose (f);
-      return FALSE;
+      res = WriteFile (hnd, pidstr + total, bytes_to_write - total,
+                       &bytes_written, NULL);
+
+      if (res == 0 || bytes_written <= 0)
+        {
+          char *emsg = _dbus_win_error_string (GetLastError ());
+          dbus_set_error (error, _dbus_win_error_from_last_error (),
+                           "Could not write to %s: %s", cfilename, emsg);
+          _dbus_win_free_error_string (emsg);
+          CloseHandle (hnd);
+          return FALSE;
+        }
+
+      total += bytes_written;
     }
 
-  if (fclose (f) == EOF)
+  if (CloseHandle (hnd) == 0)
     {
-      dbus_set_error (error, _dbus_error_from_errno (errno),
-                      "Failed to close \"%s\": %s", cfilename,
-                      strerror (errno));
+      char *emsg = _dbus_win_error_string (GetLastError ());
+      dbus_set_error (error, _dbus_win_error_from_last_error (),
+                       "Could not close file %s: %s",
+                      cfilename, emsg);
+      _dbus_win_free_error_string (emsg);
+
       return FALSE;
     }
 
@@ -159,7 +193,7 @@ _dbus_write_pid_to_file_and_pipe (const DBusString *pidfile,
       DBusString pid;
       int bytes;
 
-      _dbus_verbose ("writing our pid to pipe %d\n", print_pid_pipe->fd_or_handle);
+      _dbus_verbose ("writing our pid to pipe %d\n", print_pid_pipe->fd);
 
       if (!_dbus_string_init (&pid))
         {
@@ -225,35 +259,63 @@ _dbus_change_to_daemon_user  (const char    *user,
 }
 
 void
-_dbus_init_system_log (void)
+_dbus_request_file_descriptor_limit (unsigned int limit)
+{
+}
+
+void
+_dbus_init_system_log (dbus_bool_t is_daemon)
 {
-    // FIXME!
+  /* OutputDebugStringA doesn't need any special initialization, do nothing */
 }
 
 /**
- * Log an informative message.  Intended for use primarily by
- * the system bus.
+ * Log a message to the system log file (e.g. syslog on Unix).
  *
+ * @param severity a severity value
  * @param msg a printf-style format string
- * @param args arguments for the format string
  */
 void
-_dbus_log_info (const char *msg, va_list args)
+_dbus_system_log (DBusSystemLogSeverity severity, const char *msg, ...)
 {
-    // FIXME!
+  va_list args;
+
+  va_start (args, msg);
+
+  _dbus_system_logv (severity, msg, args);
+
+  va_end (args);
 }
 
 /**
- * Log a security-related message.  Intended for use primarily by
- * the system bus.
+ * Log a message to the system log file (e.g. syslog on Unix).
  *
+ * @param severity a severity value
  * @param msg a printf-style format string
  * @param args arguments for the format string
+ *
+ * If the FATAL severity is given, this function will terminate the program
+ * with an error code.
  */
 void
-_dbus_log_security (const char *msg, va_list args)
+_dbus_system_logv (DBusSystemLogSeverity severity, const char *msg, va_list args)
 {
-    // FIXME!
+  char *s = "";
+  char buf[1024];
+  
+  switch(severity) 
+   {
+     case DBUS_SYSTEM_LOG_INFO: s = "info"; break;
+     case DBUS_SYSTEM_LOG_SECURITY: s = "security"; break;
+     case DBUS_SYSTEM_LOG_FATAL: s = "fatal"; break;
+   }
+   
+  sprintf(buf,"%s%s",s,msg);
+  vsprintf(buf,buf,args);
+  OutputDebugStringA(buf);
+  
+  if (severity == DBUS_SYSTEM_LOG_FATAL)
+    exit (1);
 }
 
 /** Installs a signal handler
@@ -281,22 +343,16 @@ _dbus_stat(const DBusString *filename,
            DBusStat         *statbuf,
            DBusError        *error)
 {
-#ifdef DBUS_WINCE
-       return TRUE;
-       //TODO
-#else
   const char *filename_c;
   WIN32_FILE_ATTRIBUTE_DATA wfad;
   char *lastdot;
   DWORD rc;
-  PSID owner_sid, group_sid;
-  PSECURITY_DESCRIPTOR sd;
 
   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 
   filename_c = _dbus_string_get_const_data (filename);
 
-  if (!GetFileAttributesEx (filename_c, GetFileExInfoStandard, &wfad))
+  if (!GetFileAttributesExA (filename_c, GetFileExInfoStandard, &wfad))
     {
       _dbus_win_set_error_from_win_error (error, GetLastError ());
       return FALSE;
@@ -320,28 +376,36 @@ _dbus_stat(const DBusString *filename,
 
   statbuf->nlink = 1;
 
-  sd = NULL;
-  rc = GetNamedSecurityInfo ((char *) filename_c, SE_FILE_OBJECT,
-                             OWNER_SECURITY_INFORMATION |
-                             GROUP_SECURITY_INFORMATION,
-                             &owner_sid, &group_sid,
-                             NULL, NULL,
-                             &sd);
-  if (rc != ERROR_SUCCESS)
-    {
-      _dbus_win_set_error_from_win_error (error, rc);
-      if (sd != NULL)
-        LocalFree (sd);
-      return FALSE;
-    }
-
 #ifdef ENABLE_UID_TO_SID
-  /* FIXME */
-  statbuf->uid = _dbus_win_sid_to_uid_t (owner_sid);
-  statbuf->gid = _dbus_win_sid_to_uid_t (group_sid);
-#endif
+  {
+    PSID owner_sid, group_sid;
+    PSECURITY_DESCRIPTOR sd;
+
+    sd = NULL;
+    rc = GetNamedSecurityInfo ((char *) filename_c, SE_FILE_OBJECT,
+                               OWNER_SECURITY_INFORMATION |
+                               GROUP_SECURITY_INFORMATION,
+                               &owner_sid, &group_sid,
+                               NULL, NULL,
+                               &sd);
+    if (rc != ERROR_SUCCESS)
+      {
+        _dbus_win_set_error_from_win_error (error, rc);
+        if (sd != NULL)
+          LocalFree (sd);
+        return FALSE;
+      }
+    
+    /* FIXME */
+    statbuf->uid = _dbus_win_sid_to_uid_t (owner_sid);
+    statbuf->gid = _dbus_win_sid_to_uid_t (group_sid);
 
-  LocalFree (sd);
+    LocalFree (sd);
+  }
+#else
+  statbuf->uid = DBUS_UID_UNSET;
+  statbuf->gid = DBUS_GID_UNSET;
+#endif
 
   statbuf->size = ((dbus_int64_t) wfad.nFileSizeHigh << 32) + wfad.nFileSizeLow;
 
@@ -358,27 +422,9 @@ _dbus_stat(const DBusString *filename,
      wfad.ftCreationTime.dwLowDateTime) / 10000000 - DBUS_INT64_CONSTANT (116444736000000000);
 
   return TRUE;
-#endif //DBUS_WINCE
 }
 
 
-#ifdef HAVE_DIRENT_H
-
-// mingw ships with dirent.h
-#include <dirent.h>
-#define _dbus_opendir opendir
-#define _dbus_readdir readdir
-#define _dbus_closedir closedir
-
-#else
-
-#ifdef HAVE_IO_H
-#include <io.h> // win32 file functions
-#endif
-
-#include <sys/types.h>
-#include <stdlib.h>
-
 /* This file is part of the KDE project
 Copyright (C) 2000 Werner Almesberger
 
@@ -418,10 +464,10 @@ struct dirent
 /* typedef DIR - not the same as Unix */
 typedef struct
   {
-    long handle;                /* _findfirst/_findnext handle */
-    short offset;                /* offset into directory */
+    HANDLE handle;              /* FindFirst/FindNext handle */
+    short offset;               /* offset into directory */
     short finished;             /* 1 if there are not more files */
-    struct _finddata_t fileinfo;  /* from _findfirst/_findnext */
+    WIN32_FIND_DATAA fileinfo;  /* from FindFirst/FindNext */
     char *dir;                  /* the dir we are reading */
     struct dirent dent;         /* the dirent to return */
   }
@@ -437,6 +483,8 @@ DIR;
 * The dirent struct is compatible with Unix, except that d_ino is
 * always 1 and d_off is made up as we go along.
 *
+* Error codes are not available with errno but GetLastError.
+*
 * The DIR typedef is not compatible with Unix.
 **********************************************************************/
 
@@ -444,7 +492,7 @@ static DIR * _dbus_opendir(const char *dir)
 {
   DIR *dp;
   char *filespec;
-  long handle;
+  HANDLE handle;
   int index;
 
   filespec = malloc(strlen(dir) + 2 + 1);
@@ -459,9 +507,10 @@ static DIR * _dbus_opendir(const char *dir)
   dp->finished = 0;
   dp->dir = strdup(dir);
 
-  if ((handle = _findfirst(filespec, &(dp->fileinfo))) < 0)
+  handle = FindFirstFileA(filespec, &(dp->fileinfo));
+  if (handle == INVALID_HANDLE_VALUE)
     {
-      if (errno == ENOENT)
+      if (GetLastError() == ERROR_NO_MORE_FILES)
         dp->finished = 1;
       else
         return NULL;
@@ -474,35 +523,40 @@ static DIR * _dbus_opendir(const char *dir)
 }
 
 static struct dirent * _dbus_readdir(DIR *dp)
-  {
-    if (!dp || dp->finished)
-      return NULL;
-
-    if (dp->offset != 0)
-      {
-        if (_findnext(dp->handle, &(dp->fileinfo)) < 0)
-          {
-            dp->finished = 1;
-            errno = 0;
-            return NULL;
-          }
-      }
-    dp->offset++;
+{
+  int saved_err = GetLastError();
 
-    strncpy(dp->dent.d_name, dp->fileinfo.name, _MAX_FNAME);
-    dp->dent.d_ino = 1;
-    dp->dent.d_reclen = strlen(dp->dent.d_name);
-    dp->dent.d_off = dp->offset;
+  if (!dp || dp->finished)
+    return NULL;
 
-    return &(dp->dent);
-  }
+  if (dp->offset != 0)
+    {
+      if (FindNextFileA(dp->handle, &(dp->fileinfo)) == 0)
+        {
+          if (GetLastError() == ERROR_NO_MORE_FILES)
+            {
+              SetLastError(saved_err);
+              dp->finished = 1;
+            }
+          return NULL;
+        }
+    }
+  dp->offset++;
+  
+  strncpy(dp->dent.d_name, dp->fileinfo.cFileName, _MAX_FNAME);
+  dp->dent.d_ino = 1;
+  dp->dent.d_reclen = strlen(dp->dent.d_name);
+  dp->dent.d_off = dp->offset;
+  
+  return &(dp->dent);
+}
 
 
 static int _dbus_closedir(DIR *dp)
 {
   if (!dp)
     return 0;
-  _findclose(dp->handle);
+  FindClose(dp->handle);
   if (dp->dir)
     free(dp->dir);
   if (dp)
@@ -511,7 +565,6 @@ static int _dbus_closedir(DIR *dp)
   return 0;
 }
 
-#endif //#ifdef HAVE_DIRENT_H
 
 /**
  * Internals of directory iterator
@@ -544,10 +597,11 @@ _dbus_directory_open (const DBusString *filename,
   d = _dbus_opendir (filename_c);
   if (d == NULL)
     {
-      dbus_set_error (error, _dbus_error_from_errno (errno),
+      char *emsg = _dbus_win_error_string (GetLastError ());
+      dbus_set_error (error, _dbus_win_error_from_last_error (),
                       "Failed to read directory \"%s\": %s",
-                      filename_c,
-                      _dbus_strerror (errno));
+                      filename_c, emsg);
+      _dbus_win_free_error_string (emsg);
       return NULL;
     }
   iter = dbus_new0 (DBusDirIter, 1);
@@ -587,14 +641,17 @@ _dbus_directory_get_next_file (DBusDirIter      *iter,
   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 
 again:
-  errno = 0;
+  SetLastError (0);
   ent = _dbus_readdir (iter->d);
   if (ent == NULL)
     {
-      if (errno != 0)
-        dbus_set_error (error,
-                        _dbus_error_from_errno (errno),
-                        "%s", _dbus_strerror (errno));
+      if (GetLastError() != 0)
+        {
+          char *emsg = _dbus_win_error_string (GetLastError ());
+          dbus_set_error (error, _dbus_win_error_from_last_error (),
+                          "Failed to get next in directory: %s", emsg);
+          _dbus_win_free_error_string (emsg);
+        }
       return FALSE;
     }
   else if (ent->d_name[0] == '.' &&
@@ -625,23 +682,6 @@ _dbus_directory_close (DBusDirIter *iter)
   dbus_free (iter);
 }
 
-/**
- * Checks whether the filename is an absolute path
- *
- * @param filename the filename
- * @returns #TRUE if an absolute path
- */
-dbus_bool_t
-_dbus_path_is_absolute (const DBusString *filename)
-{
-  if (_dbus_string_get_length (filename) > 0)
-    return _dbus_string_get_byte (filename, 1) == ':'
-           || _dbus_string_get_byte (filename, 0) == '\\'
-           || _dbus_string_get_byte (filename, 0) == '/';
-  else
-    return FALSE;
-}
-
 /** @} */ /* End of DBusInternalsUtils functions */
 
 /**
@@ -1490,3 +1530,207 @@ _dbus_command_for_pid (unsigned long  pid,
   // FIXME
   return FALSE;
 }
+
+/*
+ * replaces the term DBUS_PREFIX in configure_time_path by the
+ * current dbus installation directory. On unix this function is a noop
+ *
+ * @param configure_time_path
+ * @return real path
+ */
+const char *
+_dbus_replace_install_prefix (const char *configure_time_path)
+{
+#ifndef DBUS_PREFIX
+  return configure_time_path;
+#else
+  static char retval[1000];
+  static char runtime_prefix[1000];
+  int len = 1000;
+  int i;
+
+  if (!configure_time_path)
+    return NULL;
+
+  if ((!_dbus_get_install_root(runtime_prefix, len) ||
+       strncmp (configure_time_path, DBUS_PREFIX "/",
+                strlen (DBUS_PREFIX) + 1))) {
+     strcat (retval, configure_time_path);
+     return retval;
+  }
+
+  strcpy (retval, runtime_prefix);
+  strcat (retval, configure_time_path + strlen (DBUS_PREFIX) + 1);
+
+  /* Somehow, in some situations, backslashes get collapsed in the string.
+   * Since windows C library accepts both forward and backslashes as
+   * path separators, convert all backslashes to forward slashes.
+   */
+
+  for(i = 0; retval[i] != '\0'; i++) {
+    if(retval[i] == '\\')
+      retval[i] = '/';
+  }
+  return retval;
+#endif
+}
+
+/**
+ * return the relocated DATADIR
+ *
+ * @returns relocated DATADIR static string
+ */
+
+static const char *
+_dbus_windows_get_datadir (void)
+{
+       return _dbus_replace_install_prefix(DBUS_DATADIR);
+}
+
+#undef DBUS_DATADIR
+#define DBUS_DATADIR _dbus_windows_get_datadir ()
+
+
+#define DBUS_STANDARD_SESSION_SERVICEDIR "/dbus-1/services"
+#define DBUS_STANDARD_SYSTEM_SERVICEDIR "/dbus-1/system-services"
+
+/**
+ * Returns the standard directories for a session bus to look for service
+ * activation files
+ *
+ * On Windows this should be data directories:
+ *
+ * %CommonProgramFiles%/dbus
+ *
+ * and
+ *
+ * relocated DBUS_DATADIR
+ *
+ * @param dirs the directory list we are returning
+ * @returns #FALSE on OOM
+ */
+
+dbus_bool_t
+_dbus_get_standard_session_servicedirs (DBusList **dirs)
+{
+  const char *common_progs;
+  DBusString servicedir_path;
+
+  if (!_dbus_string_init (&servicedir_path))
+    return FALSE;
+
+#ifdef DBUS_WINCE
+  {
+    /* On Windows CE, we adjust datadir dynamically to installation location.  */
+    const char *data_dir = _dbus_getenv ("DBUS_DATADIR");
+
+    if (data_dir != NULL)
+      {
+        if (!_dbus_string_append (&servicedir_path, data_dir))
+          goto oom;
+
+        if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
+          goto oom;
+      }
+  }
+#else
+/*
+ the code for accessing services requires absolute base pathes
+ in case DBUS_DATADIR is relative make it absolute
+*/
+#ifdef DBUS_WIN
+  {
+    DBusString p;
+
+    _dbus_string_init_const (&p, DBUS_DATADIR);
+
+    if (!_dbus_path_is_absolute (&p))
+      {
+        char install_root[1000];
+        if (_dbus_get_install_root (install_root, sizeof(install_root)))
+          if (!_dbus_string_append (&servicedir_path, install_root))
+            goto oom;
+      }
+  }
+#endif
+  if (!_dbus_string_append (&servicedir_path, DBUS_DATADIR))
+    goto oom;
+
+  if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
+    goto oom;
+#endif
+
+  common_progs = _dbus_getenv ("CommonProgramFiles");
+
+  if (common_progs != NULL)
+    {
+      if (!_dbus_string_append (&servicedir_path, common_progs))
+        goto oom;
+
+      if (!_dbus_string_append (&servicedir_path, _DBUS_PATH_SEPARATOR))
+        goto oom;
+    }
+
+  if (!_dbus_split_paths_and_append (&servicedir_path,
+                               DBUS_STANDARD_SESSION_SERVICEDIR,
+                               dirs))
+    goto oom;
+
+  _dbus_string_free (&servicedir_path);
+  return TRUE;
+
+ oom:
+  _dbus_string_free (&servicedir_path);
+  return FALSE;
+}
+
+/**
+ * Returns the standard directories for a system bus to look for service
+ * activation files
+ *
+ * On UNIX this should be the standard xdg freedesktop.org data directories:
+ *
+ * XDG_DATA_DIRS=${XDG_DATA_DIRS-/usr/local/share:/usr/share}
+ *
+ * and
+ *
+ * DBUS_DATADIR
+ *
+ * On Windows there is no system bus and this function can return nothing.
+ *
+ * @param dirs the directory list we are returning
+ * @returns #FALSE on OOM
+ */
+
+dbus_bool_t
+_dbus_get_standard_system_servicedirs (DBusList **dirs)
+{
+  *dirs = NULL;
+  return TRUE;
+}
+
+/**
+ * Append the absolute path of the system.conf file
+ * (there is no system bus on Windows so this can just
+ * return FALSE and print a warning or something)
+ *
+ * @param str the string to append to
+ * @returns #FALSE if no memory
+ */
+dbus_bool_t
+_dbus_append_system_config_file (DBusString *str)
+{
+  return _dbus_get_config_file_name(str, "system.conf");
+}
+
+/**
+ * Append the absolute path of the session.conf file.
+ *
+ * @param str the string to append to
+ * @returns #FALSE if no memory
+ */
+dbus_bool_t
+_dbus_append_session_config_file (DBusString *str)
+{
+  return _dbus_get_config_file_name(str, "session.conf");
+}