]> rtime.felk.cvut.cz Git - sojka/lightdm.git/blobdiff - tests/src/libsystem.c
Add shared data manager and test
[sojka/lightdm.git] / tests / src / libsystem.c
index ff90bac947a3359d643b335fd476386c668fed6b..b4db0c35310bba952b2c1b0c8a2e6402c1a165e0 100644 (file)
@@ -1,16 +1,21 @@
+#define _GNU_SOURCE
+#define __USE_GNU
+
 #include <stdlib.h>
+#include <stdio.h>
 #include <string.h>
 #include <errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/ioctl.h>
 #include <pwd.h>
 #include <unistd.h>
 #include <dirent.h>
 #include <grp.h>
 #include <security/pam_appl.h>
 #include <fcntl.h>
-#define __USE_GNU
 #include <dlfcn.h>
+#include <utmpx.h>
 #ifdef __linux__
 #include <linux/vt.h>
 #endif
@@ -18,6 +23,8 @@
 #include <xcb/xcb.h>
 #include <gio/gunixsocketaddress.h>
 
+#include "status.h"
+
 #define LOGIN_PROMPT "login:"
 
 static int console_fd = -1;
@@ -29,6 +36,8 @@ static GList *group_entries = NULL;
 
 static int active_vt = 7;
 
+static gboolean status_connected = FALSE;
+
 struct pam_handle
 {
     char *service_name;
@@ -152,9 +161,6 @@ setresuid (uid_t ruid, uid_t uuid, uid_t suid)
 static gchar *
 redirect_path (const gchar *path)
 {
-    size_t offset;
-    gboolean matches;
-
     // Don't redirect if inside the running directory
     if (g_str_has_prefix (path, g_getenv ("LIGHTDM_TEST_ROOT")))
         return g_strdup (path);
@@ -165,12 +171,15 @@ redirect_path (const gchar *path)
     if (g_str_has_prefix (path, LOCALSTATEDIR))
         return g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "var", path + strlen (LOCALSTATEDIR), NULL);
 
+    if (g_str_has_prefix (path, DATADIR))
+        return g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "usr", "share", path + strlen (DATADIR), NULL);
+
     // Don't redirect if inside the build directory
     if (g_str_has_prefix (path, BUILDDIR))
         return g_strdup (path);
 
     if (g_str_has_prefix (path, "/tmp"))
-        return g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "tmp", path + strlen ("tmp"), NULL);
+        return g_build_filename (g_getenv ("LIGHTDM_TEST_ROOT"), "tmp", path + strlen ("/tmp"), NULL);
 
     return g_strdup (path);
 }
@@ -246,6 +255,22 @@ fopen (const char *path, const char *mode)
     return result;
 }
 
+int
+unlinkat (int dirfd, const char *pathname, int flags)
+{
+    int (*_unlinkat) (int dirfd, const char *pathname, int flags);
+    gchar *new_path = NULL;
+    int result;
+
+    _unlinkat = (int (*)(int dirfd, const char *pathname, int flags)) dlsym (RTLD_NEXT, "unlinkat");
+
+    new_path = redirect_path (pathname);
+    result = _unlinkat (dirfd, new_path, flags);
+    g_free (new_path);
+
+    return result;
+}
+
 int
 creat (const char *pathname, mode_t mode)
 {
@@ -285,6 +310,10 @@ access (const char *pathname, int mode)
     gchar *new_path = NULL;
     int ret;
 
+    /* Look like systemd is always running */
+    if (strcmp (pathname, "/run/systemd/seats/") == 0)
+        return 1;
+
     _access = (int (*)(const char *pathname, int mode)) dlsym (RTLD_NEXT, "access");
 
     new_path = redirect_path (pathname);
@@ -311,16 +340,16 @@ stat (const char *path, struct stat *buf)
 }
 
 int
-stat64 (const char *path, struct stat *buf)
+stat64 (const char *path, struct stat64 *buf)
 {
-    int (*_stat64) (const char *path, struct stat *buf);
+    int (*_stat64) (const char *path, struct stat64 *buf);
     gchar *new_path = NULL;
     int ret;
 
-    _stat64 = (int (*)(const char *path, struct stat *buf)) dlsym (RTLD_NEXT, "stat64");
+    _stat64 = (int (*)(const char *path, struct stat64 *buf)) dlsym (RTLD_NEXT, "stat64");
 
     new_path = redirect_path (path);
-    ret = _stat (new_path, buf);
+    ret = _stat64 (new_path, buf);
     g_free (new_path);
 
     return ret;
@@ -343,13 +372,13 @@ __xstat (int version, const char *path, struct stat *buf)
 }
 
 int
-__xstat64 (int version, const char *path, struct stat *buf)
+__xstat64 (int version, const char *path, struct stat64 *buf)
 {
-    int (*___xstat64) (int version, const char *path, struct stat *buf);
+    int (*___xstat64) (int version, const char *path, struct stat64 *buf);
     gchar *new_path = NULL;
     int ret;
   
-    ___xstat64 = (int (*)(int version, const char *path, struct stat *buf)) dlsym (RTLD_NEXT, "__xstat64");
+    ___xstat64 = (int (*)(int version, const char *path, struct stat64 *buf)) dlsym (RTLD_NEXT, "__xstat64");
 
     new_path = redirect_path (path);
     ret = ___xstat64 (version, new_path, buf);
@@ -358,6 +387,38 @@ __xstat64 (int version, const char *path, struct stat *buf)
     return ret;
 }
 
+int
+__fxstatat(int ver, int dirfd, const char *pathname, struct stat *buf, int flags)
+{
+    int (*___fxstatat) (int ver, int dirfd, const char *pathname, struct stat *buf, int flags);
+    gchar *new_path = NULL;
+    int ret;
+  
+    ___fxstatat = (int (*)(int ver, int dirfd, const char *pathname, struct stat *buf, int flags)) dlsym (RTLD_NEXT, "__fxstatat");
+
+    new_path = redirect_path (pathname);
+    ret = ___fxstatat (ver, dirfd, new_path, buf, flags);
+    g_free (new_path);
+
+    return ret;
+}
+
+int
+__fxstatat64(int ver, int dirfd, const char *pathname, struct stat64 *buf, int flags)
+{
+    int (*___fxstatat64) (int ver, int dirfd, const char *pathname, struct stat64 *buf, int flags);
+    gchar *new_path = NULL;
+    int ret;
+  
+    ___fxstatat64 = (int (*)(int ver, int dirfd, const char *pathname, struct stat64 *buf, int flags)) dlsym (RTLD_NEXT, "__fxstatat64");
+
+    new_path = redirect_path (pathname);
+    ret = ___fxstatat64 (ver, dirfd, new_path, buf, flags);
+    g_free (new_path);
+
+    return ret;
+}
+
 DIR *
 opendir (const char *name)
 {
@@ -407,24 +468,52 @@ chown (const char *pathname, uid_t owner, gid_t group)
 }
 
 int
-ioctl (int d, int request, void *data)
+chmod (const char *path, mode_t mode)
+{
+    int (*_chmod) (const char *path, mode_t mode);
+    gchar *new_path = NULL;
+    int result;
+
+    _chmod = (int (*)(const char *path, mode_t mode)) dlsym (RTLD_NEXT, "chmod");
+
+    new_path = redirect_path (path);
+    result = _chmod (new_path, mode);
+    g_free (new_path);
+
+    return result;
+}
+
+int
+ioctl (int d, unsigned long request, ...)
 {
-    int (*_ioctl) (int d, int request, void *data);
+    int (*_ioctl) (int d, int request, ...);
 
-    _ioctl = (int (*)(int d, int request, void *data)) dlsym (RTLD_NEXT, "ioctl");
+    _ioctl = (int (*)(int d, int request, ...)) dlsym (RTLD_NEXT, "ioctl");
     if (d > 0 && d == console_fd)
     {
         struct vt_stat *console_state;
-        int *n;
+        int vt;
+        va_list ap;
 
         switch (request)
         {
         case VT_GETSTATE:
-            console_state = data;
+            va_start (ap, request);
+            console_state = va_arg (ap, struct vt_stat *);
+            va_end (ap);
             console_state->v_active = active_vt;
             break;
         case VT_ACTIVATE:
-            active_vt = GPOINTER_TO_INT (data);
+            va_start (ap, request);
+            vt = va_arg (ap, int);
+            va_end (ap);
+            if (vt != active_vt)
+            {
+                active_vt = vt;
+                if (!status_connected)
+                    status_connected = status_connect (NULL);
+                status_notify ("VT ACTIVATE VT=%d", active_vt);
+            }
             break;
         case VT_WAITACTIVE:
             break;
@@ -432,7 +521,15 @@ ioctl (int d, int request, void *data)
         return 0;
     }
     else
+    {
+        va_list ap;
+        void *data;
+
+        va_start (ap, request);
+        data = va_arg (ap, void *);
+        va_end (ap);
         return _ioctl (d, request, data);
+    }
 }
 
 int
@@ -462,7 +559,7 @@ free_user (gpointer data)
 }
 
 static void
-load_passwd_file ()
+load_passwd_file (void)
 {
     gchar *path, *data = NULL, **lines;
     gint i;
@@ -594,7 +691,7 @@ free_group (gpointer data)
 }
 
 static void
-load_group_file ()
+load_group_file (void)
 {
     gchar *path, *data = NULL, **lines;
     gint i;
@@ -957,9 +1054,9 @@ static const char *
 get_env_value (const char *name_value, const char *name)
 {
     int j;
-
-    for (j = 0; name[j] && name[j] != '=' && name[j] == name_value[j]; j++);
-    if (name_value[j] == '=')
+  
+    for (j = 0; name[j] && name_value[j] && name[j] == name_value[j]; j++);
+    if (name[j] == '\0' && name_value[j] == '=')
         return &name_value[j + 1];
 
     return NULL;
@@ -969,15 +1066,21 @@ int
 pam_putenv (pam_handle_t *pamh, const char *name_value)
 {
     int i;
+    gchar *name;
 
     if (pamh == NULL || name_value == NULL)
         return PAM_SYSTEM_ERR;
 
+    name = strdup (name_value);
+    for (i = 0; name[i]; i++)
+        if (name[i] == '=')
+            name[i] = '\0';
     for (i = 0; pamh->envlist[i]; i++)
     {
-        if (get_env_value (pamh->envlist[i], name_value))
+        if (get_env_value (pamh->envlist[i], name))
             break;
     }
+    free (name);
 
     if (pamh->envlist[i])
     {
@@ -1155,7 +1258,10 @@ pam_chauthtok (pam_handle_t *pamh, int flags)
     msg = malloc (sizeof (struct pam_message *) * 1);
     msg[0] = malloc (sizeof (struct pam_message));
     msg[0]->msg_style = PAM_PROMPT_ECHO_OFF;
-    msg[0]->msg = "Enter new password:";
+    if ((flags & PAM_CHANGE_EXPIRED_AUTHTOK) != 0)
+        msg[0]->msg = "Enter new password (expired):";
+    else
+        msg[0]->msg = "Enter new password:";
     result = pamh->conversation.conv (1, (const struct pam_message **) msg, &resp, pamh->conversation.appdata_ptr);
     free (msg[0]);
     free (msg);
@@ -1213,8 +1319,12 @@ pam_setcred (pam_handle_t *pamh, int flags)
         if (group)
         {
             groups_length = getgroups (0, NULL);
+            if (groups_length < 0)
+                return PAM_SYSTEM_ERR;
             groups = malloc (sizeof (gid_t) * (groups_length + 1));
             groups_length = getgroups (groups_length, groups);
+            if (groups_length < 0)
+                return PAM_SYSTEM_ERR;
             groups[groups_length] = group->gr_gid;
             groups_length++;
             setgroups (groups_length, groups);
@@ -1330,10 +1440,10 @@ setutxent (void)
 {
 }
   
-struct utmp *
-pututxline (struct utmp *ut)
+struct utmpx *
+pututxline (const struct utmpx *ut)
 {
-    return ut;
+    return (struct utmpx *)ut;
 }
 
 void
@@ -1353,7 +1463,6 @@ xcb_connect_to_display_with_auth_info (const char *display, xcb_auth_info_t *aut
 {
     xcb_connection_t *c;
     gchar *socket_path;
-    GSocketAddress *address;
     GError *error = NULL;
   
     c = malloc (sizeof (xcb_connection_t));
@@ -1378,6 +1487,7 @@ xcb_connect_to_display_with_auth_info (const char *display, xcb_auth_info_t *aut
     if (c->error == 0)
     {
         gchar *d;
+        GSocketAddress *address;
 
         /* Skip the hostname, we'll assume it's localhost */
         d = g_strdup_printf (".x%s", strchr (display, ':'));
@@ -1387,6 +1497,7 @@ xcb_connect_to_display_with_auth_info (const char *display, xcb_auth_info_t *aut
         address = g_unix_socket_address_new (socket_path);
         if (!g_socket_connect (c->socket, address, NULL, &error))
             c->error = XCB_CONN_ERROR;
+        g_object_unref (address);
         if (error)
             g_printerr ("Failed to connect to X socket %s: %s\n", socket_path, error->message);
         g_free (socket_path);
@@ -1398,8 +1509,6 @@ xcb_connect_to_display_with_auth_info (const char *display, xcb_auth_info_t *aut
     {
     }
 
-    g_object_unref (address);
-
     return c;
 }