Added APIs for fetching users based on the user type upstream/1.0.5
authorImran Zaman <imran.zaman@intel.com>
Wed, 28 Jan 2015 12:11:16 +0000 (14:11 +0200)
committerImran Zaman <imran.zaman@intel.com>
Wed, 28 Jan 2015 17:23:06 +0000 (19:23 +0200)
Change-Id: Ica95501ea531f68a0b228709b807078f580836e6
Signed-off-by: Imran Zaman <imran.zaman@intel.com>
52 files changed:
configure
configure.ac
data/gumd.conf.in
data/tizen/etc/gumd/gumd-tizen-common.conf
data/tizen/etc/gumd/gumd-tizen-ivi.conf
dists/debian/changelog
dists/debian/gumd.preinst
dists/rpm/gum-suse.spec
dists/rpm/tizen/packaging/gumd.changes
dists/rpm/tizen/packaging/gumd.spec
docs/gumd-sections.txt
docs/html/GumDisposable.html
docs/html/GumUser.html
docs/html/ch02.html
docs/html/ch04.html
docs/html/gumd-Group-types.html
docs/html/gumd-Gum-Error.html [moved from docs/html/gumd-Errors.html with 89% similarity]
docs/html/gumd-Gum-User-Types.html [new file with mode: 0644]
docs/html/gumd-Gum-Utils.html
docs/html/gumd-Logging.html
docs/html/gumd-User-types.html [deleted file]
docs/html/gumd.devhelp2
docs/html/index.html
docs/html/index.sgml
include/gum/common/gum-group-types.h
include/gum/common/gum-user-types.h
include/gum/gum-user-service.h [new file with mode: 0644]
src/common/Makefile.am
src/common/Makefile.in
src/common/dbus/interfaces/org.tizen.SecurityAccounts.gUserManagement.UserService.xml
src/common/gum-config.c
src/common/gum-error.c
src/common/gum-string-utils.c
src/common/gum-user-types.c [new file with mode: 0644]
src/daemon/core/gumd-daemon-user.c
src/daemon/core/gumd-daemon-user.h
src/daemon/core/gumd-daemon.c
src/daemon/core/gumd-daemon.h
src/daemon/dbus/gumd-dbus-server-msg-bus.c
src/daemon/dbus/gumd-dbus-user-service-adapter.c
src/lib/Makefile.am
src/lib/Makefile.in
src/lib/gum-group-service.c
src/lib/gum-user-service.c
src/lib/gum-user-service.h [deleted file]
src/lib/gum-user.c
src/utils/gumd-utils.c
test/common/commontest.c
test/daemon/daemon-test.c
test/data/gumd.conf
test/data/test-gumd-dbus.conf
test/lib/client-test.c

index 972d1c3..febb5ea 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for gumd 1.0.4.
+# Generated by GNU Autoconf 2.69 for gumd 1.0.5.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -587,8 +587,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='gumd'
 PACKAGE_TARNAME='gumd'
-PACKAGE_VERSION='1.0.4'
-PACKAGE_STRING='gumd 1.0.4'
+PACKAGE_VERSION='1.0.5'
+PACKAGE_STRING='gumd 1.0.5'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL='https://github.com/01org/gumd'
 
@@ -1405,7 +1405,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures gumd 1.0.4 to adapt to many kinds of systems.
+\`configure' configures gumd 1.0.5 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1475,7 +1475,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of gumd 1.0.4:";;
+     short | recursive ) echo "Configuration of gumd 1.0.5:";;
    esac
   cat <<\_ACEOF
 
@@ -1634,7 +1634,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-gumd configure 1.0.4
+gumd configure 1.0.5
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1999,7 +1999,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by gumd $as_me 1.0.4, which was
+It was created by gumd $as_me 1.0.5, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2867,7 +2867,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='gumd'
- VERSION='1.0.4'
+ VERSION='1.0.5'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -13932,7 +13932,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by gumd $as_me 1.0.4, which was
+This file was extended by gumd $as_me 1.0.5, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -13999,7 +13999,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-gumd config.status 1.0.4
+gumd config.status 1.0.5
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
index 050353d..7b8691a 100644 (file)
@@ -2,7 +2,7 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ([2.60])
-AC_INIT([gumd], [1.0.4],[],[],[https://github.com/01org/gumd])
+AC_INIT([gumd], [1.0.5],[],[],[https://github.com/01org/gumd])
 AC_CONFIG_SRCDIR([src/daemon/main.c])
 AC_CONFIG_HEADERS([config.h])
 AC_CONFIG_AUX_DIR([build-aux])
index 49904c9..52d0df6 100644 (file)
 # environment variable.
 #SKEL_DIR=/etc/skel
 
-# Minimum value for the automatic uid selection. Default value is: 2000
-#UID_MIN=2000
+# Minimum value for the automatic uid selection. Default value is: 1000
+#UID_MIN=1000
 
 # Maximum value for the automatic uid selection. Default value is: 60000
 #UID_MAX=60000
 
 # Minimum value for the automatic uid selection for system user. Default
-# value is: 200
-#SYS_UID_MIN=200
+# value is: 100
+#SYS_UID_MIN=100
 
 # Maximum value for the automatic uid selection for system user. Default value
 # is: 999
 #SYS_UID_MAX=999
 
-# Minimum value for the automatic gid selection. Default value is: 2000
-#GID_MIN=2000
+# Minimum value for the automatic gid selection. Default value is: 1000
+#GID_MIN=1000
 
 # Maximum value for the automatic gid selection. Default value is: 60000
 #GID_MAX=60000
 
 # Minimum value for the automatic gid selection for system user. Default value
-# is: 200
-#SYS_GID_MIN=200
+# is: 100
+#SYS_GID_MIN=100
 
 # Maximum value for the automatic gid selection for system user. Default value
 # is: 999
index 1022ef3..25de44e 100644 (file)
@@ -65,29 +65,29 @@ USR_PRIMARY_GRPNAME=users
 # environment variable.
 #SKEL_DIR=/etc/skel
 
-# Minimum value for the automatic uid selection. Default value is: 2000
-#UID_MIN=2000
+# Minimum value for the automatic uid selection. Default value is: 1000
+#UID_MIN=1000
 
 # Maximum value for the automatic uid selection. Default value is: 60000
 #UID_MAX=60000
 
 # Minimum value for the automatic uid selection for system user. Default
-# value is: 200
-#SYS_UID_MIN=200
+# value is: 100
+#SYS_UID_MIN=100
 
 # Maximum value for the automatic uid selection for system user. Default value
 # is: 999
 #SYS_UID_MAX=999
 
-# Minimum value for the automatic gid selection. Default value is: 2000
-#GID_MIN=2000
+# Minimum value for the automatic gid selection. Default value is: 1000
+#GID_MIN=1000
 
 # Maximum value for the automatic gid selection. Default value is: 60000
 #GID_MAX=60000
 
 # Minimum value for the automatic gid selection for system user. Default value
-# is: 200
-#SYS_GID_MIN=200
+# is: 100
+#SYS_GID_MIN=100
 
 # Maximum value for the automatic gid selection for system user. Default value
 # is: 999
index 71c4463..d48afd2 100644 (file)
@@ -15,7 +15,7 @@ USR_PRIMARY_GRPNAME=users
 # Comma separate listed of groups, which every user (other than system user)
 # will be added to at the time of user account creation. Default value is:
 # ''
-DEFAULT_USR_GROUPS=weston-launch
+DEFAULT_USR_GROUPS=weston-launch,audio,video
 
 # Comma separate listed of groups, which admin user will be added to at the
 # time of user account creation. Default value is: ''
@@ -65,29 +65,29 @@ DEFAULT_USR_GROUPS=weston-launch
 # environment variable.
 #SKEL_DIR=/etc/skel
 
-# Minimum value for the automatic uid selection. Default value is: 2000
-#UID_MIN=2000
+# Minimum value for the automatic uid selection. Default value is: 1000
+#UID_MIN=1000
 
 # Maximum value for the automatic uid selection. Default value is: 60000
 #UID_MAX=60000
 
 # Minimum value for the automatic uid selection for system user. Default
-# value is: 200
-#SYS_UID_MIN=200
+# value is: 100
+#SYS_UID_MIN=100
 
 # Maximum value for the automatic uid selection for system user. Default value
 # is: 999
 #SYS_UID_MAX=999
 
-# Minimum value for the automatic gid selection. Default value is: 2000
-#GID_MIN=2000
+# Minimum value for the automatic gid selection. Default value is: 1000
+#GID_MIN=1000
 
 # Maximum value for the automatic gid selection. Default value is: 60000
 #GID_MAX=60000
 
 # Minimum value for the automatic gid selection for system user. Default value
-# is: 200
-#SYS_GID_MIN=200
+# is: 100
+#SYS_GID_MIN=100
 
 # Maximum value for the automatic gid selection for system user. Default value
 # is: 999
index b92c896..6eab0b9 100644 (file)
@@ -1,3 +1,9 @@
+gumd (1.0.5-0) unstable; urgency=low
+
+  * Added APIs for fetching users based on the type
+
+ -- Imran Zaman <imran.zaman@intel.com>  Wed, 28 Jan  2015 18:00:00 +0300
+
 gumd (1.0.4-0) unstable; urgency=low
 
   * Added separate configuration file Tizen IVI
index 8cba018..a93d0ce 100644 (file)
@@ -18,7 +18,7 @@ case "$1" in
     install)
     ;;
     upgrade)
-        cp -a /etc/gumd.conf /etc/gumd.conf.orig
+        cp -a /etc/gumd/gumd.conf /etc/gumd/gumd.conf.orig
     ;;
 
     abort-upgrade)
index 582b6c7..1fba2dc 100644 (file)
@@ -7,7 +7,7 @@
 
 Name: gumd
 Summary: User management daemon and client library
-Version: 1.0.4
+Version: 1.0.5
 Release: 0
 Group: System/Daemons
 License: LGPL-2.1+
@@ -150,6 +150,9 @@ mkdir -p %{_sysconfdir}/%{name}/groupdel.d
 
 
 %changelog
+* Wed Jan 28 2015 Imran Zaman <imran.zaman@intel.com>
+- Added APIs for fetching users based on the type
+
 * Thu Jan 15 2015 Imran Zaman <imran.zaman@intel.com>
 - Added separate configuration file Tizen IVI
 - Newly created users are added to weston-launch group for Tizen IVI
index d61e008..dde1134 100644 (file)
@@ -1,3 +1,6 @@
+* Wed Jan 28 2015 Imran Zaman <imran.zaman@intel.com>
+- Added APIs for fetching users based on the type
+
 * Thu Jan 15 2015 Imran Zaman <imran.zaman@intel.com>
 - Added separate configuration file Tizen IVI
 - Newly created users are added to weston-launch group for Tizen IVI
index 4c3be03..bd09729 100644 (file)
@@ -6,7 +6,7 @@
 
 Name:    gumd
 Summary: User management daemon and client library
-Version: 1.0.4
+Version: 1.0.5
 Release: 0
 Group:   Security/Accounts
 License: LGPL-2.1+
@@ -103,10 +103,10 @@ install -m 644 data/tizen/etc/%{name}/%{name}-tizen-ivi.conf %{buildroot}%{_sysc
 %post
 ldconfig
 getent group gumd > /dev/null || groupadd -r gumd
-mkdir -p %{_sysconfdir}/%{name}/useradd.d
-mkdir -p %{_sysconfdir}/%{name}/userdel.d
-mkdir -p %{_sysconfdir}/%{name}/groupadd.d
-mkdir -p %{_sysconfdir}/%{name}/groupdel.d
+install -d -m 755 %{_sysconfdir}/%{name}/useradd.d
+install -d -m 755 %{_sysconfdir}/%{name}/userdel.d
+install -d -m 755 %{_sysconfdir}/%{name}/groupadd.d
+install -d -m 755 %{_sysconfdir}/%{name}/groupdel.d
 
 
 %postun -p /sbin/ldconfig
index a907103..dd13313 100644 (file)
@@ -246,7 +246,13 @@ gum_user_get_type
 
 <SECTION>
 <FILE>gum-user-types</FILE>
+GUM_USERTYPE_COUNT
+GUM_USERTYPE_MAX_VALUE
 GumUserType
+gum_user_type_to_string
+gum_user_type_from_string
+gum_user_type_to_strv
+gum_user_type_from_strv
 </SECTION>
 
 <SECTION>
index 219c5ea..dd69e22 100644 (file)
@@ -6,7 +6,7 @@
 <meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
 <link rel="home" href="index.html" title="gumd API Reference Manual">
 <link rel="up" href="ch02.html" title="Common">
-<link rel="prev" href="gumd-Errors.html" title="Errors">
+<link rel="prev" href="gumd-Gum-Error.html" title="Gum Error">
 <link rel="next" href="gumd-Gum-File.html" title="Gum File">
 <meta name="generator" content="GTK-Doc V1.20 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
@@ -22,7 +22,7 @@
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="ch02.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="gumd-Errors.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="p" href="gumd-Gum-Error.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="gumd-Gum-File.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refentry">
index b5d1065..6835977 100644 (file)
@@ -570,7 +570,7 @@ notify when the user is added.</p>
 <tbody>
 <tr>
 <td class="parameter_name"><p>self</p></td>
-<td class="parameter_description"><p><a class="link" href="GumUser.html" title="GumUser"><span class="type">GumUser</span></a> object to be added; object should have either valid
+<td class="parameter_description"><p><a class="link" href="GumUser.html" title="GumUser"><span class="type">GumUser</span></a> object to be added
 <a class="link" href="GumUser.html#GumUser--username" title="The “username” property"><span class="type">“username”</span></a> or <a class="link" href="GumUser.html#GumUser--nickname" title="The “nickname” property"><span class="type">“nickname”</span></a> in addition to valid
 <a class="link" href="GumUser.html#GumUser--usertype" title="The “usertype” property"><span class="type">“usertype”</span></a>.</p></td>
 <td class="parameter_annotations"> </td>
@@ -928,7 +928,7 @@ or <a class="link" href="GumUser.html#GumUser--nickname" title="The “nickname
 <a name="GumUser--usertype"></a><h3>The <code class="literal">“usertype”</code> property</h3>
 <pre class="programlisting">  “usertype”                 <a href="http://library.gnome.org/devel/glib/unstable/glib-Basic-Types.html#guint"><span class="type">guint</span></a></pre>
 <p>This property holds a user type that the object corresponds to. Valid
-values of user types are as specified in <a class="link" href="gumd-User-types.html#GumUserType" title="enum GumUserType"><span class="type">GumUserType</span></a>.
+values of user types are as specified in <a class="link" href="gumd-Gum-User-Types.html#GumUserType" title="enum GumUserType"><span class="type">GumUserType</span></a>.
 <a class="link" href="GumUser.html#GumUser--usertype" title="The “usertype” property"><span class="type">“usertype”</span></a> must be specified when adding a new user.</p>
 <p>Flags: Read / Write</p>
 <p>Allowed values: &lt;= 65535</p>
index fe10f0e..4301eb4 100644 (file)
@@ -34,7 +34,7 @@
 <span class="refentrytitle"><a href="gumd-Logging.html">Logging</a></span><span class="refpurpose"> — logging facilities</span>
 </dt>
 <dt>
-<span class="refentrytitle"><a href="gumd-Errors.html">Errors</a></span><span class="refpurpose"> — error definitions and utilities</span>
+<span class="refentrytitle"><a href="gumd-Gum-Error.html">Gum Error</a></span><span class="refpurpose"> — error definitions and utilities</span>
 </dt>
 <dt>
 <span class="refentrytitle"><a href="GumDisposable.html">GumDisposable</a></span><span class="refpurpose"> — timer-based auto disposable object</span>
@@ -55,7 +55,7 @@
 <span class="refentrytitle"><a href="gumd-Gum-Utils.html">Gum Utils</a></span><span class="refpurpose"> — Utility functions</span>
 </dt>
 <dt>
-<span class="refentrytitle"><a href="gumd-User-types.html">User types</a></span><span class="refpurpose"> — user types definition</span>
+<span class="refentrytitle"><a href="gumd-Gum-User-Types.html">Gum User Types</a></span><span class="refpurpose"> — Utility functions for user types</span>
 </dt>
 <dt>
 <span class="refentrytitle"><a href="gumd-Group-types.html">Group types</a></span><span class="refpurpose"> — group types definition</span>
index b6bedf7..9dc04ac 100644 (file)
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="gumd-Errors.html#GUM-ERROR:CAPS" title="GUM_ERROR">GUM_ERROR</a>, macro in <a class="link" href="gumd-Errors.html" title="Errors">Errors</a>
+<a class="link" href="gumd-Gum-Error.html#GUM-ERROR:CAPS" title="GUM_ERROR">GUM_ERROR</a>, macro in <a class="link" href="gumd-Gum-Error.html" title="Gum Error">Gum Error</a>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="gumd-Errors.html#GumError" title="enum GumError">GumError</a>, enum in <a class="link" href="gumd-Errors.html" title="Errors">Errors</a>
+<a class="link" href="gumd-Gum-Error.html#GumError" title="enum GumError">GumError</a>, enum in <a class="link" href="gumd-Gum-Error.html" title="Gum Error">Gum Error</a>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="gumd-Errors.html#gum-error-new-from-variant" title="gum_error_new_from_variant ()">gum_error_new_from_variant</a>, function in <a class="link" href="gumd-Errors.html" title="Errors">Errors</a>
+<a class="link" href="gumd-Gum-Error.html#gum-error-new-from-variant" title="gum_error_new_from_variant ()">gum_error_new_from_variant</a>, function in <a class="link" href="gumd-Gum-Error.html" title="Gum Error">Gum Error</a>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="gumd-Errors.html#gum-error-quark" title="gum_error_quark ()">gum_error_quark</a>, function in <a class="link" href="gumd-Errors.html" title="Errors">Errors</a>
+<a class="link" href="gumd-Gum-Error.html#gum-error-quark" title="gum_error_quark ()">gum_error_quark</a>, function in <a class="link" href="gumd-Gum-Error.html" title="Gum Error">Gum Error</a>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="gumd-Errors.html#gum-error-to-variant" title="gum_error_to_variant ()">gum_error_to_variant</a>, function in <a class="link" href="gumd-Errors.html" title="Errors">Errors</a>
+<a class="link" href="gumd-Gum-Error.html#gum-error-to-variant" title="gum_error_to_variant ()">gum_error_to_variant</a>, function in <a class="link" href="gumd-Gum-Error.html" title="Gum Error">Gum Error</a>
 </dt>
 <dd></dd>
 <a name="idxF"></a><h3 class="title">F</h3>
 <dd></dd>
 <a name="idxG"></a><h3 class="title">G</h3>
 <dt>
-<a class="link" href="gumd-Errors.html#GUM-GET-ERROR-FOR-ID:CAPS" title="GUM_GET_ERROR_FOR_ID()">GUM_GET_ERROR_FOR_ID</a>, macro in <a class="link" href="gumd-Errors.html" title="Errors">Errors</a>
+<a class="link" href="gumd-Gum-Error.html#GUM-GET-ERROR-FOR-ID:CAPS" title="GUM_GET_ERROR_FOR_ID()">GUM_GET_ERROR_FOR_ID</a>, macro in <a class="link" href="gumd-Gum-Error.html" title="Gum Error">Gum Error</a>
 </dt>
 <dd></dd>
 <dt>
 <dd></dd>
 <a name="idxR"></a><h3 class="title">R</h3>
 <dt>
-<a class="link" href="gumd-Errors.html#GUM-RETURN-WITH-ERROR:CAPS" title="GUM_RETURN_WITH_ERROR()">GUM_RETURN_WITH_ERROR</a>, macro in <a class="link" href="gumd-Errors.html" title="Errors">Errors</a>
+<a class="link" href="gumd-Gum-Error.html#GUM-RETURN-WITH-ERROR:CAPS" title="GUM_RETURN_WITH_ERROR()">GUM_RETURN_WITH_ERROR</a>, macro in <a class="link" href="gumd-Gum-Error.html" title="Gum Error">Gum Error</a>
 </dt>
 <dd></dd>
 <a name="idxS"></a><h3 class="title">S</h3>
 <dt>
-<a class="link" href="gumd-Errors.html#GUM-SET-ERROR:CAPS" title="GUM_SET_ERROR()">GUM_SET_ERROR</a>, macro in <a class="link" href="gumd-Errors.html" title="Errors">Errors</a>
+<a class="link" href="gumd-Gum-Error.html#GUM-SET-ERROR:CAPS" title="GUM_SET_ERROR()">GUM_SET_ERROR</a>, macro in <a class="link" href="gumd-Gum-Error.html" title="Gum Error">Gum Error</a>
 </dt>
 <dd></dd>
 <dt>
 </dt>
 <dd></dd>
 <dt>
-<a class="link" href="gumd-User-types.html#GumUserType" title="enum GumUserType">GumUserType</a>, enum in <a class="link" href="gumd-User-types.html" title="User types">User types</a>
+<a class="link" href="gumd-Gum-User-Types.html#GumUserType" title="enum GumUserType">GumUserType</a>, enum in <a class="link" href="gumd-Gum-User-Types.html" title="Gum User Types">Gum User Types</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="gumd-Gum-User-Types.html#GUM-USERTYPE-COUNT:CAPS" title="GUM_USERTYPE_COUNT">GUM_USERTYPE_COUNT</a>, macro in <a class="link" href="gumd-Gum-User-Types.html" title="Gum User Types">Gum User Types</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="gumd-Gum-User-Types.html#GUM-USERTYPE-MAX-VALUE:CAPS" title="GUM_USERTYPE_MAX_VALUE">GUM_USERTYPE_MAX_VALUE</a>, macro in <a class="link" href="gumd-Gum-User-Types.html" title="Gum User Types">Gum User Types</a>
 </dt>
 <dd></dd>
 <dt>
 </dt>
 <dd></dd>
 <dt>
+<a class="link" href="gumd-Gum-User-Types.html#gum-user-type-from-string" title="gum_user_type_from_string ()">gum_user_type_from_string</a>, function in <a class="link" href="gumd-Gum-User-Types.html" title="Gum User Types">Gum User Types</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="gumd-Gum-User-Types.html#gum-user-type-from-strv" title="gum_user_type_from_strv ()">gum_user_type_from_strv</a>, function in <a class="link" href="gumd-Gum-User-Types.html" title="Gum User Types">Gum User Types</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="gumd-Gum-User-Types.html#gum-user-type-to-string" title="gum_user_type_to_string ()">gum_user_type_to_string</a>, function in <a class="link" href="gumd-Gum-User-Types.html" title="Gum User Types">Gum User Types</a>
+</dt>
+<dd></dd>
+<dt>
+<a class="link" href="gumd-Gum-User-Types.html#gum-user-type-to-strv" title="gum_user_type_to_strv ()">gum_user_type_to_strv</a>, function in <a class="link" href="gumd-Gum-User-Types.html" title="Gum User Types">Gum User Types</a>
+</dt>
+<dd></dd>
+<dt>
 <a class="link" href="GumUser.html#gum-user-update" title="gum_user_update ()">gum_user_update</a>, function in <a class="link" href="GumUser.html" title="GumUser">GumUser</a>
 </dt>
 <dd></dd>
index 4b7c3d1..3691404 100644 (file)
@@ -6,7 +6,7 @@
 <meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
 <link rel="home" href="index.html" title="gumd API Reference Manual">
 <link rel="up" href="ch02.html" title="Common">
-<link rel="prev" href="gumd-User-types.html" title="User types">
+<link rel="prev" href="gumd-Gum-User-Types.html" title="Gum User Types">
 <link rel="next" href="ch03.html" title="Client library (libgum) interface">
 <meta name="generator" content="GTK-Doc V1.20 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
@@ -20,7 +20,7 @@
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="ch02.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="gumd-User-types.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="p" href="gumd-Gum-User-Types.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
 <td><a accesskey="n" href="ch03.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refentry">
similarity index 89%
rename from docs/html/gumd-Errors.html
rename to docs/html/gumd-Gum-Error.html
index b631c1f..a2d8825 100644 (file)
@@ -2,7 +2,7 @@
 <html>
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<title>gumd API Reference Manual: Errors</title>
+<title>gumd API Reference Manual: Gum Error</title>
 <meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
 <link rel="home" href="index.html" title="gumd API Reference Manual">
 <link rel="up" href="ch02.html" title="Common">
@@ -15,8 +15,8 @@
 <table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="10"><tr valign="middle">
 <td width="100%" align="left" class="shortcuts">
 <a href="#" class="shortcut">Top</a><span id="nav_description"> <span class="dim">|</span> 
-                  <a href="#gumd-Errors.description" class="shortcut">Description</a></span><span id="nav_hierarchy"> <span class="dim">|</span> 
-                  <a href="#gumd-Errors.object-hierarchy" class="shortcut">Object Hierarchy</a></span>
+                  <a href="#gumd-Gum-Error.description" class="shortcut">Description</a></span><span id="nav_hierarchy"> <span class="dim">|</span> 
+                  <a href="#gumd-Gum-Error.object-hierarchy" class="shortcut">Object Hierarchy</a></span>
 </td>
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="ch02.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="n" href="GumDisposable.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refentry">
-<a name="gumd-Errors"></a><div class="titlepage"></div>
+<a name="gumd-Gum-Error"></a><div class="titlepage"></div>
 <div class="refnamediv"><table width="100%"><tr>
 <td valign="top">
-<h2><span class="refentrytitle"><a name="gumd-Errors.top_of_page"></a>Errors</span></h2>
-<p>Errors — error definitions and utilities</p>
+<h2><span class="refentrytitle"><a name="gumd-Gum-Error.top_of_page"></a>Gum Error</span></h2>
+<p>Gum Error — error definitions and utilities</p>
 </td>
 <td class="gallery_image" valign="top" align="right"></td>
 </tr></table></div>
 <div class="refsect1">
-<a name="gumd-Errors.functions"></a><h2>Functions</h2>
+<a name="gumd-Gum-Error.functions"></a><h2>Functions</h2>
 <div class="informaltable"><table width="100%" border="0">
 <colgroup>
 <col width="150px" class="functions_return">
 <tbody>
 <tr>
 <td class="define_keyword">#define</td>
-<td class="function_name"><a class="link" href="gumd-Errors.html#GUM-ERROR:CAPS" title="GUM_ERROR">GUM_ERROR</a></td>
+<td class="function_name"><a class="link" href="gumd-Gum-Error.html#GUM-ERROR:CAPS" title="GUM_ERROR">GUM_ERROR</a></td>
 </tr>
 <tr>
 <td class="define_keyword">#define</td>
 <td class="function_name">
-<a class="link" href="gumd-Errors.html#GUM-GET-ERROR-FOR-ID:CAPS" title="GUM_GET_ERROR_FOR_ID()">GUM_GET_ERROR_FOR_ID</a><span class="c_punctuation">()</span>
+<a class="link" href="gumd-Gum-Error.html#GUM-GET-ERROR-FOR-ID:CAPS" title="GUM_GET_ERROR_FOR_ID()">GUM_GET_ERROR_FOR_ID</a><span class="c_punctuation">()</span>
 </td>
 </tr>
 <tr>
 <td class="define_keyword">#define</td>
 <td class="function_name">
-<a class="link" href="gumd-Errors.html#GUM-SET-ERROR:CAPS" title="GUM_SET_ERROR()">GUM_SET_ERROR</a><span class="c_punctuation">()</span>
+<a class="link" href="gumd-Gum-Error.html#GUM-SET-ERROR:CAPS" title="GUM_SET_ERROR()">GUM_SET_ERROR</a><span class="c_punctuation">()</span>
 </td>
 </tr>
 <tr>
 <td class="define_keyword">#define</td>
 <td class="function_name">
-<a class="link" href="gumd-Errors.html#GUM-RETURN-WITH-ERROR:CAPS" title="GUM_RETURN_WITH_ERROR()">GUM_RETURN_WITH_ERROR</a><span class="c_punctuation">()</span>
+<a class="link" href="gumd-Gum-Error.html#GUM-RETURN-WITH-ERROR:CAPS" title="GUM_RETURN_WITH_ERROR()">GUM_RETURN_WITH_ERROR</a><span class="c_punctuation">()</span>
 </td>
 </tr>
 <tr>
@@ -67,7 +67,7 @@
 <a href="http://library.gnome.org/devel/glib/unstable/glib-Quarks.html#GQuark"><span class="returnvalue">GQuark</span></a>
 </td>
 <td class="function_name">
-<a class="link" href="gumd-Errors.html#gum-error-quark" title="gum_error_quark ()">gum_error_quark</a> <span class="c_punctuation">()</span>
+<a class="link" href="gumd-Gum-Error.html#gum-error-quark" title="gum_error_quark ()">gum_error_quark</a> <span class="c_punctuation">()</span>
 </td>
 </tr>
 <tr>
@@ -75,7 +75,7 @@
 <a href="http://library.gnome.org/devel/glib/unstable/glib-Error-Reporting.html#GError"><span class="returnvalue">GError</span></a> *
 </td>
 <td class="function_name">
-<a class="link" href="gumd-Errors.html#gum-error-new-from-variant" title="gum_error_new_from_variant ()">gum_error_new_from_variant</a> <span class="c_punctuation">()</span>
+<a class="link" href="gumd-Gum-Error.html#gum-error-new-from-variant" title="gum_error_new_from_variant ()">gum_error_new_from_variant</a> <span class="c_punctuation">()</span>
 </td>
 </tr>
 <tr>
 <a href="http://library.gnome.org/devel/glib/unstable/glib-GVariant.html#GVariant"><span class="returnvalue">GVariant</span></a> *
 </td>
 <td class="function_name">
-<a class="link" href="gumd-Errors.html#gum-error-to-variant" title="gum_error_to_variant ()">gum_error_to_variant</a> <span class="c_punctuation">()</span>
+<a class="link" href="gumd-Gum-Error.html#gum-error-to-variant" title="gum_error_to_variant ()">gum_error_to_variant</a> <span class="c_punctuation">()</span>
 </td>
 </tr>
 </tbody>
 </table></div>
 </div>
 <div class="refsect1">
-<a name="gumd-Errors.other"></a><h2>Types and Values</h2>
+<a name="gumd-Gum-Error.other"></a><h2>Types and Values</h2>
 <div class="informaltable"><table width="100%" border="0">
 <colgroup>
 <col width="150px" class="name">
 </colgroup>
 <tbody><tr>
 <td class="datatype_keyword">enum</td>
-<td class="function_name"><a class="link" href="gumd-Errors.html#GumError" title="enum GumError">GumError</a></td>
+<td class="function_name"><a class="link" href="gumd-Gum-Error.html#GumError" title="enum GumError">GumError</a></td>
 </tr></tbody>
 </table></div>
 </div>
 <div class="refsect1">
-<a name="gumd-Errors.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<a name="gumd-Gum-Error.object-hierarchy"></a><h2>Object Hierarchy</h2>
 <pre class="screen">
 </pre>
 </div>
 <div class="refsect1">
-<a name="gumd-Errors.includes"></a><h2>Includes</h2>
+<a name="gumd-Gum-Error.includes"></a><h2>Includes</h2>
 <pre class="synopsis">#include &lt;gum/common/gum-error.h&gt;
 </pre>
 </div>
 <div class="refsect1">
-<a name="gumd-Errors.description"></a><h2>Description</h2>
+<a name="gumd-Gum-Error.description"></a><h2>Description</h2>
 <p>This file provides Gum error definitions and utilities.
-When creating an error, use <a class="link" href="gumd-Errors.html#GUM-ERROR:CAPS" title="GUM_ERROR"><span class="type">GUM_ERROR</span></a> for the error domain and errors
-from <a class="link" href="gumd-Errors.html#GumError" title="enum GumError"><span class="type">GumError</span></a> for the error code.</p>
+When creating an error, use <a class="link" href="gumd-Gum-Error.html#GUM-ERROR:CAPS" title="GUM_ERROR"><span class="type">GUM_ERROR</span></a> for the error domain and errors
+from <a class="link" href="gumd-Gum-Error.html#GumError" title="enum GumError"><span class="type">GumError</span></a> for the error code.</p>
 <div class="informalexample"><pre class="programlisting">
     GError* err = g_error_new(GUM_ERROR, GUM_ERROR_USER_ALREADY_EXISTS,
     "User already exists");
@@ -124,7 +124,7 @@ from <a class="link" href="gumd-Errors.html#GumError" title="enum GumError"><spa
 <p></p>
 </div>
 <div class="refsect1">
-<a name="gumd-Errors.functions_details"></a><h2>Functions</h2>
+<a name="gumd-Gum-Error.functions_details"></a><h2>Functions</h2>
 <div class="refsect2">
 <a name="GUM-ERROR:CAPS"></a><h3>GUM_ERROR</h3>
 <pre class="programlisting">#define GUM_ERROR   (gum_error_quark())
@@ -148,7 +148,7 @@ from <a class="link" href="gumd-Errors.html#GumError" title="enum GumError"><spa
 <tbody>
 <tr>
 <td class="parameter_name"><p>code</p></td>
-<td class="parameter_description"><p>A <a class="link" href="gumd-Errors.html#GumError" title="enum GumError"><span class="type">GumError</span></a> specifying the error</p></td>
+<td class="parameter_description"><p>A <a class="link" href="gumd-Gum-Error.html#GumError" title="enum GumError"><span class="type">GumError</span></a> specifying the error</p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -182,7 +182,7 @@ the error message to logs, and sets the specified retval to retvar.</p>
 <tbody>
 <tr>
 <td class="parameter_name"><p>code</p></td>
-<td class="parameter_description"><p>the error code as listed in <a class="link" href="gumd-Errors.html#GumError" title="enum GumError"><span class="type">GumError</span></a></p></td>
+<td class="parameter_description"><p>the error code as listed in <a class="link" href="gumd-Gum-Error.html#GumError" title="enum GumError"><span class="type">GumError</span></a></p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -226,7 +226,7 @@ the error message to logs, and returns with specified retval.</p>
 <tbody>
 <tr>
 <td class="parameter_name"><p>code</p></td>
-<td class="parameter_description"><p>the error code as listed in <a class="link" href="gumd-Errors.html#GumError" title="enum GumError"><span class="type">GumError</span></a></p></td>
+<td class="parameter_description"><p>the error code as listed in <a class="link" href="gumd-Gum-Error.html#GumError" title="enum GumError"><span class="type">GumError</span></a></p></td>
 <td class="parameter_annotations"> </td>
 </tr>
 <tr>
@@ -316,7 +316,7 @@ gum_error_to_variant (<em class="parameter"><code><a href="http://library.gnome.
 </div>
 </div>
 <div class="refsect1">
-<a name="gumd-Errors.other_details"></a><h2>Types and Values</h2>
+<a name="gumd-Gum-Error.other_details"></a><h2>Types and Values</h2>
 <div class="refsect2">
 <a name="GumError"></a><h3>enum GumError</h3>
 <p>This enumeration provides a list of errors</p>
diff --git a/docs/html/gumd-Gum-User-Types.html b/docs/html/gumd-Gum-User-Types.html
new file mode 100644 (file)
index 0000000..1294df6
--- /dev/null
@@ -0,0 +1,313 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>gumd API Reference Manual: Gum User Types</title>
+<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
+<link rel="home" href="index.html" title="gumd API Reference Manual">
+<link rel="up" href="ch02.html" title="Common">
+<link rel="prev" href="gumd-Gum-Utils.html" title="Gum Utils">
+<link rel="next" href="gumd-Group-types.html" title="Group types">
+<meta name="generator" content="GTK-Doc V1.20 (XML mode)">
+<link rel="stylesheet" href="style.css" type="text/css">
+</head>
+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="10"><tr valign="middle">
+<td width="100%" align="left" class="shortcuts">
+<a href="#" class="shortcut">Top</a><span id="nav_description"> <span class="dim">|</span> 
+                  <a href="#gumd-Gum-User-Types.description" class="shortcut">Description</a></span><span id="nav_hierarchy"> <span class="dim">|</span> 
+                  <a href="#gumd-Gum-User-Types.object-hierarchy" class="shortcut">Object Hierarchy</a></span>
+</td>
+<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
+<td><a accesskey="u" href="ch02.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
+<td><a accesskey="p" href="gumd-Gum-Utils.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
+<td><a accesskey="n" href="gumd-Group-types.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+</tr></table>
+<div class="refentry">
+<a name="gumd-Gum-User-Types"></a><div class="titlepage"></div>
+<div class="refnamediv"><table width="100%"><tr>
+<td valign="top">
+<h2><span class="refentrytitle"><a name="gumd-Gum-User-Types.top_of_page"></a>Gum User Types</span></h2>
+<p>Gum User Types — Utility functions for user types</p>
+</td>
+<td class="gallery_image" valign="top" align="right"></td>
+</tr></table></div>
+<div class="refsect1">
+<a name="gumd-Gum-User-Types.functions"></a><h2>Functions</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="functions_return">
+<col class="functions_name">
+</colgroup>
+<tbody>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="gumd-Gum-User-Types.html#GUM-USERTYPE-MAX-VALUE:CAPS" title="GUM_USERTYPE_MAX_VALUE">GUM_USERTYPE_MAX_VALUE</a></td>
+</tr>
+<tr>
+<td class="function_type">const <a href="http://library.gnome.org/devel/glib/unstable/glib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+</td>
+<td class="function_name">
+<a class="link" href="gumd-Gum-User-Types.html#gum-user-type-to-string" title="gum_user_type_to_string ()">gum_user_type_to_string</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a class="link" href="gumd-Gum-User-Types.html#GumUserType" title="enum GumUserType"><span class="returnvalue">GumUserType</span></a>
+</td>
+<td class="function_name">
+<a class="link" href="gumd-Gum-User-Types.html#gum-user-type-from-string" title="gum_user_type_from_string ()">gum_user_type_from_string</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<a href="http://library.gnome.org/devel/glib/unstable/glib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> **
+</td>
+<td class="function_name">
+<a class="link" href="gumd-Gum-User-Types.html#gum-user-type-to-strv" title="gum_user_type_to_strv ()">gum_user_type_to_strv</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+<tr>
+<td class="function_type">
+<span class="returnvalue">guint16</span>
+</td>
+<td class="function_name">
+<a class="link" href="gumd-Gum-User-Types.html#gum-user-type-from-strv" title="gum_user_type_from_strv ()">gum_user_type_from_strv</a> <span class="c_punctuation">()</span>
+</td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="gumd-Gum-User-Types.other"></a><h2>Types and Values</h2>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="name">
+<col class="description">
+</colgroup>
+<tbody>
+<tr>
+<td class="define_keyword">#define</td>
+<td class="function_name"><a class="link" href="gumd-Gum-User-Types.html#GUM-USERTYPE-COUNT:CAPS" title="GUM_USERTYPE_COUNT">GUM_USERTYPE_COUNT</a></td>
+</tr>
+<tr>
+<td class="datatype_keyword">enum</td>
+<td class="function_name"><a class="link" href="gumd-Gum-User-Types.html#GumUserType" title="enum GumUserType">GumUserType</a></td>
+</tr>
+</tbody>
+</table></div>
+</div>
+<div class="refsect1">
+<a name="gumd-Gum-User-Types.object-hierarchy"></a><h2>Object Hierarchy</h2>
+<pre class="screen">
+</pre>
+</div>
+<div class="refsect1">
+<a name="gumd-Gum-User-Types.includes"></a><h2>Includes</h2>
+<pre class="synopsis">#include &lt;gum/common/gum-user-types.h&gt;
+</pre>
+</div>
+<div class="refsect1">
+<a name="gumd-Gum-User-Types.description"></a><h2>Description</h2>
+<p>User type conversion/validation functions</p>
+</div>
+<div class="refsect1">
+<a name="gumd-Gum-User-Types.functions_details"></a><h2>Functions</h2>
+<div class="refsect2">
+<a name="GUM-USERTYPE-MAX-VALUE:CAPS"></a><h3>GUM_USERTYPE_MAX_VALUE</h3>
+<pre class="programlisting">#define GUM_USERTYPE_MAX_VALUE   (0x1 &lt;&lt; (GUM_USERTYPE_COUNT-1))
+</pre>
+<p>Defines the maximum value of the user type in <a class="link" href="gumd-Gum-User-Types.html#GumUserType" title="enum GumUserType"><span class="type">GumUserType</span></a>.</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gum-user-type-to-string"></a><h3>gum_user_type_to_string ()</h3>
+<pre class="programlisting">const <a href="http://library.gnome.org/devel/glib/unstable/glib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> *
+gum_user_type_to_string (<em class="parameter"><code><a class="link" href="gumd-Gum-User-Types.html#GumUserType" title="enum GumUserType"><span class="type">GumUserType</span></a> type</code></em>);</pre>
+<p>Converts the user type enum to string</p>
+<div class="refsect3">
+<a name="id-1.5.12.8.3.5"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>type</p></td>
+<td class="parameter_description"><p>the user type enum to convert</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="id-1.5.12.8.3.6"></a><h4>Returns</h4>
+<p> usertype if conversion succeeds, NULL otherwise. </p>
+<p><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gum-user-type-from-string"></a><h3>gum_user_type_from_string ()</h3>
+<pre class="programlisting"><a class="link" href="gumd-Gum-User-Types.html#GumUserType" title="enum GumUserType"><span class="returnvalue">GumUserType</span></a>
+gum_user_type_from_string (<em class="parameter"><code>const <a href="http://library.gnome.org/devel/glib/unstable/glib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *type</code></em>);</pre>
+<p>Validates and then converts it to the correct user type</p>
+<div class="refsect3">
+<a name="id-1.5.12.8.4.5"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>type</p></td>
+<td class="parameter_description"><p> the user type string to convert. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="id-1.5.12.8.4.6"></a><h4>Returns</h4>
+<p> <a class="link" href="gumd-Gum-User-Types.html#GumUserType" title="enum GumUserType"><span class="type">GumUserType</span></a> if conversion succeeds, GUM_USERTYPE_NONE otherwise.</p>
+<p></p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gum-user-type-to-strv"></a><h3>gum_user_type_to_strv ()</h3>
+<pre class="programlisting"><a href="http://library.gnome.org/devel/glib/unstable/glib-Basic-Types.html#gchar"><span class="returnvalue">gchar</span></a> **
+gum_user_type_to_strv (<em class="parameter"><code><span class="type">guint16</span> types</code></em>);</pre>
+<p>Converts enumerated <a class="link" href="gumd-Gum-User-Types.html#GumUserType" title="enum GumUserType"><span class="type">GumUserType</span></a> types into an array of string of user type.</p>
+<div class="refsect3">
+<a name="id-1.5.12.8.5.5"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>types</p></td>
+<td class="parameter_description"><p>the type(s) of the user OR'd as per defined as <a class="link" href="gumd-Gum-User-Types.html#GumUserType" title="enum GumUserType"><span class="type">GumUserType</span></a>
+e.g. GUM_USERTYPE_SYSTEM | GUM_USERTYPE_NORMAL</p></td>
+<td class="parameter_annotations"> </td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="id-1.5.12.8.5.6"></a><h4>Returns</h4>
+<p> (transfer full) if successful returns a string, NULL otherwise.</p>
+<p></p>
+</div>
+</div>
+<hr>
+<div class="refsect2">
+<a name="gum-user-type-from-strv"></a><h3>gum_user_type_from_strv ()</h3>
+<pre class="programlisting"><span class="returnvalue">guint16</span>
+gum_user_type_from_strv (<em class="parameter"><code>const <a href="http://library.gnome.org/devel/glib/unstable/glib-Basic-Types.html#gchar"><span class="type">gchar</span></a> *const *types</code></em>);</pre>
+<p>Converts the string consisting of types to a single uint16 by ORing each
+type as <a class="link" href="gumd-Gum-User-Types.html#GumUserType" title="enum GumUserType"><span class="type">GumUserType</span></a> e.g. if string array contains guest and normal, then
+result would be GUM_USERTYPE_GUEST | GUM_USERTYPE_NORMAL</p>
+<div class="refsect3">
+<a name="id-1.5.12.8.6.5"></a><h4>Parameters</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="150px" class="parameters_name">
+<col class="parameters_description">
+<col width="200px" class="parameters_annotations">
+</colgroup>
+<tbody><tr>
+<td class="parameter_name"><p>types</p></td>
+<td class="parameter_description"><p> an array of string of user types. </p></td>
+<td class="parameter_annotations"><span class="annotation">[<acronym title="Don't free data after the code is done."><span class="acronym">transfer none</span></acronym>]</span></td>
+</tr></tbody>
+</table></div>
+</div>
+<div class="refsect3">
+<a name="id-1.5.12.8.6.6"></a><h4>Returns</h4>
+<p> if successful returns the converted types, GUM_USERTYPE_NONE
+otherwise.</p>
+<p></p>
+</div>
+</div>
+</div>
+<div class="refsect1">
+<a name="gumd-Gum-User-Types.other_details"></a><h2>Types and Values</h2>
+<div class="refsect2">
+<a name="GUM-USERTYPE-COUNT:CAPS"></a><h3>GUM_USERTYPE_COUNT</h3>
+<pre class="programlisting">#define GUM_USERTYPE_COUNT   5
+</pre>
+<p>Defines total number of types of the users.</p>
+</div>
+<hr>
+<div class="refsect2">
+<a name="GumUserType"></a><h3>enum GumUserType</h3>
+<p>This enumeration lists users types.</p>
+<div class="refsect3">
+<a name="id-1.5.12.9.3.4"></a><h4>Members</h4>
+<div class="informaltable"><table width="100%" border="0">
+<colgroup>
+<col width="300px" class="enum_members_name">
+<col class="enum_members_description">
+<col width="200px" class="enum_members_annotations">
+</colgroup>
+<tbody>
+<tr>
+<td class="enum_member_name"><p><a name="GUM-USERTYPE-NONE:CAPS"></a>GUM_USERTYPE_NONE</p></td>
+<td class="enum_member_description">
+<p>user type not defined/set/invalid</p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="GUM-USERTYPE-SYSTEM:CAPS"></a>GUM_USERTYPE_SYSTEM</p></td>
+<td class="enum_member_description">
+<p>no home directory will be created for system user.
+System user is not able to use login/logout functionality as
+its primary usage is limited to system daemons. Uid will be chosen between
+<a class="link" href="gumd-General-configuration.html#GUM-CONFIG-GENERAL-SYS-UID-MIN:CAPS" title="GUM_CONFIG_GENERAL_SYS_UID_MIN"><span class="type">GUM_CONFIG_GENERAL_SYS_UID_MIN</span></a> and <a class="link" href="gumd-General-configuration.html#GUM-CONFIG-GENERAL-SYS-UID-MAX:CAPS" title="GUM_CONFIG_GENERAL_SYS_UID_MAX"><span class="type">GUM_CONFIG_GENERAL_SYS_UID_MAX</span></a></p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="GUM-USERTYPE-ADMIN:CAPS"></a>GUM_USERTYPE_ADMIN</p></td>
+<td class="enum_member_description">
+<p>admin user is similar to normal user with the addition
+that it will be assigned to admin user groups at the time of account
+creation. Uid will be chosen between <a class="link" href="gumd-General-configuration.html#GUM-CONFIG-GENERAL-UID-MIN:CAPS" title="GUM_CONFIG_GENERAL_UID_MIN"><span class="type">GUM_CONFIG_GENERAL_UID_MIN</span></a> and
+<a class="link" href="gumd-General-configuration.html#GUM-CONFIG-GENERAL-UID-MAX:CAPS" title="GUM_CONFIG_GENERAL_UID_MAX"><span class="type">GUM_CONFIG_GENERAL_UID_MAX</span></a></p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="GUM-USERTYPE-GUEST:CAPS"></a>GUM_USERTYPE_GUEST</p></td>
+<td class="enum_member_description">
+<p>guest user does not need secret/password to login.
+Guest user home directory is created with login and cleaned up/destroyed
+when user logs out. Uid will be chosen between <a class="link" href="gumd-General-configuration.html#GUM-CONFIG-GENERAL-UID-MIN:CAPS" title="GUM_CONFIG_GENERAL_UID_MIN"><span class="type">GUM_CONFIG_GENERAL_UID_MIN</span></a>
+and <a class="link" href="gumd-General-configuration.html#GUM-CONFIG-GENERAL-UID-MAX:CAPS" title="GUM_CONFIG_GENERAL_UID_MAX"><span class="type">GUM_CONFIG_GENERAL_UID_MAX</span></a></p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+<tr>
+<td class="enum_member_name"><p><a name="GUM-USERTYPE-NORMAL:CAPS"></a>GUM_USERTYPE_NORMAL</p></td>
+<td class="enum_member_description">
+<p>normal user with home directory created based on prefix
+<a class="link" href="gumd-General-configuration.html#GUM-CONFIG-GENERAL-HOME-DIR-PREF:CAPS" title="GUM_CONFIG_GENERAL_HOME_DIR_PREF"><span class="type">GUM_CONFIG_GENERAL_HOME_DIR_PREF</span></a>. Contents of <a class="link" href="gumd-General-configuration.html#GUM-CONFIG-GENERAL-SKEL-DIR:CAPS" title="GUM_CONFIG_GENERAL_SKEL_DIR"><span class="type">GUM_CONFIG_GENERAL_SKEL_DIR</span></a>
+are copied to the home directory. Uid will be chosen between
+<a class="link" href="gumd-General-configuration.html#GUM-CONFIG-GENERAL-UID-MIN:CAPS" title="GUM_CONFIG_GENERAL_UID_MIN"><span class="type">GUM_CONFIG_GENERAL_UID_MIN</span></a> and <a class="link" href="gumd-General-configuration.html#GUM-CONFIG-GENERAL-UID-MAX:CAPS" title="GUM_CONFIG_GENERAL_UID_MAX"><span class="type">GUM_CONFIG_GENERAL_UID_MAX</span></a></p>
+</td>
+<td class="enum_member_annotations"> </td>
+</tr>
+</tbody>
+</table></div>
+</div>
+</div>
+</div>
+</div>
+<div class="footer">
+<hr>
+          Generated by GTK-Doc V1.20</div>
+</body>
+</html>
\ No newline at end of file
index 10643a6..8d8af33 100644 (file)
@@ -7,7 +7,7 @@
 <link rel="home" href="index.html" title="gumd API Reference Manual">
 <link rel="up" href="ch02.html" title="Common">
 <link rel="prev" href="gumd-Gum-String-Utils.html" title="Gum String Utils">
-<link rel="next" href="gumd-User-types.html" title="User types">
+<link rel="next" href="gumd-Gum-User-Types.html" title="Gum User Types">
 <meta name="generator" content="GTK-Doc V1.20 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
 </head>
@@ -21,7 +21,7 @@
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="ch02.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="gumd-Gum-String-Utils.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="gumd-User-types.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+<td><a accesskey="n" href="gumd-Gum-User-Types.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refentry">
 <a name="gumd-Gum-Utils"></a><div class="titlepage"></div>
index fa62624..3bdb3b0 100644 (file)
@@ -7,7 +7,7 @@
 <link rel="home" href="index.html" title="gumd API Reference Manual">
 <link rel="up" href="ch02.html" title="Common">
 <link rel="prev" href="gumd-Gum-Crypt.html" title="Gum Crypt">
-<link rel="next" href="gumd-Errors.html" title="Errors">
+<link rel="next" href="gumd-Gum-Error.html" title="Gum Error">
 <meta name="generator" content="GTK-Doc V1.20 (XML mode)">
 <link rel="stylesheet" href="style.css" type="text/css">
 </head>
@@ -21,7 +21,7 @@
 <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
 <td><a accesskey="u" href="ch02.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
 <td><a accesskey="p" href="gumd-Gum-Crypt.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="gumd-Errors.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
+<td><a accesskey="n" href="gumd-Gum-Error.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
 </tr></table>
 <div class="refentry">
 <a name="gumd-Logging"></a><div class="titlepage"></div>
diff --git a/docs/html/gumd-User-types.html b/docs/html/gumd-User-types.html
deleted file mode 100644 (file)
index 269868c..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-<html>
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-<title>gumd API Reference Manual: User types</title>
-<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
-<link rel="home" href="index.html" title="gumd API Reference Manual">
-<link rel="up" href="ch02.html" title="Common">
-<link rel="prev" href="gumd-Gum-Utils.html" title="Gum Utils">
-<link rel="next" href="gumd-Group-types.html" title="Group types">
-<meta name="generator" content="GTK-Doc V1.20 (XML mode)">
-<link rel="stylesheet" href="style.css" type="text/css">
-</head>
-<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
-<table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="10"><tr valign="middle">
-<td width="100%" align="left" class="shortcuts">
-<a href="#" class="shortcut">Top</a><span id="nav_description"> <span class="dim">|</span> 
-                  <a href="#gumd-User-types.description" class="shortcut">Description</a></span><span id="nav_hierarchy"> <span class="dim">|</span> 
-                  <a href="#gumd-User-types.object-hierarchy" class="shortcut">Object Hierarchy</a></span>
-</td>
-<td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td>
-<td><a accesskey="u" href="ch02.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td>
-<td><a accesskey="p" href="gumd-Gum-Utils.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td>
-<td><a accesskey="n" href="gumd-Group-types.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td>
-</tr></table>
-<div class="refentry">
-<a name="gumd-User-types"></a><div class="titlepage"></div>
-<div class="refnamediv"><table width="100%"><tr>
-<td valign="top">
-<h2><span class="refentrytitle"><a name="gumd-User-types.top_of_page"></a>User types</span></h2>
-<p>User types — user types definition</p>
-</td>
-<td class="gallery_image" valign="top" align="right"></td>
-</tr></table></div>
-<div class="refsect1">
-<a name="gumd-User-types.other"></a><h2>Types and Values</h2>
-<div class="informaltable"><table width="100%" border="0">
-<colgroup>
-<col width="150px" class="name">
-<col class="description">
-</colgroup>
-<tbody><tr>
-<td class="datatype_keyword">enum</td>
-<td class="function_name"><a class="link" href="gumd-User-types.html#GumUserType" title="enum GumUserType">GumUserType</a></td>
-</tr></tbody>
-</table></div>
-</div>
-<div class="refsect1">
-<a name="gumd-User-types.object-hierarchy"></a><h2>Object Hierarchy</h2>
-<pre class="screen">
-</pre>
-</div>
-<div class="refsect1">
-<a name="gumd-User-types.description"></a><h2>Description</h2>
-<p>This file provides various types of users that can be created by the user
-management framework.</p>
-</div>
-<div class="refsect1">
-<a name="gumd-User-types.functions_details"></a><h2>Functions</h2>
-</div>
-<div class="refsect1">
-<a name="gumd-User-types.other_details"></a><h2>Types and Values</h2>
-<div class="refsect2">
-<a name="GumUserType"></a><h3>enum GumUserType</h3>
-<p>This enumeration lists users types.</p>
-<div class="refsect3">
-<a name="id-1.5.12.7.2.4"></a><h4>Members</h4>
-<div class="informaltable"><table width="100%" border="0">
-<colgroup>
-<col width="300px" class="enum_members_name">
-<col class="enum_members_description">
-<col width="200px" class="enum_members_annotations">
-</colgroup>
-<tbody>
-<tr>
-<td class="enum_member_name"><p><a name="GUM-USERTYPE-NONE:CAPS"></a>GUM_USERTYPE_NONE</p></td>
-<td class="enum_member_description">
-<p>user type not defined/set</p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GUM-USERTYPE-SYSTEM:CAPS"></a>GUM_USERTYPE_SYSTEM</p></td>
-<td class="enum_member_description">
-<p>no home directory will be created for system user.
-System user is not able to use login/logout functionality as
-its primary usage is limited to system daemons. Uid will be chosen between
-<a class="link" href="gumd-General-configuration.html#GUM-CONFIG-GENERAL-SYS-UID-MIN:CAPS" title="GUM_CONFIG_GENERAL_SYS_UID_MIN"><span class="type">GUM_CONFIG_GENERAL_SYS_UID_MIN</span></a> and <a class="link" href="gumd-General-configuration.html#GUM-CONFIG-GENERAL-SYS-UID-MAX:CAPS" title="GUM_CONFIG_GENERAL_SYS_UID_MAX"><span class="type">GUM_CONFIG_GENERAL_SYS_UID_MAX</span></a></p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GUM-USERTYPE-ADMIN:CAPS"></a>GUM_USERTYPE_ADMIN</p></td>
-<td class="enum_member_description">
-<p>admin user is similar to normal user with the addition
-that it will be assigned to admin user groups at the time of account
-creation. Uid will be chosen between <a class="link" href="gumd-General-configuration.html#GUM-CONFIG-GENERAL-UID-MIN:CAPS" title="GUM_CONFIG_GENERAL_UID_MIN"><span class="type">GUM_CONFIG_GENERAL_UID_MIN</span></a> and
-<a class="link" href="gumd-General-configuration.html#GUM-CONFIG-GENERAL-UID-MAX:CAPS" title="GUM_CONFIG_GENERAL_UID_MAX"><span class="type">GUM_CONFIG_GENERAL_UID_MAX</span></a></p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GUM-USERTYPE-GUEST:CAPS"></a>GUM_USERTYPE_GUEST</p></td>
-<td class="enum_member_description">
-<p>guest user does not need secret/password to login.
-Guest user home directory is created with login and cleaned up/destroyed
-when user logs out. Uid will be chosen between <a class="link" href="gumd-General-configuration.html#GUM-CONFIG-GENERAL-UID-MIN:CAPS" title="GUM_CONFIG_GENERAL_UID_MIN"><span class="type">GUM_CONFIG_GENERAL_UID_MIN</span></a>
-and <a class="link" href="gumd-General-configuration.html#GUM-CONFIG-GENERAL-UID-MAX:CAPS" title="GUM_CONFIG_GENERAL_UID_MAX"><span class="type">GUM_CONFIG_GENERAL_UID_MAX</span></a></p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-<tr>
-<td class="enum_member_name"><p><a name="GUM-USERTYPE-NORMAL:CAPS"></a>GUM_USERTYPE_NORMAL</p></td>
-<td class="enum_member_description">
-<p>normal user with home directory created based on prefix
-<a class="link" href="gumd-General-configuration.html#GUM-CONFIG-GENERAL-HOME-DIR-PREF:CAPS" title="GUM_CONFIG_GENERAL_HOME_DIR_PREF"><span class="type">GUM_CONFIG_GENERAL_HOME_DIR_PREF</span></a>. Contents of <a class="link" href="gumd-General-configuration.html#GUM-CONFIG-GENERAL-SKEL-DIR:CAPS" title="GUM_CONFIG_GENERAL_SKEL_DIR"><span class="type">GUM_CONFIG_GENERAL_SKEL_DIR</span></a>
-are copied to the home directory. Uid will be chosen between
-<a class="link" href="gumd-General-configuration.html#GUM-CONFIG-GENERAL-UID-MIN:CAPS" title="GUM_CONFIG_GENERAL_UID_MIN"><span class="type">GUM_CONFIG_GENERAL_UID_MIN</span></a> and <a class="link" href="gumd-General-configuration.html#GUM-CONFIG-GENERAL-UID-MAX:CAPS" title="GUM_CONFIG_GENERAL_UID_MAX"><span class="type">GUM_CONFIG_GENERAL_UID_MAX</span></a></p>
-</td>
-<td class="enum_member_annotations"> </td>
-</tr>
-</tbody>
-</table></div>
-</div>
-</div>
-</div>
-</div>
-<div class="footer">
-<hr>
-          Generated by GTK-Doc V1.20</div>
-</body>
-</html>
\ No newline at end of file
index 600cec1..6966b67 100644 (file)
       <sub name="GumDictionary" link="gumd-GumDictionary.html"/>
       <sub name="Gum Crypt" link="gumd-Gum-Crypt.html"/>
       <sub name="Logging" link="gumd-Logging.html"/>
-      <sub name="Errors" link="gumd-Errors.html"/>
+      <sub name="Gum Error" link="gumd-Gum-Error.html"/>
       <sub name="GumDisposable" link="GumDisposable.html"/>
       <sub name="Gum File" link="gumd-Gum-File.html"/>
       <sub name="Gum Validate" link="gumd-Gum-Validate.html"/>
       <sub name="Gum Lock" link="gumd-Gum-Lock.html"/>
       <sub name="Gum String Utils" link="gumd-Gum-String-Utils.html"/>
       <sub name="Gum Utils" link="gumd-Gum-Utils.html"/>
-      <sub name="User types" link="gumd-User-types.html"/>
+      <sub name="Gum User Types" link="gumd-Gum-User-Types.html"/>
       <sub name="Group types" link="gumd-Group-types.html"/>
     </sub>
     <sub name="Client library (libgum) interface" link="ch03.html">
     <keyword type="macro" name="WARN()" link="gumd-Logging.html#WARN:CAPS"/>
     <keyword type="macro" name="INFO()" link="gumd-Logging.html#INFO:CAPS"/>
     <keyword type="macro" name="DBG()" link="gumd-Logging.html#DBG:CAPS"/>
-    <keyword type="macro" name="GUM_ERROR" link="gumd-Errors.html#GUM-ERROR:CAPS"/>
-    <keyword type="macro" name="GUM_GET_ERROR_FOR_ID()" link="gumd-Errors.html#GUM-GET-ERROR-FOR-ID:CAPS"/>
-    <keyword type="macro" name="GUM_SET_ERROR()" link="gumd-Errors.html#GUM-SET-ERROR:CAPS"/>
-    <keyword type="macro" name="GUM_RETURN_WITH_ERROR()" link="gumd-Errors.html#GUM-RETURN-WITH-ERROR:CAPS"/>
-    <keyword type="function" name="gum_error_quark ()" link="gumd-Errors.html#gum-error-quark"/>
-    <keyword type="function" name="gum_error_new_from_variant ()" link="gumd-Errors.html#gum-error-new-from-variant"/>
-    <keyword type="function" name="gum_error_to_variant ()" link="gumd-Errors.html#gum-error-to-variant"/>
-    <keyword type="enum" name="enum GumError" link="gumd-Errors.html#GumError"/>
+    <keyword type="macro" name="GUM_ERROR" link="gumd-Gum-Error.html#GUM-ERROR:CAPS"/>
+    <keyword type="macro" name="GUM_GET_ERROR_FOR_ID()" link="gumd-Gum-Error.html#GUM-GET-ERROR-FOR-ID:CAPS"/>
+    <keyword type="macro" name="GUM_SET_ERROR()" link="gumd-Gum-Error.html#GUM-SET-ERROR:CAPS"/>
+    <keyword type="macro" name="GUM_RETURN_WITH_ERROR()" link="gumd-Gum-Error.html#GUM-RETURN-WITH-ERROR:CAPS"/>
+    <keyword type="function" name="gum_error_quark ()" link="gumd-Gum-Error.html#gum-error-quark"/>
+    <keyword type="function" name="gum_error_new_from_variant ()" link="gumd-Gum-Error.html#gum-error-new-from-variant"/>
+    <keyword type="function" name="gum_error_to_variant ()" link="gumd-Gum-Error.html#gum-error-to-variant"/>
+    <keyword type="enum" name="enum GumError" link="gumd-Gum-Error.html#GumError"/>
     <keyword type="function" name="gum_disposable_set_auto_dispose ()" link="GumDisposable.html#gum-disposable-set-auto-dispose"/>
     <keyword type="function" name="gum_disposable_get_auto_dispose ()" link="GumDisposable.html#gum-disposable-get-auto-dispose"/>
     <keyword type="function" name="gum_disposable_set_timeout ()" link="GumDisposable.html#gum-disposable-set-timeout"/>
     <keyword type="function" name="gum_utils_gain_privileges ()" link="gumd-Gum-Utils.html#gum-utils-gain-privileges"/>
     <keyword type="function" name="gum_utils_run_user_scripts ()" link="gumd-Gum-Utils.html#gum-utils-run-user-scripts"/>
     <keyword type="function" name="gum_utils_run_group_scripts ()" link="gumd-Gum-Utils.html#gum-utils-run-group-scripts"/>
-    <keyword type="enum" name="enum GumUserType" link="gumd-User-types.html#GumUserType"/>
+    <keyword type="macro" name="GUM_USERTYPE_MAX_VALUE" link="gumd-Gum-User-Types.html#GUM-USERTYPE-MAX-VALUE:CAPS"/>
+    <keyword type="function" name="gum_user_type_to_string ()" link="gumd-Gum-User-Types.html#gum-user-type-to-string"/>
+    <keyword type="function" name="gum_user_type_from_string ()" link="gumd-Gum-User-Types.html#gum-user-type-from-string"/>
+    <keyword type="function" name="gum_user_type_to_strv ()" link="gumd-Gum-User-Types.html#gum-user-type-to-strv"/>
+    <keyword type="function" name="gum_user_type_from_strv ()" link="gumd-Gum-User-Types.html#gum-user-type-from-strv"/>
+    <keyword type="macro" name="GUM_USERTYPE_COUNT" link="gumd-Gum-User-Types.html#GUM-USERTYPE-COUNT:CAPS"/>
+    <keyword type="enum" name="enum GumUserType" link="gumd-Gum-User-Types.html#GumUserType"/>
     <keyword type="enum" name="enum GumGroupType" link="gumd-Group-types.html#GumGroupType"/>
     <keyword type="function" name="GumUserCb ()" link="GumUser.html#GumUserCb"/>
     <keyword type="function" name="gum_user_create ()" link="GumUser.html#gum-user-create"/>
index 457d11d..1762ba3 100644 (file)
@@ -15,7 +15,7 @@
 <div>
 <div><table class="navigation" id="top" width="100%" cellpadding="2" cellspacing="0"><tr><th valign="middle"><p class="title">gumd API Reference Manual</p></th></tr></table></div>
 <div><p class="releaseinfo">This document discusses the details of user management 
-        daemon (gumd) and client library (libgum) with version 1.0.4
+        daemon (gumd) and client library (libgum) with version 1.0.5
 .
         </p></div>
 </div>
@@ -53,7 +53,7 @@
 <span class="refentrytitle"><a href="gumd-Logging.html">Logging</a></span><span class="refpurpose"> — logging facilities</span>
 </dt>
 <dt>
-<span class="refentrytitle"><a href="gumd-Errors.html">Errors</a></span><span class="refpurpose"> — error definitions and utilities</span>
+<span class="refentrytitle"><a href="gumd-Gum-Error.html">Gum Error</a></span><span class="refpurpose"> — error definitions and utilities</span>
 </dt>
 <dt>
 <span class="refentrytitle"><a href="GumDisposable.html">GumDisposable</a></span><span class="refpurpose"> — timer-based auto disposable object</span>
@@ -74,7 +74,7 @@
 <span class="refentrytitle"><a href="gumd-Gum-Utils.html">Gum Utils</a></span><span class="refpurpose"> — Utility functions</span>
 </dt>
 <dt>
-<span class="refentrytitle"><a href="gumd-User-types.html">User types</a></span><span class="refpurpose"> — user types definition</span>
+<span class="refentrytitle"><a href="gumd-Gum-User-Types.html">Gum User Types</a></span><span class="refpurpose"> — Utility functions for user types</span>
 </dt>
 <dt>
 <span class="refentrytitle"><a href="gumd-Group-types.html">Group types</a></span><span class="refpurpose"> — group types definition</span>
index 8ae88da..f130d6c 100644 (file)
 <ANCHOR id="INFO:CAPS" href="gumd/gumd-Logging.html#INFO:CAPS">
 <ANCHOR id="DBG:CAPS" href="gumd/gumd-Logging.html#DBG:CAPS">
 <ANCHOR id="gumd-Logging.other_details" href="gumd/gumd-Logging.html#gumd-Logging.other_details">
-<ANCHOR id="gumd-Errors" href="gumd/gumd-Errors.html">
-<ANCHOR id="gumd-Errors.functions" href="gumd/gumd-Errors.html#gumd-Errors.functions">
-<ANCHOR id="gumd-Errors.other" href="gumd/gumd-Errors.html#gumd-Errors.other">
-<ANCHOR id="gumd-Errors.object-hierarchy" href="gumd/gumd-Errors.html#gumd-Errors.object-hierarchy">
-<ANCHOR id="gumd-Errors.includes" href="gumd/gumd-Errors.html#gumd-Errors.includes">
-<ANCHOR id="gumd-Errors.description" href="gumd/gumd-Errors.html#gumd-Errors.description">
-<ANCHOR id="gumd-Errors.functions_details" href="gumd/gumd-Errors.html#gumd-Errors.functions_details">
-<ANCHOR id="GUM-ERROR:CAPS" href="gumd/gumd-Errors.html#GUM-ERROR:CAPS">
-<ANCHOR id="GUM-GET-ERROR-FOR-ID:CAPS" href="gumd/gumd-Errors.html#GUM-GET-ERROR-FOR-ID:CAPS">
-<ANCHOR id="GUM-SET-ERROR:CAPS" href="gumd/gumd-Errors.html#GUM-SET-ERROR:CAPS">
-<ANCHOR id="GUM-RETURN-WITH-ERROR:CAPS" href="gumd/gumd-Errors.html#GUM-RETURN-WITH-ERROR:CAPS">
-<ANCHOR id="gum-error-quark" href="gumd/gumd-Errors.html#gum-error-quark">
-<ANCHOR id="gum-error-new-from-variant" href="gumd/gumd-Errors.html#gum-error-new-from-variant">
-<ANCHOR id="gum-error-to-variant" href="gumd/gumd-Errors.html#gum-error-to-variant">
-<ANCHOR id="gumd-Errors.other_details" href="gumd/gumd-Errors.html#gumd-Errors.other_details">
-<ANCHOR id="GumError" href="gumd/gumd-Errors.html#GumError">
+<ANCHOR id="gumd-Gum-Error" href="gumd/gumd-Gum-Error.html">
+<ANCHOR id="gumd-Gum-Error.functions" href="gumd/gumd-Gum-Error.html#gumd-Gum-Error.functions">
+<ANCHOR id="gumd-Gum-Error.other" href="gumd/gumd-Gum-Error.html#gumd-Gum-Error.other">
+<ANCHOR id="gumd-Gum-Error.object-hierarchy" href="gumd/gumd-Gum-Error.html#gumd-Gum-Error.object-hierarchy">
+<ANCHOR id="gumd-Gum-Error.includes" href="gumd/gumd-Gum-Error.html#gumd-Gum-Error.includes">
+<ANCHOR id="gumd-Gum-Error.description" href="gumd/gumd-Gum-Error.html#gumd-Gum-Error.description">
+<ANCHOR id="gumd-Gum-Error.functions_details" href="gumd/gumd-Gum-Error.html#gumd-Gum-Error.functions_details">
+<ANCHOR id="GUM-ERROR:CAPS" href="gumd/gumd-Gum-Error.html#GUM-ERROR:CAPS">
+<ANCHOR id="GUM-GET-ERROR-FOR-ID:CAPS" href="gumd/gumd-Gum-Error.html#GUM-GET-ERROR-FOR-ID:CAPS">
+<ANCHOR id="GUM-SET-ERROR:CAPS" href="gumd/gumd-Gum-Error.html#GUM-SET-ERROR:CAPS">
+<ANCHOR id="GUM-RETURN-WITH-ERROR:CAPS" href="gumd/gumd-Gum-Error.html#GUM-RETURN-WITH-ERROR:CAPS">
+<ANCHOR id="gum-error-quark" href="gumd/gumd-Gum-Error.html#gum-error-quark">
+<ANCHOR id="gum-error-new-from-variant" href="gumd/gumd-Gum-Error.html#gum-error-new-from-variant">
+<ANCHOR id="gum-error-to-variant" href="gumd/gumd-Gum-Error.html#gum-error-to-variant">
+<ANCHOR id="gumd-Gum-Error.other_details" href="gumd/gumd-Gum-Error.html#gumd-Gum-Error.other_details">
+<ANCHOR id="GumError" href="gumd/gumd-Gum-Error.html#GumError">
 <ANCHOR id="GumDisposable" href="gumd/GumDisposable.html">
 <ANCHOR id="GumDisposable.functions" href="gumd/GumDisposable.html#GumDisposable.functions">
 <ANCHOR id="GumDisposable.properties" href="gumd/GumDisposable.html#GumDisposable.properties">
 <ANCHOR id="gum-utils-run-user-scripts" href="gumd/gumd-Gum-Utils.html#gum-utils-run-user-scripts">
 <ANCHOR id="gum-utils-run-group-scripts" href="gumd/gumd-Gum-Utils.html#gum-utils-run-group-scripts">
 <ANCHOR id="gumd-Gum-Utils.other_details" href="gumd/gumd-Gum-Utils.html#gumd-Gum-Utils.other_details">
-<ANCHOR id="gumd-User-types" href="gumd/gumd-User-types.html">
-<ANCHOR id="gumd-User-types.other" href="gumd/gumd-User-types.html#gumd-User-types.other">
-<ANCHOR id="gumd-User-types.object-hierarchy" href="gumd/gumd-User-types.html#gumd-User-types.object-hierarchy">
-<ANCHOR id="gumd-User-types.description" href="gumd/gumd-User-types.html#gumd-User-types.description">
-<ANCHOR id="gumd-User-types.functions_details" href="gumd/gumd-User-types.html#gumd-User-types.functions_details">
-<ANCHOR id="gumd-User-types.other_details" href="gumd/gumd-User-types.html#gumd-User-types.other_details">
-<ANCHOR id="GumUserType" href="gumd/gumd-User-types.html#GumUserType">
+<ANCHOR id="gumd-Gum-User-Types" href="gumd/gumd-Gum-User-Types.html">
+<ANCHOR id="gumd-Gum-User-Types.functions" href="gumd/gumd-Gum-User-Types.html#gumd-Gum-User-Types.functions">
+<ANCHOR id="gumd-Gum-User-Types.other" href="gumd/gumd-Gum-User-Types.html#gumd-Gum-User-Types.other">
+<ANCHOR id="gumd-Gum-User-Types.object-hierarchy" href="gumd/gumd-Gum-User-Types.html#gumd-Gum-User-Types.object-hierarchy">
+<ANCHOR id="gumd-Gum-User-Types.includes" href="gumd/gumd-Gum-User-Types.html#gumd-Gum-User-Types.includes">
+<ANCHOR id="gumd-Gum-User-Types.description" href="gumd/gumd-Gum-User-Types.html#gumd-Gum-User-Types.description">
+<ANCHOR id="gumd-Gum-User-Types.functions_details" href="gumd/gumd-Gum-User-Types.html#gumd-Gum-User-Types.functions_details">
+<ANCHOR id="GUM-USERTYPE-MAX-VALUE:CAPS" href="gumd/gumd-Gum-User-Types.html#GUM-USERTYPE-MAX-VALUE:CAPS">
+<ANCHOR id="gum-user-type-to-string" href="gumd/gumd-Gum-User-Types.html#gum-user-type-to-string">
+<ANCHOR id="gum-user-type-from-string" href="gumd/gumd-Gum-User-Types.html#gum-user-type-from-string">
+<ANCHOR id="gum-user-type-to-strv" href="gumd/gumd-Gum-User-Types.html#gum-user-type-to-strv">
+<ANCHOR id="gum-user-type-from-strv" href="gumd/gumd-Gum-User-Types.html#gum-user-type-from-strv">
+<ANCHOR id="gumd-Gum-User-Types.other_details" href="gumd/gumd-Gum-User-Types.html#gumd-Gum-User-Types.other_details">
+<ANCHOR id="GUM-USERTYPE-COUNT:CAPS" href="gumd/gumd-Gum-User-Types.html#GUM-USERTYPE-COUNT:CAPS">
+<ANCHOR id="GumUserType" href="gumd/gumd-Gum-User-Types.html#GumUserType">
 <ANCHOR id="gumd-Group-types" href="gumd/gumd-Group-types.html">
 <ANCHOR id="gumd-Group-types.other" href="gumd/gumd-Group-types.html#gumd-Group-types.other">
 <ANCHOR id="gumd-Group-types.object-hierarchy" href="gumd/gumd-Group-types.html#gumd-Group-types.object-hierarchy">
index 3e987ff..d8ec48d 100644 (file)
@@ -53,9 +53,9 @@ G_BEGIN_DECLS
 
 typedef enum {
 
-    GUM_GROUPTYPE_NONE = 0,
-    GUM_GROUPTYPE_SYSTEM = 1,
-    GUM_GROUPTYPE_USER = 2
+    GUM_GROUPTYPE_NONE = 0x0,
+    GUM_GROUPTYPE_SYSTEM = 0x1,
+    GUM_GROUPTYPE_USER = 0x2
 
 } GumGroupType;
 
index 647d3e5..1b6bde7 100644 (file)
@@ -3,7 +3,7 @@
 /*
  * This file is part of gum
  *
- * Copyright (C) 2013 Intel Corporation.
+ * Copyright (C) 2015 Intel Corporation.
  *
  * Contact: Imran Zaman <imran.zaman@intel.com>
  *
@@ -42,7 +42,7 @@ G_BEGIN_DECLS
 
 /**
  * GumUserType:
- * @GUM_USERTYPE_NONE: user type not defined/set
+ * @GUM_USERTYPE_NONE: user type not defined/set/invalid
  * @GUM_USERTYPE_SYSTEM: no home directory will be created for system user.
  * System user is not able to use login/logout functionality as
  * its primary usage is limited to system daemons. Uid will be chosen between
@@ -63,16 +63,44 @@ G_BEGIN_DECLS
  * This enumeration lists users types.
  */
 
-typedef enum {
+/**
+ * GUM_USERTYPE_COUNT:
+ *
+ * Defines total number of types of the users.
+ */
+#define GUM_USERTYPE_COUNT   5
 
-    GUM_USERTYPE_NONE = 0,
-    GUM_USERTYPE_SYSTEM = 1,
-    GUM_USERTYPE_ADMIN = 2,
-    GUM_USERTYPE_GUEST = 3,
-    GUM_USERTYPE_NORMAL = 4
+/**
+ * GUM_USERTYPE_MAX_VALUE:
+ *
+ * Defines the maximum value of the user type in #GumUserType.
+ */
+#define GUM_USERTYPE_MAX_VALUE   (0x1 << (GUM_USERTYPE_COUNT-1))
 
+typedef enum {
+    GUM_USERTYPE_NONE = 0x00,
+    GUM_USERTYPE_SYSTEM = 0x01,
+    GUM_USERTYPE_ADMIN = 0x02,
+    GUM_USERTYPE_GUEST = 0x04,
+    GUM_USERTYPE_NORMAL = 0x08
 } GumUserType;
 
+const gchar *
+gum_user_type_to_string (
+        GumUserType type);
+
+GumUserType
+gum_user_type_from_string (
+        const gchar *type);
+
+gchar **
+gum_user_type_to_strv (
+        guint16 types);
+
+guint16
+gum_user_type_from_strv (
+        const gchar *const *types);
+
 G_END_DECLS
 
 #endif /* __GUM_USER_TYPES_H_ */
diff --git a/include/gum/gum-user-service.h b/include/gum/gum-user-service.h
new file mode 100644 (file)
index 0000000..1592c8e
--- /dev/null
@@ -0,0 +1,111 @@
+/* vi: set et sw=4 ts=4 cino=t0,(0: */
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of gum
+ *
+ * Copyright (C) 2013 - 2015 Intel Corporation.
+ *
+ * Contact: Imran Zaman <imran.zaman@intel.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef __GUM_USER_SERVICE_H_
+#define __GUM_USER_SERVICE_H_
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define GUM_TYPE_USER_SERVICE            (gum_user_service_get_type())
+#define GUM_USER_SERVICE(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), \
+        GUM_TYPE_USER_SERVICE, GumUserService))
+#define GUM_USER_SERVICE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), \
+        GUM_TYPE_USER_SERVICE, GumUserServiceClass))
+#define GUM_IS_USER_SERVICE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
+        GUM_TYPE_USER_SERVICE))
+#define GUM_IS_USER_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), \
+        GUM_TYPE_USER_SERVICE))
+#define GUM_USER_SERVICE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), \
+        GUM_TYPE_USER_SERVICE, GumUserServiceClass))
+
+typedef struct _GumUserService GumUserService;
+typedef struct _GumUserServiceClass GumUserServiceClass;
+typedef struct _GumUserServicePrivate GumUserServicePrivate;
+
+struct _GumUserService
+{
+    GObject parent;
+
+    /* priv */
+    GumUserServicePrivate *priv;
+};
+
+struct _GumUserServiceClass
+{
+    GObjectClass parent_class;
+};
+
+typedef GList GumUserList;
+
+typedef void (*GumUserServiceCb) (
+        GumUserService *service,
+        const GError *error,
+        gpointer user_data);
+
+typedef void (*GumUserServiceListCb) (
+        GumUserService *service,
+        GumUserList *users,
+        const GError *error,
+        gpointer user_data);
+
+GType
+gum_user_service_get_type (void) G_GNUC_CONST;
+
+GumUserService *
+gum_user_service_create (
+        GumUserServiceCb callback,
+        gpointer user_data);
+
+GumUserService *
+gum_user_service_create_sync (
+        gboolean offline);
+
+gboolean
+gum_user_service_get_user_list (
+        GumUserService *self,
+        const gchar *const *types,
+        GumUserServiceListCb callback,
+        gpointer user_data);
+
+GumUserList *
+gum_user_service_get_user_list_sync (
+        GumUserService *self,
+        const gchar *const *types);
+
+void
+gum_user_service_list_free (
+        GumUserList *users);
+
+GDBusProxy *
+gum_user_service_get_dbus_proxy (
+        GumUserService *self);
+
+G_END_DECLS
+
+#endif /* __GUM_USER_SERVICE_H_ */
index 1c5bf98..2695c11 100644 (file)
@@ -49,6 +49,7 @@ libgum_common_la_SOURCES = \
     gum-string-utils.c \
     gum-utils.c \
     gum-validate.c \
+    gum-user-types.c \
     $(NULL)
 
 dist_libgum_common_la_SOURCES = \
index 1816b44..e922444 100644 (file)
@@ -135,7 +135,7 @@ am_libgum_common_la_OBJECTS = libgum_common_la-gum-config.lo \
        libgum_common_la-gum-file.lo \
        libgum_common_la-gum-string-utils.lo \
        libgum_common_la-gum-utils.lo libgum_common_la-gum-validate.lo \
-       $(am__objects_1)
+       libgum_common_la-gum-user-types.lo $(am__objects_1)
 dist_libgum_common_la_OBJECTS = $(am__objects_1)
 libgum_common_la_OBJECTS = $(am_libgum_common_la_OBJECTS) \
        $(dist_libgum_common_la_OBJECTS)
@@ -453,6 +453,7 @@ libgum_common_la_SOURCES = \
     gum-string-utils.c \
     gum-utils.c \
     gum-validate.c \
+    gum-user-types.c \
     $(NULL)
 
 dist_libgum_common_la_SOURCES = \
@@ -550,6 +551,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgum_common_la-gum-file.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgum_common_la-gum-lock.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgum_common_la-gum-string-utils.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgum_common_la-gum-user-types.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgum_common_la-gum-utils.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgum_common_la-gum-validate.Plo@am__quote@
 
@@ -647,6 +649,13 @@ libgum_common_la-gum-validate.lo: gum-validate.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgum_common_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgum_common_la-gum-validate.lo `test -f 'gum-validate.c' || echo '$(srcdir)/'`gum-validate.c
 
+libgum_common_la-gum-user-types.lo: gum-user-types.c
+@am__fastdepCC_TRUE@   $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgum_common_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libgum_common_la-gum-user-types.lo -MD -MP -MF $(DEPDIR)/libgum_common_la-gum-user-types.Tpo -c -o libgum_common_la-gum-user-types.lo `test -f 'gum-user-types.c' || echo '$(srcdir)/'`gum-user-types.c
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/libgum_common_la-gum-user-types.Tpo $(DEPDIR)/libgum_common_la-gum-user-types.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='gum-user-types.c' object='libgum_common_la-gum-user-types.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgum_common_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libgum_common_la-gum-user-types.lo `test -f 'gum-user-types.c' || echo '$(srcdir)/'`gum-user-types.c
+
 mostlyclean-libtool:
        -rm -f *.lo
 
index 7028d0e..43f3e60 100644 (file)
                 </tp:docstring>
             </arg>
         </method>
+
+        <method name="getUserList" tp:name-for-bindings="getUserList">
+            <tp:docstring>Gets the list of the uids of the users
+            </tp:docstring>
+
+            <arg name="types" type="as" direction="in">
+                <tp:docstring>Type of the users to be retrieved. If type is an
+                empty string, all users are fetched. User type is first compared
+                with usertype in gecos field. If gecos field for usertype does
+                not exist, then all the users are considered as normal users
+                other than system users which are filtered out based on system
+                min and max uids.
+                </tp:docstring>
+            </arg>
+
+            <arg name="uids" type="au" direction="out">
+                <tp:docstring>users' list of uids.
+                </tp:docstring>
+            </arg>
+        </method>
         
     </interface>
     
index fe0a7f4..81e10bb 100644 (file)
@@ -107,13 +107,13 @@ struct _GumConfigPrivate
 
 G_DEFINE_TYPE (GumConfig, gum_config, G_TYPE_OBJECT);
 
-#define UID_MIN      2000
+#define UID_MIN      1000
 #define UID_MAX      60000
-#define SYS_UID_MIN  200
+#define SYS_UID_MIN  100
 #define SYS_UID_MAX  999
-#define GID_MIN      2000
+#define GID_MIN      1000
 #define GID_MAX      60000
-#define SYS_GID_MIN  200
+#define SYS_GID_MIN  100
 #define SYS_GID_MAX  999
 
 /* shadow */
index 59b5d5c..1bbed36 100644 (file)
@@ -31,7 +31,7 @@
 /**
  * SECTION:gum-error
  * @short_description: error definitions and utilities
- * @title: Errors
+ * @title: Gum Error
  * @include: gum/common/gum-error.h
  *
  * This file provides Gum error definitions and utilities.
index 1de8212..797b692 100644 (file)
@@ -275,12 +275,17 @@ gum_string_utils_append_string (
 {
     gchar **dest_strv = NULL;
     gint ind = 0;
-    gint len = g_strv_length (src_strv);
+    gint len = 0;
+
+    if (src_strv)
+        len = g_strv_length (src_strv);
 
     dest_strv = g_malloc0 (sizeof (gchar *) * (len + 2));
-    while (src_strv[ind]) {
-        dest_strv[ind] = g_strdup (src_strv[ind]);
-        ind++;
+    if (src_strv) {
+        while (src_strv[ind]) {
+            dest_strv[ind] = g_strdup (src_strv[ind]);
+            ind++;
+        }
     }
     dest_strv[ind++] = g_strdup (string);
     dest_strv[ind] = NULL;
diff --git a/src/common/gum-user-types.c b/src/common/gum-user-types.c
new file mode 100644 (file)
index 0000000..b60a064
--- /dev/null
@@ -0,0 +1,164 @@
+/* vi: set et sw=4 ts=4 cino=t0,(0: */
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of gum
+ *
+ * Copyright (C) 2015 Intel Corporation.
+ *
+ * Contact: Imran Zaman <imran.zaman@intel.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <string.h>
+
+#include "common/gum-user-types.h"
+#include "common/gum-log.h"
+#include "common/gum-error.h"
+
+/**
+ * SECTION:gum-user-types
+ * @short_description: Utility functions for user types
+ * @title: Gum User Types
+ * @include: gum/common/gum-user-types.h
+ *
+ * User type conversion/validation functions
+ */
+
+typedef struct  {
+    GumUserType type;
+    const char *str;
+} GumUserTypeString;
+
+GumUserTypeString user_type_strings[GUM_USERTYPE_COUNT] = {
+        {GUM_USERTYPE_NONE, "none"},
+        {GUM_USERTYPE_SYSTEM, "system"},
+        {GUM_USERTYPE_ADMIN, "admin"},
+        {GUM_USERTYPE_GUEST, "guest"},
+        {GUM_USERTYPE_NORMAL, "normal"}
+};
+
+gint16
+_get_user_type_strings_index (
+        GumUserType type)
+{
+    if (type >= GUM_USERTYPE_MAX_VALUE || type < 0)
+        return -1;
+    gint index = 0;
+    while (type) {
+        type >>= 1;
+        index++;
+    }
+    return index;
+}
+
+/**
+ * gum_user_type_to_string:
+ * @type: the user type enum to convert
+ *
+ * Converts the user type enum to string
+ *
+ * Returns: (transfer none): usertype if conversion succeeds, NULL otherwise.
+ */
+const gchar *
+gum_user_type_to_string (
+        GumUserType type)
+{
+    gint16 ind = _get_user_type_strings_index (type);
+    if (ind <= 0 || ind >= GUM_USERTYPE_COUNT)
+        return NULL;
+    return user_type_strings[ind].str;
+}
+
+/**
+ * gum_user_type_from_string:
+ * @type: (transfer none): the user type string to convert
+ *
+ * Validates and then converts it to the correct user type
+ *
+ * Returns: #GumUserType if conversion succeeds, GUM_USERTYPE_NONE otherwise.
+ */
+GumUserType
+gum_user_type_from_string (
+        const gchar *type)
+{
+    gint i = 0;
+    if (!type || strlen(type) <= 0) {
+        return GUM_USERTYPE_NONE;
+    }
+
+    while (i < GUM_USERTYPE_COUNT) {
+        if (g_strcmp0 (type,  user_type_strings[i].str) == 0)
+            return user_type_strings[i].type;
+        i++;
+    }
+    WARN ("user type %s not found", type);
+    return GUM_USERTYPE_NONE;
+}
+
+/**
+ * gum_user_type_to_strv:
+ * @types: the type(s) of the user OR'd as per defined as #GumUserType
+ * e.g. GUM_USERTYPE_SYSTEM | GUM_USERTYPE_NORMAL
+ *
+ * Converts enumerated #GumUserType types into an array of string of user type.
+ *
+ * Returns: (transfer full) if successful returns a string, NULL otherwise.
+ */
+gchar **
+gum_user_type_to_strv (
+        guint16 types)
+{
+    gint i = 0, ind = 0;
+    gchar **strv = g_malloc0 (sizeof (gchar *) * (GUM_USERTYPE_COUNT + 1));
+    while (i < GUM_USERTYPE_COUNT) {
+        if (types & user_type_strings[i].type) {
+            strv[ind++] = g_strdup ((gchar *) user_type_strings[i].str);
+        }
+        i++;
+    }
+    strv[ind] = NULL;
+    return strv;
+}
+
+/**
+ * gum_user_type_from_strv:
+ * @types: (transfer none): an array of string of user types
+ *
+ * Converts the string consisting of types to a single uint16 by ORing each
+ * type as #GumUserType e.g. if string array contains guest and normal, then
+ * result would be GUM_USERTYPE_GUEST | GUM_USERTYPE_NORMAL
+ *
+ * Returns: if successful returns the converted types, GUM_USERTYPE_NONE
+ * otherwise.
+ */
+guint16
+gum_user_type_from_strv (
+        const gchar *const *types)
+{
+    guint16 res = GUM_USERTYPE_NONE;
+    gint i = 0, len = 0;
+    gchar **strv = (gchar **)types;
+
+    if (!strv || (len = g_strv_length (strv)) <= 0) {
+        return GUM_USERTYPE_NONE;
+    }
+
+    while (i < len) {
+        res |= gum_user_type_from_string (strv[i++]);
+    }
+    return res;
+}
index b2130fa..24fcbb7 100644 (file)
@@ -3,7 +3,7 @@
 /*
  * This file is part of gumd
  *
- * Copyright (C) 2013 Intel Corporation.
+ * Copyright (C) 2013 - 2015 Intel Corporation.
  *
  * Contact: Imran Zaman <imran.zaman@intel.com>
  *
 struct _GumdDaemonUserPrivate
 {
     GumConfig *config;
-    guint16 user_type;
     gchar *nick_name;
 
     /* passwd file entries format:
         * name:passwd:uid:gid:gecos:dir:shell
         * whereas gecos contain the following comma(',') separated values
-        * realname,officelocation,officephone,homephone
+        * realname,officelocation,officephone,homephone,usertype
         */
     struct passwd *pw;
 
@@ -94,6 +93,17 @@ enum
     N_PROPERTIES
 };
 
+typedef enum
+{
+    GECOS_FIELD_REALNAME = 0,
+    GECOS_FIELD_OFFICE,
+    GECOS_FIELD_OFFICEPHONE,
+    GECOS_FIELD_HOMEPHONE,
+    GECOS_FIELD_USERTYPE,
+
+    GECOS_FIELD_COUNT
+}GecosField;
+
 static GParamSpec *properties[N_PROPERTIES];
 
 static void
@@ -121,6 +131,20 @@ _free_shadow_entry (
     }
 }
 
+static GumUserType
+_get_usertype_from_gecos (
+        struct passwd *pw)
+{
+    if (pw && pw->pw_gecos) {
+        gchar *str = gum_string_utils_get_string (pw->pw_gecos, ",",
+                GECOS_FIELD_USERTYPE);
+        GumUserType ut = gum_user_type_from_string (str);
+        g_free (str);
+        return ut;
+    }
+    return GUM_USERTYPE_NONE;
+}
+
 static void
 _set_config_property (
         GumdDaemonUser *self,
@@ -162,10 +186,18 @@ _set_usertype_property (
         GumdDaemonUser *self,
         GumUserType value)
 {
-    if (self->priv->user_type != value) {
-        self->priv->user_type = value;
-        g_object_notify_by_pspec (G_OBJECT (self),
-                properties[PROP_USERTYPE]);
+    if (value > GUM_USERTYPE_NONE && value < GUM_USERTYPE_MAX_VALUE) {
+        GumUserType ut = _get_usertype_from_gecos (self->priv->pw);
+        if (ut != value) {
+            gchar *gecos = gum_string_utils_insert_string (
+                    self->priv->pw->pw_gecos, ",",
+                    gum_user_type_to_string (value), GECOS_FIELD_USERTYPE,
+                    GECOS_FIELD_COUNT);
+            GUM_STR_FREE (self->priv->pw->pw_gecos);
+            self->priv->pw->pw_gecos = gecos;
+            g_object_notify_by_pspec (G_OBJECT (self),
+                    properties[PROP_USERTYPE]);
+        }
     }
 }
 
@@ -215,11 +247,12 @@ _set_realname_property (
         const gchar *value)
 {
     gchar *str = gum_string_utils_get_string (self->priv->pw->pw_gecos, ",",
-            0);
+            GECOS_FIELD_REALNAME);
     if (g_strcmp0 (value, str) != 0 &&
         gum_validate_db_string_entry (value, NULL)) {
         gchar *gecos = gum_string_utils_insert_string (
-                self->priv->pw->pw_gecos, ",", value, 0, 4);
+                self->priv->pw->pw_gecos, ",", value, GECOS_FIELD_REALNAME,
+                GECOS_FIELD_COUNT);
         GUM_STR_FREE (self->priv->pw->pw_gecos);
         self->priv->pw->pw_gecos = gecos;
         g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_REALNAME]);
@@ -233,11 +266,12 @@ _set_office_property (
         const gchar *value)
 {
     gchar *str = gum_string_utils_get_string (self->priv->pw->pw_gecos, ",",
-            1);
+            GECOS_FIELD_OFFICE);
     if (g_strcmp0 (value, str) != 0 &&
         gum_validate_db_string_entry (value, NULL)) {
         gchar *gecos = gum_string_utils_insert_string (
-                self->priv->pw->pw_gecos, ",", value, 1, 4);
+                self->priv->pw->pw_gecos, ",", value, GECOS_FIELD_OFFICE,
+                GECOS_FIELD_COUNT);
         GUM_STR_FREE (self->priv->pw->pw_gecos);
         self->priv->pw->pw_gecos = gecos;
         g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_OFFICE]);
@@ -251,11 +285,12 @@ _set_officephone_property (
         const gchar *value)
 {
     gchar *str = gum_string_utils_get_string (self->priv->pw->pw_gecos, ",",
-            2);
+            GECOS_FIELD_OFFICEPHONE);
     if (g_strcmp0 (value, str) != 0 &&
         gum_validate_db_string_entry (value, NULL)) {
         gchar *gecos = gum_string_utils_insert_string (
-                self->priv->pw->pw_gecos, ",", value, 2, 4);
+                self->priv->pw->pw_gecos, ",", value, GECOS_FIELD_OFFICEPHONE,
+                GECOS_FIELD_COUNT);
         GUM_STR_FREE (self->priv->pw->pw_gecos);
         self->priv->pw->pw_gecos = gecos;
         g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_OFFICEPHONE]);
@@ -269,11 +304,12 @@ _set_homephone_property (
         const gchar *value)
 {
     gchar *str = gum_string_utils_get_string (self->priv->pw->pw_gecos, ",",
-            3);
+            GECOS_FIELD_HOMEPHONE);
     if (g_strcmp0 (value, str) != 0 &&
         gum_validate_db_string_entry (value, NULL)) {
         gchar *gecos = gum_string_utils_insert_string (
-                self->priv->pw->pw_gecos, ",", value, 3, 4);
+                self->priv->pw->pw_gecos, ",", value, GECOS_FIELD_HOMEPHONE,
+                GECOS_FIELD_COUNT);
         GUM_STR_FREE (self->priv->pw->pw_gecos);
         self->priv->pw->pw_gecos = gecos;
         g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_HOMEPHONE]);
@@ -397,7 +433,8 @@ _get_property (
             break;
         }
         case PROP_USERTYPE: {
-            g_value_set_uint (value, (guint)self->priv->user_type);
+            g_value_set_uint (value,
+                    (guint)_get_usertype_from_gecos(self->priv->pw));
             break;
         }
         case PROP_NICKNAME: {
@@ -415,7 +452,7 @@ _get_property (
         case PROP_REALNAME: {
             if (self->priv->pw->pw_gecos) {
                 gchar *str = gum_string_utils_get_string (
-                        self->priv->pw->pw_gecos, ",", 0);
+                        self->priv->pw->pw_gecos, ",", GECOS_FIELD_REALNAME);
                 if (str) {
                     g_value_set_string (value, str);
                     g_free (str);
@@ -426,7 +463,7 @@ _get_property (
         case PROP_OFFICE: {
             if (self->priv->pw->pw_gecos) {
                 gchar *str = gum_string_utils_get_string (
-                        self->priv->pw->pw_gecos, ",", 1);
+                        self->priv->pw->pw_gecos, ",", GECOS_FIELD_OFFICE);
                 if (str) {
                     g_value_set_string (value, str);
                     g_free (str);
@@ -437,7 +474,7 @@ _get_property (
         case PROP_OFFICEPHONE: {
             if (self->priv->pw->pw_gecos) {
                 gchar *str = gum_string_utils_get_string (
-                        self->priv->pw->pw_gecos, ",", 2);
+                        self->priv->pw->pw_gecos, ",", GECOS_FIELD_OFFICEPHONE);
                 if (str) {
                     g_value_set_string (value, str);
                     g_free (str);
@@ -448,7 +485,7 @@ _get_property (
         case PROP_HOMEPHONE: {
             if (self->priv->pw->pw_gecos) {
                 gchar *str = gum_string_utils_get_string (
-                        self->priv->pw->pw_gecos, ",", 3);
+                        self->priv->pw->pw_gecos, ",", GECOS_FIELD_HOMEPHONE);
                 if (str) {
                     g_value_set_string (value, str);
                     g_free (str);
@@ -655,7 +692,8 @@ _set_daemon_user_name (
         }
         g_free (tname);
         return TRUE;
-    } else if (self->priv->user_type == GUM_USERTYPE_SYSTEM) {
+    } else if (_get_usertype_from_gecos (self->priv->pw) ==
+            GUM_USERTYPE_SYSTEM) {
         GUM_RETURN_WITH_ERROR (GUM_ERROR_INVALID_NAME,
                 "System user name must exist with pattern "
                 GUM_NAME_PATTERN, error, FALSE);
@@ -683,22 +721,23 @@ _set_daemon_user_name (
 
 static gboolean
 _get_default_uid_range (
-        GumdDaemonUser *self,
+        GumUserType ut,
+        GumConfig *config,
         uid_t *min,
         uid_t *max)
 {
-    if (self->priv->user_type == GUM_USERTYPE_SYSTEM)
-        *min = (uid_t) gum_config_get_uint (self->priv->config,
+    if (ut == GUM_USERTYPE_SYSTEM)
+        *min = (uid_t) gum_config_get_uint (config,
                 GUM_CONFIG_GENERAL_SYS_UID_MIN, GUM_USER_INVALID_UID);
     else
-        *min = (uid_t) gum_config_get_uint (self->priv->config,
+        *min = (uid_t) gum_config_get_uint (config,
                 GUM_CONFIG_GENERAL_UID_MIN, GUM_USER_INVALID_UID);
 
-    if (self->priv->user_type == GUM_USERTYPE_SYSTEM)
-        *max = (uid_t) gum_config_get_uint (self->priv->config,
+    if (ut == GUM_USERTYPE_SYSTEM)
+        *max = (uid_t) gum_config_get_uint (config,
                 GUM_CONFIG_GENERAL_SYS_UID_MAX, GUM_USER_INVALID_UID);
     else
-        *max = (uid_t) gum_config_get_uint (self->priv->config,
+        *max = (uid_t) gum_config_get_uint (config,
                 GUM_CONFIG_GENERAL_UID_MAX, GUM_USER_INVALID_UID);
 
     return (*min < *max);
@@ -711,7 +750,8 @@ _find_free_uid (
 {
     uid_t tmp_uid, uid_min, uid_max;
 
-    if (!_get_default_uid_range (self, &uid_min, &uid_max))
+    if (!_get_default_uid_range (_get_usertype_from_gecos (self->priv->pw),
+            self->priv->config, &uid_min, &uid_max))
         return FALSE;
 
     /* Select the first available uid */
@@ -750,7 +790,7 @@ _set_uid (
     }
     _set_uid_property (self, uid);
 
-    if (self->priv->user_type != GUM_USERTYPE_SYSTEM)  {
+    if (_get_usertype_from_gecos (self->priv->pw) != GUM_USERTYPE_SYSTEM)  {
         gchar *dir = g_strdup_printf ("%s/%s",
                 gum_config_get_string (self->priv->config,
                         GUM_CONFIG_GENERAL_HOME_DIR_PREF),
@@ -762,27 +802,6 @@ _set_uid (
 }
 
 static gboolean
-_check_daemon_user_type (
-        GumdDaemonUser *self,
-        GError **error)
-{
-       switch (self->priv->user_type) {
-               case GUM_USERTYPE_ADMIN:
-               case GUM_USERTYPE_NORMAL:
-               case GUM_USERTYPE_GUEST:
-               case GUM_USERTYPE_SYSTEM:
-                       break;
-               case GUM_USERTYPE_NONE:
-               default:
-                       GUM_RETURN_WITH_ERROR (GUM_ERROR_USER_INVALID_USER_TYPE,
-                                       "Invalid user type", error, FALSE);
-                       break;
-       }
-
-    return TRUE;
-}
-
-static gboolean
 _set_secret (
         GumdDaemonUser *self,
         GError **error)
@@ -790,9 +809,10 @@ _set_secret (
     GUM_STR_FREE (self->priv->shadow->sp_pwdp);
 
     if (!self->priv->pw->pw_passwd) {
-        if (self->priv->user_type == GUM_USERTYPE_SYSTEM)
+        GumUserType ut = _get_usertype_from_gecos (self->priv->pw);
+        if (ut == GUM_USERTYPE_SYSTEM)
             self->priv->shadow->sp_pwdp = g_strdup ("*");
-        else if (self->priv->user_type == GUM_USERTYPE_GUEST)
+        else if (ut == GUM_USERTYPE_GUEST)
             self->priv->shadow->sp_pwdp = g_strdup ("");
         else
             self->priv->shadow->sp_pwdp = g_strdup ("!");
@@ -1090,8 +1110,8 @@ _set_group (
         GUM_RETURN_WITH_ERROR (GUM_ERROR_USER_GROUP_ADD_FAILURE,
                         "Group add failure", error, FALSE);
     }
-
-    GumGroupType grp_type = self->priv->user_type == GUM_USERTYPE_SYSTEM ?
+    GumUserType ut = _get_usertype_from_gecos (self->priv->pw);
+    GumGroupType grp_type = (ut == GUM_USERTYPE_SYSTEM) ?
             GUM_GROUPTYPE_SYSTEM : GUM_GROUPTYPE_USER;
 
     primary_gname = gum_config_get_string (self->priv->config,
@@ -1130,10 +1150,11 @@ _set_default_groups (
     gboolean added = TRUE;
     gchar **def_groupsv = NULL;
 
-    if (self->priv->user_type == GUM_USERTYPE_SYSTEM)
+    GumUserType ut = _get_usertype_from_gecos (self->priv->pw);
+    if (ut == GUM_USERTYPE_SYSTEM)
         return TRUE;
 
-    if (self->priv->user_type == GUM_USERTYPE_ADMIN)
+    if (ut == GUM_USERTYPE_ADMIN)
         def_groupsv = g_strsplit (gum_config_get_string (self->priv->config,
                 GUM_CONFIG_GENERAL_DEF_ADMIN_GROUPS), ",", -1);
     else
@@ -1169,11 +1190,11 @@ _create_home_dir (
         GumdDaemonUser *self,
         GError **error)
 {
-       if (self->priv->user_type == GUM_USERTYPE_SYSTEM) {
-               return TRUE;
-       }
+    if (_get_usertype_from_gecos (self->priv->pw) == GUM_USERTYPE_SYSTEM) {
+        return TRUE;
+    }
 
-       return gum_file_create_home_dir (self->priv->pw->pw_dir,
+    return gum_file_create_home_dir (self->priv->pw->pw_dir,
                self->priv->pw->pw_uid, self->priv->pw->pw_gid,
                gum_config_get_uint (self->priv->config,
                            GUM_CONFIG_GENERAL_UMASK, GUM_UMASK), error);
@@ -1184,11 +1205,11 @@ _delete_home_dir (
         GumdDaemonUser *self,
         GError **error)
 {
-       if (self->priv->user_type == GUM_USERTYPE_SYSTEM) {
-               return TRUE;
-       }
+    if (_get_usertype_from_gecos (self->priv->pw) == GUM_USERTYPE_SYSTEM) {
+        return TRUE;
+    }
 
-       return gum_file_delete_home_dir (self->priv->pw->pw_dir, error);
+    return gum_file_delete_home_dir (self->priv->pw->pw_dir, error);
 }
 
 gboolean
@@ -1265,22 +1286,27 @@ _copy_passwd_struct (
     _set_uid_property (dest, src->pw_uid);
     _set_gid_property (dest, src->pw_gid);
 
-    str = gum_string_utils_get_string (src->pw_gecos, ",", 0);
+    str = gum_string_utils_get_string (src->pw_gecos, ",",
+            GECOS_FIELD_REALNAME);
     _set_realname_property (dest, str);
     g_free (str);
 
-    str = gum_string_utils_get_string (src->pw_gecos, ",", 1);
+    str = gum_string_utils_get_string (src->pw_gecos, ",", GECOS_FIELD_OFFICE);
     _set_office_property (dest, str);
     g_free (str);
 
-    str = gum_string_utils_get_string (src->pw_gecos, ",", 2);
+    str = gum_string_utils_get_string (src->pw_gecos, ",",
+            GECOS_FIELD_OFFICEPHONE);
     _set_officephone_property (dest, str);
     g_free (str);
 
-    str = gum_string_utils_get_string (src->pw_gecos, ",", 3);
+    str = gum_string_utils_get_string (src->pw_gecos, ",",
+            GECOS_FIELD_HOMEPHONE);
     _set_homephone_property (dest, str);
     g_free (str);
 
+    _set_usertype_property (dest, _get_usertype_from_gecos (src));
+
     _set_homedir_property (dest, src->pw_dir);
     _set_shell_property (dest, src->pw_shell);
 
@@ -1406,29 +1432,6 @@ _finished:
     return retval;
 }
 
-
-static const gchar *
-_usertype_to_string (
-        GumUserType type)
-{
-    switch (type) {
-    case GUM_USERTYPE_SYSTEM:
-        return "system";
-    case GUM_USERTYPE_ADMIN:
-        return "admin";
-    case GUM_USERTYPE_GUEST:
-        return "guest";
-    case GUM_USERTYPE_NORMAL:
-        return "normal";
-    case GUM_USERTYPE_NONE:
-    default:
-        WARN ("undefined user type");
-        break;
-    }
-    return NULL;
-}
-
-
 GumdDaemonUser *
 gumd_daemon_user_new (
         GumConfig *config)
@@ -1505,8 +1508,9 @@ gumd_daemon_user_add (
      *** copy skel files and set permissions
      * unlock db
      */
-    if (!_check_daemon_user_type (self, error)) {
-        return FALSE;
+    if (_get_usertype_from_gecos (self->priv->pw) == GUM_USERTYPE_NONE) {
+        GUM_RETURN_WITH_ERROR (GUM_ERROR_USER_INVALID_USER_TYPE,
+                            "Invalid user type", error, FALSE);
     }
 
     if (!self->priv->pw->pw_shell) {
@@ -1559,12 +1563,12 @@ gumd_daemon_user_add (
         scrip_dir = env_val;
 #   endif
 
-
+    gchar *ut = gum_string_utils_get_string (self->priv->pw->pw_gecos, ",",
+                    GECOS_FIELD_USERTYPE);
     gum_utils_run_user_scripts (scrip_dir, self->priv->pw->pw_name,
             self->priv->pw->pw_uid, self->priv->pw->pw_gid,
-            self->priv->pw->pw_dir,
-            _usertype_to_string (self->priv->user_type));
-
+            self->priv->pw->pw_dir, ut);
+    g_free (ut);
     gum_lock_pwdf_unlock ();
     return TRUE;
 }
@@ -1683,6 +1687,43 @@ gumd_daemon_user_delete (
     return TRUE;
 }
 
+static void
+_update_gecos_field (
+        struct passwd *src,
+        GumdDaemonUser *dest,
+        GecosField field)
+{
+    gchar *str = NULL;
+    str = gum_string_utils_get_string (dest->priv->pw->pw_gecos, ",", field);
+    if (str && strlen(str) > 0) {
+        g_free(str);
+        return;
+    }
+    g_free(str);
+
+    str = gum_string_utils_get_string (src->pw_gecos, ",", field);
+    switch (field) {
+    case GECOS_FIELD_REALNAME:
+        _set_realname_property (dest, str);
+        break;
+    case GECOS_FIELD_OFFICE:
+        _set_office_property (dest, str);
+        break;
+    case GECOS_FIELD_OFFICEPHONE:
+        _set_officephone_property (dest, str);
+        break;
+    case GECOS_FIELD_HOMEPHONE:
+        _set_homephone_property (dest, str);
+        break;
+    case GECOS_FIELD_USERTYPE:
+        _set_usertype_property (dest, gum_user_type_from_string (str));
+        break;
+    default:
+        break;
+    }
+    g_free(str);
+}
+
 gboolean
 gumd_daemon_user_update (
         GumdDaemonUser *self,
@@ -1729,6 +1770,12 @@ gumd_daemon_user_update (
     _set_gid_property (self, pw->pw_gid);
     _set_homedir_property (self, pw->pw_dir);
 
+    _update_gecos_field (pw, self, GECOS_FIELD_REALNAME);
+    _update_gecos_field (pw, self, GECOS_FIELD_OFFICE);
+    _update_gecos_field (pw, self, GECOS_FIELD_OFFICEPHONE);
+    _update_gecos_field (pw, self, GECOS_FIELD_HOMEPHONE);
+    _update_gecos_field (pw, self, GECOS_FIELD_USERTYPE);
+
     if (self->priv->pw->pw_passwd &&
         g_strcmp0 (self->priv->pw->pw_passwd, "x") != 0 &&
         gum_crypt_cmp_secret (self->priv->pw->pw_passwd,
@@ -1745,8 +1792,22 @@ gumd_daemon_user_update (
 
     if (self->priv->pw->pw_gecos &&
         g_strcmp0 (pw->pw_gecos, self->priv->pw->pw_gecos) != 0) {
+        gchar *str1 = NULL, *str2 = NULL;
         DBG ("old gecos %s :: new gecos %s", pw->pw_gecos,
                 self->priv->pw->pw_gecos);
+        //usertype cannot change
+        str1 = gum_string_utils_get_string (self->priv->pw->pw_gecos, ",",
+                GECOS_FIELD_USERTYPE);
+        str2 = gum_string_utils_get_string (pw->pw_gecos, ",",
+                GECOS_FIELD_USERTYPE);
+        if (g_strcmp0 (str1, str2) != 0) {
+            gum_lock_pwdf_unlock ();
+            g_free (str1); g_free (str2);
+            GUM_RETURN_WITH_ERROR (GUM_ERROR_USER_INVALID_USER_TYPE,
+                            "User type cannot be updated", error, FALSE);
+        }
+        g_free (str1); g_free (str2);
+        //realname, office, officephone, homephone can change
         change++;
     }
 
@@ -1801,3 +1862,77 @@ gumd_daemon_user_get_uid_by_name (
     }
     return uid;
 }
+
+GVariant *
+gumd_daemon_user_get_user_list (
+        const gchar *const *types,
+        GumConfig *config,
+        GError **error)
+{
+    GVariantBuilder builder;
+    GVariant *users = NULL;
+    struct passwd *pent = NULL;
+    FILE *fp = NULL;
+    guint16 in_types = GUM_USERTYPE_NONE;
+    GumUserType ut;
+    uid_t sys_uid_min, sys_uid_max;
+    const gchar *fn = NULL;
+    DBG ("");
+
+    /* If user type is NULL or empty string, then return all users */
+    if (!types || g_strv_length ((gchar **)types) <= 0)
+        in_types = GUM_USERTYPE_SYSTEM | GUM_USERTYPE_ADMIN |
+        GUM_USERTYPE_GUEST | GUM_USERTYPE_NORMAL;
+    else
+        in_types = gum_user_type_from_strv (types);
+
+    if (in_types == GUM_USERTYPE_NONE) {
+        GUM_RETURN_WITH_ERROR (GUM_ERROR_USER_INVALID_USER_TYPE,
+                "Invalid user type specified", error, NULL);
+    }
+
+    DBG ("get user list in types %d", in_types);
+    if (!gum_lock_pwdf_lock ()) {
+        GUM_RETURN_WITH_ERROR (GUM_ERROR_DB_ALREADY_LOCKED,
+                "Database already locked", error, NULL);
+    }
+
+    fn = gum_config_get_string (config, GUM_CONFIG_GENERAL_PASSWD_FILE);
+    if (!fn || !(fp = fopen (fn, "r"))) {
+        gum_lock_pwdf_unlock ();
+        GUM_RETURN_WITH_ERROR (GUM_ERROR_FILE_OPEN,
+                "Opening passwd file failed", error, NULL);
+    }
+
+    sys_uid_min = (uid_t) gum_config_get_uint (config,
+            GUM_CONFIG_GENERAL_SYS_UID_MIN, GUM_USER_INVALID_UID);
+
+    sys_uid_max = (uid_t) gum_config_get_uint (config,
+            GUM_CONFIG_GENERAL_SYS_UID_MAX, GUM_USER_INVALID_UID);
+
+    g_variant_builder_init (&builder, (const GVariantType *)"au");
+    while ((pent = fgetpwent (fp)) != NULL) {
+        /* If type is an empty string, all users are fetched. User type is
+         * first compared with usertype in gecos field. If gecos field for
+         * usertype does not exist, then all the users are considered as
+         * normal users other than system users which are filtered out based
+         * on system min and max uids
+         * */
+        ut = _get_usertype_from_gecos (pent);
+        if (ut == GUM_USERTYPE_NONE) {
+            if (pent->pw_uid >=sys_uid_min && pent->pw_uid <= sys_uid_max)
+                ut = GUM_USERTYPE_SYSTEM;
+            else
+                ut = GUM_USERTYPE_NORMAL;
+        }
+        if (ut & in_types) {
+            g_variant_builder_add (&builder, "u", pent->pw_uid);
+        }
+        pent = NULL;
+    }
+    users = g_variant_builder_end (&builder);
+    fclose (fp);
+
+    gum_lock_pwdf_unlock ();
+    return users;
+}
index ae5523f..f280fa2 100644 (file)
@@ -101,6 +101,12 @@ gumd_daemon_user_get_uid_by_name (
         const gchar *username,
         GumConfig *config);
 
+GVariant *
+gumd_daemon_user_get_user_list (
+        const gchar *const *types,
+        GumConfig *config,
+        GError **error);
+
 G_END_DECLS
 
 #endif /* __GUMD_DAEMON_USER_H_ */
index d7b3df1..53a5470 100644 (file)
@@ -393,6 +393,20 @@ gumd_daemon_update_user (
     return TRUE;
 }
 
+GVariant *
+gumd_daemon_get_user_list (
+        GumdDaemon *self,
+        const gchar *const *types,
+        GError **error)
+{
+    if (!self || !GUMD_IS_DAEMON (self)) {
+        GUM_RETURN_WITH_ERROR (GUM_ERROR_INVALID_INPUT,
+                "Daemon object is not valid", error, NULL);
+    }
+
+    return gumd_daemon_user_get_user_list (types, self->priv->config, error);
+}
+
 guint
 gumd_daemon_get_user_timeout (
         GumdDaemon *self)
index 21d9472..a6519b2 100644 (file)
@@ -112,6 +112,12 @@ gumd_daemon_update_user (
         GumdDaemonUser *user,
         GError **error);
 
+GVariant *
+gumd_daemon_get_user_list (
+        GumdDaemon *self,
+        const gchar *const *types,
+        GError **error);
+
 guint
 gumd_daemon_get_user_timeout (
         GumdDaemon *self) G_GNUC_CONST;
index 55bb861..49e0758 100644 (file)
@@ -83,12 +83,12 @@ _close_server (
 }
 
 static void
-_on_bus_acquired (
+_on_name_acquired (
         GDBusConnection *connection,
         const gchar *name,
         gpointer user_data)
 {
-    INFO ("Bus aquired on connection '%p'", connection);
+    INFO ("Name acquired %s on connection '%p'", name, connection);
 }
 
 static void
@@ -136,12 +136,12 @@ _on_group_interface_dispose (
 }
 
 static void
-_on_name_acquired (
+_on_bus_acquired (
         GDBusConnection *connection,
         const gchar *name,
         gpointer user_data)
 {
-    INFO ("Acquired the name %s on connection '%p'", name, connection);
+    INFO ("Bus acquired the name %s on connection '%p'", name, connection);
     GumdDbusServerMsgBus *server = GUMD_DBUS_SERVER_MSG_BUS (user_data);
 
     DBG("Export user service interface");
index 6cd37b9..08708d9 100644 (file)
@@ -90,6 +90,13 @@ _handle_get_user_by_name (
         const gchar *username,
         gpointer user_data);
 
+static gboolean
+_handle_get_user_list (
+        GumdDbusUserServiceAdapter *self,
+        GDBusMethodInvocation *invocation,
+        const gchar *const *types,
+        gpointer user_data);
+
 static void
 _on_dbus_user_adapter_disposed (
         gpointer data,
@@ -272,7 +279,6 @@ _dispose (
 
     G_OBJECT_CLASS (gumd_dbus_user_service_adapter_parent_class)->dispose (
             object);
-    DBG ("user service adapter (%p) dispose end", object);
 }
 
 static void
@@ -280,14 +286,12 @@ _finalize (
         GObject *object)
 {
     GumdDbusUserServiceAdapter *self = GUMD_DBUS_USER_SERVICE_ADAPTER (object);
-    DBG ("user service adapter (%p) finalise beg", object);
 
     if (self->priv->peer_users) {
         g_list_free (self->priv->peer_users);
         self->priv->peer_users = NULL;
     }
 
-    DBG ("user service adapter (%p) finalize end", object);
     G_OBJECT_CLASS (gumd_dbus_user_service_adapter_parent_class)->finalize (
             object);
 }
@@ -654,6 +658,39 @@ _handle_get_user_by_name (
     return TRUE;
 }
 
+static gboolean
+_handle_get_user_list (
+        GumdDbusUserServiceAdapter *self,
+        GDBusMethodInvocation *invocation,
+        const gchar *const *types,
+        gpointer user_data)
+{
+    GError *error = NULL;
+    GVariant *users = NULL;
+
+    DBG ("");
+
+    gum_disposable_set_auto_dispose (GUM_DISPOSABLE (self), FALSE);
+
+    users = gumd_daemon_get_user_list (self->priv->daemon, types, &error);
+
+    if (users) {
+        gum_dbus_user_service_complete_get_user_list (
+                self->priv->dbus_user_service, invocation, users);
+    } else {
+        if (!error) {
+            error = GUM_GET_ERROR_FOR_ID (GUM_ERROR_USER_NOT_FOUND,
+                    "Users Not Found");
+        }
+        g_dbus_method_invocation_return_gerror (invocation, error);
+        g_error_free (error);
+    }
+
+    gum_disposable_set_auto_dispose (GUM_DISPOSABLE (self), TRUE);
+
+    return TRUE;
+}
+
 GumdDbusUserServiceAdapter *
 gumd_dbus_user_service_adapter_new_with_connection (
         GDBusConnection *bus_connection,
@@ -693,6 +730,9 @@ gumd_dbus_user_service_adapter_new_with_connection (
     g_signal_connect_swapped (adapter->priv->dbus_user_service,
         "handle-get-user-by-name", G_CALLBACK(_handle_get_user_by_name),
         adapter);
+    g_signal_connect_swapped (adapter->priv->dbus_user_service,
+        "handle-get-user-list", G_CALLBACK(_handle_get_user_list),
+        adapter);
 
     g_signal_connect (G_OBJECT (adapter->priv->daemon), "user-added",
             G_CALLBACK (_on_user_added), adapter);
index 0e5bca8..e4804a7 100644 (file)
@@ -23,12 +23,12 @@ gum_pubhdr = $(top_srcdir)/include/gum
 libgum_includedir = $(includedir)/gum
 libgum_include_HEADERS = \
     $(gum_pubhdr)/gum-user.h \
+    $(gum_pubhdr)/gum-user-service.h \
     $(gum_pubhdr)/gum-group.h \
     $(NULL)
     
 libgum_la_SOURCES = \
     gum-internals.h \
-    gum-user-service.h \
     gum-user-service.c \
     gum-user.c \
     gum-group-service.h \
index af14a55..1a168f7 100644 (file)
@@ -424,12 +424,12 @@ gum_pubhdr = $(top_srcdir)/include/gum
 libgum_includedir = $(includedir)/gum
 libgum_include_HEADERS = \
     $(gum_pubhdr)/gum-user.h \
+    $(gum_pubhdr)/gum-user-service.h \
     $(gum_pubhdr)/gum-group.h \
     $(NULL)
 
 libgum_la_SOURCES = \
     gum-internals.h \
-    gum-user-service.h \
     gum-user-service.c \
     gum-user.c \
     gum-group-service.h \
index 299ff83..a747862 100644 (file)
@@ -44,6 +44,7 @@ static void
 _thread_service_free (
         GWeakRef *data)
 {
+    g_weak_ref_clear (data);
     g_slice_free (GWeakRef, data);
 }
 
@@ -94,10 +95,12 @@ _on_group_service_destroyed (
         GObject *obj)
 {
     g_mutex_lock (&mutex);
-    if (group_service_objects)
-    {
-        g_hash_table_unref (group_service_objects);
-        group_service_objects = NULL;
+    if (group_service_objects) {
+        g_hash_table_remove (group_service_objects, g_thread_self ());
+        if (g_hash_table_size (group_service_objects) <= 0) {
+            g_hash_table_unref (group_service_objects);
+            group_service_objects = NULL;
+        }
     }
     g_mutex_unlock (&mutex);
 }
index baa5877..09fde3b 100644 (file)
@@ -3,7 +3,7 @@
 /*
  * This file is part of gum
  *
- * Copyright (C) 2013 - 2014 Intel Corporation.
+ * Copyright (C) 2013 - 2015 Intel Corporation.
  *
  * Contact: Imran Zaman <imran.zaman@intel.com>
  *
 
 #include "config.h"
 
+#include "common/dbus/gum-dbus-user-service-gen.h"
 #include "common/gum-dbus.h"
 #include "common/gum-error.h"
 #include "common/gum-log.h"
+#include "common/gum-defines.h"
 
+#include "daemon/core/gumd-daemon.h"
+#include "gum-user.h"
 #include "gum-user-service.h"
+#include "gum-internals.h"
+
+/**
+ * SECTION:gum-user-service
+ * @short_description: provides interface for managing user's service
+ * @include: gum/gum-user-service.h
+ *
+ * #GumUserService provides interface for retrieving user list based on the
+ * types of the users. Only privileged user can access the interface when
+ * system-bus is used for communication with the user management daemon.
+ * NOTE: #GumUserService object is a singleton object.
+ *
+ * Following code snippet demonstrates how to create a new remote user
+ * service object:
+ *
+ * |[
+ *  GumUserService *user_service = NULL;
+ *
+ *  user_service = gum_user_service_create_sync (FALSE);
+ *
+ *  // use the object
+ *
+ *  // destroy the object
+ *  g_object_unref (user_service);
+ * ]|
+ *
+ * Similarly, user list can be retrieved as:
+ * |[
+ *  GumUserService *user_service = NULL;
+ *  gchar *users = NULL;
+ *
+ *  user_service = gum_user_service_create_sync (FALSE);
+ *
+ *  // fetch user list
+ *  users = gum_user_service_get_user_list_sync (user_service, "normal,guest",
+ *  NULL, FALSE);
+ *
+ *  // destroy the object
+ *  g_object_unref (user_service);
+ * ]|
+ *
+ * For more details, see example implementation here:
+ *<ulink url="https://github.com/01org/gumd/blob/master/src/utils/gum-utils.c">
+ *          gum-utils</ulink>
+ */
+
+/**
+ * GumUserList:
+ *
+ * Data structure for the list of users (tyepdef'd #GList).
+ */
+
+/**
+ * GumUserServiceCb:
+ * @service: (transfer none): #GumUserService object which is used in the
+ * request
+ * @error: (transfer none): #GError object. In case of error, error will be
+ * non-NULL
+ * @user_data: user data passed onto the request
+ *
+ * #GumUserServiceCb defines the callback which is used when the service object
+ * is created e.g..
+ */
+
+/**
+ * GumUserServiceListCb:
+ * @service: (transfer none): #GumUserService object which is used in the
+ * request
+ * @users: (transfer full): #GumUserList list of #GumUser objects. Use
+ * gum_user_list_free to free the list of the users
+ * @error: (transfer none): #GError object. In case of error, error will be
+ * non-NULL
+ * @user_data: user data passed onto the request
+ *
+ * #GumUserServiceListCb defines the callback which is used when list of users
+ * are to be retrieved based on the user types.
+ */
+
+/**
+ * GumUserService:
+ *
+ * Opaque structure for the object.
+ */
+
+/**
+ * GumUserServiceClass:
+ * @parent_class: parent class object
+ *
+ * Opaque structure for the class.
+ */
+
+G_DEFINE_TYPE (GumUserService, gum_user_service, G_TYPE_OBJECT)
+
+#define GUM_USER_SERVICE_PRIV(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+        GUM_TYPE_USER_SERVICE, GumUserServicePrivate)
+
+typedef struct {
+    gpointer callback;
+    gpointer user_data;
+    GError *error;
+    GumUserList *users;
+    guint cb_id;
+} GumUserServiceOp;
+
+struct _GumUserServicePrivate
+{
+    GumDbusUserService *dbus_service;
+    GumdDaemon *offline_service;
+    GCancellable *cancellable;
+    GumUserServiceOp *op;
+    guint dbus_proxy_cb_id;
+};
+
+enum
+{
+    PROP_0,
+
+    PROP_OFFLINE,
+
+    N_PROPERTIES
+};
+
+static GParamSpec *properties[N_PROPERTIES];
 
 static const gchar *_bus_type =
 #ifdef GUM_BUS_TYPE_P2P
@@ -37,26 +164,27 @@ static const gchar *_bus_type =
 #else
     "system";
 #endif
-static GHashTable *user_service_objects = NULL;
+static GObject *self = 0;
+static GHashTable *dbus_service_objects = NULL;
 static GMutex mutex;
 
 static void
-_thread_service_free (
+_thread_dbus_service_free (
         GWeakRef *data)
 {
+    g_weak_ref_clear (data);
     g_slice_free (GWeakRef, data);
 }
 
 static GumDbusUserService *
-_get_service_singleton ()
+_get_dbus_service ()
 {
     GumDbusUserService *object = NULL;
-
     g_mutex_lock (&mutex);
 
-    if (user_service_objects != NULL) {
+    if (dbus_service_objects != NULL) {
         GWeakRef *ref;
-        ref = g_hash_table_lookup (user_service_objects, g_thread_self ());
+        ref = g_hash_table_lookup (dbus_service_objects, g_thread_self ());
         if (ref != NULL) {
             object = g_weak_ref_get (ref);
         }
@@ -67,53 +195,125 @@ _get_service_singleton ()
 }
 
 static void
-_set_service_singleton (
+_insert_dbus_service (
         GumDbusUserService *object)
 {
     g_return_if_fail (GUM_DBUS_IS_USER_SERVICE (object));
 
     g_mutex_lock (&mutex);
 
-    if (!user_service_objects) {
-        user_service_objects = g_hash_table_new_full (g_direct_hash,
-                g_direct_equal, NULL, (GDestroyNotify)_thread_service_free);
+    if (!dbus_service_objects) {
+        dbus_service_objects = g_hash_table_new_full (g_direct_hash,
+                g_direct_equal, NULL,
+                (GDestroyNotify)_thread_dbus_service_free);
     }
 
     if (object != NULL) {
         GWeakRef *ref = g_slice_new (GWeakRef);
         g_weak_ref_init (ref, object);
-        g_hash_table_insert (user_service_objects, g_thread_self (), ref);
+        g_hash_table_insert (dbus_service_objects, g_thread_self (), ref);
     }
 
     g_mutex_unlock (&mutex);
 }
 
 static void
-_on_user_service_destroyed (
+_on_dbus_service_destroyed (
         gpointer data,
         GObject *obj)
 {
     g_mutex_lock (&mutex);
-    if (user_service_objects)
-    {
-        g_hash_table_unref (user_service_objects);
-        user_service_objects = NULL;
+    if (dbus_service_objects) {
+        g_hash_table_remove (dbus_service_objects, g_thread_self ());
+        if (g_hash_table_size (dbus_service_objects) <= 0) {
+            g_hash_table_unref (dbus_service_objects);
+            dbus_service_objects = NULL;
+        }
     }
     g_mutex_unlock (&mutex);
 }
 
-GumDbusUserService *
-gum_user_service_get_instance ()
+static void
+_free_op (
+        GumUserService *self)
+{
+    if (self &&
+        self->priv->op) {
+        if (self->priv->op->cb_id > 0) {
+            g_source_remove (self->priv->op->cb_id);
+            self->priv->op->cb_id = 0;
+        }
+        if (self->priv->op->error) g_error_free (self->priv->op->error);
+        gum_user_service_list_free (self->priv->op->users);
+        g_free (self->priv->op);
+        self->priv->op = NULL;
+    }
+}
+
+static void
+_create_op (
+        GumUserService *self,
+        gpointer callback,
+        gpointer user_data)
 {
-    const gchar *env;
-    GumDbusUserService *user_service = NULL;
+    GumUserServiceOp *op = g_malloc0 (sizeof (GumUserServiceOp));
+    op->callback = callback;
+    op->user_data = user_data;
+    _free_op (self);
+    self->priv->op = op;
+}
+
+static gboolean
+_trigger_callback (
+        gpointer user_data)
+{
+    g_return_val_if_fail (user_data && GUM_IS_USER_SERVICE (user_data), FALSE);
+
+    GumUserService *user_service = GUM_USER_SERVICE (user_data);
+    if (user_service->priv->op) {
+        if (user_service->priv->op->callback) {
+            ((GumUserServiceCb)user_service->priv->op->callback) (user_service,
+                user_service->priv->op->error,
+                user_service->priv->op->user_data);
+        }
+        user_service->priv->op->cb_id = 0;
+    }
+    return FALSE;
+}
+
+static void
+_setup_idle_callback (
+        GumUserService *self,
+        const GError *error)
+{
+    if (!self->priv->op || !self->priv->op->callback) return;
+    if (error) {
+        if (self->priv->op->error) g_clear_error (&self->priv->op->error);
+        self->priv->op->error = g_error_copy (error);
+    }
+    self->priv->op->cb_id = g_idle_add (_trigger_callback, self);
+}
+
+static gboolean
+_service_dbus_proxy_callback (
+        gpointer user_data)
+{
+    g_return_if_fail (user_data && GUM_IS_USER_SERVICE (user_data));
+    const gchar *env = NULL;
+    GumDbusUserService *dbus_service = NULL;
     GDBusConnection *connection = NULL;
     GError *error = NULL;
     const gchar *bus_name = NULL;
 
-    user_service = _get_service_singleton ();
-    if (user_service) {
-        return user_service;
+    GumUserService *self = GUM_USER_SERVICE (user_data);
+    self->priv->dbus_proxy_cb_id = 0;
+
+    if (!self->priv->dbus_service)
+        self->priv->dbus_service = _get_dbus_service ();
+
+    if (self->priv->dbus_service) {
+        _setup_idle_callback (self, NULL);
+        return FALSE;
     }
 
     env = getenv ("GUM_BUS_TYPE");
@@ -130,19 +330,429 @@ gum_user_service_get_instance ()
         bus_name = GUM_SERVICE;
     }
 
-    user_service = gum_dbus_user_service_proxy_new_sync (connection,
+    dbus_service = gum_dbus_user_service_proxy_new_sync (connection,
             G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, bus_name,
             GUM_USER_SERVICE_OBJECTPATH, NULL, &error);
-
     if (G_LIKELY (error == NULL)) {
-        g_object_weak_ref (G_OBJECT (user_service), _on_user_service_destroyed,
-                user_service);
-        _set_service_singleton (user_service);
+        g_object_weak_ref (G_OBJECT (dbus_service), _on_dbus_service_destroyed,
+                dbus_service);
+        _insert_dbus_service (dbus_service);
         gum_error_quark ();
+        self->priv->dbus_service = dbus_service;
+        _setup_idle_callback (self, NULL);
     } else {
         WARN ("Unable to start user service: %s", error->message);
+        _setup_idle_callback (self, error);
         g_clear_error (&error);
     }
+    return FALSE;
+}
+
+static gboolean
+_trigger_user_list_callback (
+        gpointer user_data)
+{
+    g_return_val_if_fail (user_data && GUM_IS_USER_SERVICE (user_data), FALSE);
+
+    GumUserService *self = GUM_USER_SERVICE (user_data);
+    if (self->priv->op) {
+        if (self->priv->op->callback) {
+            ((GumUserServiceListCb)self->priv->op->callback) (self,
+                    self->priv->op->users, self->priv->op->error,
+                    self->priv->op->user_data);
+            self->priv->op->users = NULL;
+        }
+        self->priv->op->cb_id = 0;
+    }
+    return FALSE;
+}
+
+static void
+_setup_idle_user_list_callback (
+        GumUserService *self,
+        GumUserList *users,
+        const GError *error)
+{
+    if (!self->priv->op || !self->priv->op->callback) return;
+    if (error) {
+        if (self->priv->op->error) g_clear_error (&self->priv->op->error);
+        self->priv->op->error = g_error_copy (error);
+    }
+    self->priv->op->users = users;
+    self->priv->op->cb_id = g_idle_add (_trigger_user_list_callback, self);
+}
+
+static void
+_setup_idle_dbus_proxy_callback (
+        GumUserService *self)
+{
+    if (self->priv->dbus_proxy_cb_id > 0)
+        return;
+    self->priv->dbus_proxy_cb_id = g_idle_add (
+            _service_dbus_proxy_callback, self);
+}
+
+static void
+_gum_user_service_list_free (
+        gpointer ptr)
+{
+    GumUserService *self = (GumUserService *) ptr;
+    GUM_OBJECT_UNREF (self);
+}
+
+static GumUserList *
+_uids_variant_to_user_list(
+        GVariant *uids,
+        gboolean offline)
+{
+    GumUserList *users = NULL;
+    if (uids) {
+        GumUser *user = NULL;
+        GVariantIter iter;
+        GVariant *value;
+        uid_t uid;
 
-    return user_service;
+        g_variant_iter_init (&iter, uids);
+        while ((value = g_variant_iter_next_value (&iter))) {
+            uid = g_variant_get_uint32 (value);
+            if (uid != GUM_USER_INVALID_UID) {
+                user = gum_user_get_sync (uid, offline);
+                if (user)
+                    users = g_list_append (users, user);
+                else
+                    WARN ("unable to get user for uid %d", uid);
+            }
+            g_variant_unref (value);
+        }
+    }
+    return users;
 }
+
+static void
+_on_get_user_list_cb (
+        GObject *object,
+        GAsyncResult *res,
+        gpointer user_data)
+{
+    GumUserService *self = (GumUserService*)user_data;
+    GumDbusUserService *proxy = GUM_DBUS_USER_SERVICE (object);
+    GVariant *uids = NULL;
+    GError *error = NULL;
+    GumUserList *users = NULL;
+
+    g_return_if_fail (self != NULL);
+
+    DBG ("");
+
+    gum_dbus_user_service_call_get_user_list_finish (proxy, &uids,
+            res, &error);
+
+    if (GUM_OPERATION_IS_NOT_CANCELLED (error)) {
+        if (!error) {
+            users = _uids_variant_to_user_list (uids, FALSE);
+        }
+        _setup_idle_user_list_callback (self, users, error);
+    }
+    g_variant_unref (uids);
+    g_clear_error (&error);
+}
+
+static GObject*
+_constructor (GType type,
+              guint n_construct_params,
+              GObjectConstructParam *construct_params)
+{
+    /*
+     * Singleton object
+     */
+    if (!self) {
+        self = G_OBJECT_CLASS (gum_user_service_parent_class)->constructor (
+                  type, n_construct_params, construct_params);
+    }
+    else {
+        g_object_ref (self);
+    }
+
+    return self;
+}
+
+static void
+_set_property (
+        GObject *object,
+        guint property_id,
+        const GValue *value,
+        GParamSpec *pspec)
+{
+    GumUserService *self = GUM_USER_SERVICE (object);
+    switch (property_id) {
+        case PROP_OFFLINE: {
+            if (g_value_get_boolean (value)) {
+                self->priv->offline_service = gumd_daemon_new ();
+            } else {
+                self->priv->cancellable = g_cancellable_new ();
+            }
+            break;
+        }
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    }
+}
+
+static void
+_get_property (
+        GObject *object,
+        guint property_id,
+        GValue *value,
+        GParamSpec *pspec)
+{
+    GumUserService *self = GUM_USER_SERVICE (object);
+    switch (property_id) {
+        case PROP_OFFLINE: {
+            g_value_set_boolean (value, self->priv->offline_service != NULL);
+            break;
+        }
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    }
+}
+
+static void
+_dispose (GObject *object)
+{
+    GumUserService *self = GUM_USER_SERVICE(object);
+    if (self->priv->dbus_proxy_cb_id > 0) {
+        g_source_remove (self->priv->dbus_proxy_cb_id);
+        self->priv->dbus_proxy_cb_id = 0;
+    }
+
+    _free_op (self);
+
+    if (self->priv->cancellable) {
+        g_cancellable_cancel (self->priv->cancellable);
+        g_object_unref (self->priv->cancellable);
+        self->priv->cancellable = NULL;
+    }
+
+    GUM_OBJECT_UNREF (self->priv->dbus_service);
+
+    GUM_OBJECT_UNREF (self->priv->offline_service);
+
+    G_OBJECT_CLASS (gum_user_service_parent_class)->dispose (object);
+}
+
+static void
+_finalize (GObject *object)
+{
+    G_OBJECT_CLASS (gum_user_service_parent_class)->finalize (object);
+    self = NULL;
+}
+
+static void
+gum_user_service_init (
+        GumUserService *self)
+{
+    self->priv = GUM_USER_SERVICE_PRIV (self);
+    self->priv->cancellable = NULL;
+    self->priv->dbus_service = NULL;
+    self->priv->offline_service = NULL;
+    self->priv->op = NULL;
+    self->priv->dbus_proxy_cb_id = 0;
+}
+
+static void
+gum_user_service_class_init (
+        GumUserServiceClass *klass)
+{
+    GObjectClass* object_class = G_OBJECT_CLASS (klass);
+
+    g_type_class_add_private (object_class, sizeof (GumUserServicePrivate));
+
+    object_class->constructor = _constructor;
+    object_class->get_property = _get_property;
+    object_class->set_property = _set_property;
+    object_class->dispose = _dispose;
+    object_class->finalize = _finalize;
+
+    /**
+     * GumUserService:offline:
+     *
+     * This property is used to define the behaviour of synchronous operation
+     * performed on the object. If it is set to TRUE, then the object performs
+     * the operation without daemon (dbus/gumd) otherwise 'gumd' daemon will be
+     * used for the required synchronous functionality.
+     */
+    properties[PROP_OFFLINE] =  g_param_spec_boolean ("offline",
+            "Offline",
+            "Operational mode for the User object",
+            FALSE,
+            G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+
+    g_object_class_install_properties (object_class, N_PROPERTIES,
+            properties);
+}
+
+/**
+ * gum_user_service_create:
+ * @callback: #GumUserServiceCb to be invoked when new object is created
+ * @user_data: user data
+ *
+ * This method creates a new user object over the DBus asynchronously.
+ * Callback is used to notify when the remote object is fully created and
+ * accessible.
+ *
+ * NOTE: #GumUserService is a singleton object. If the object is already
+ * created earlier, same object will be returned in the callback.
+ *
+ * Returns: (transfer full): #GumUserService newly created object if
+ * successful, NULL otherwise.
+ */
+GumUserService *
+gum_user_service_create (
+        GumUserServiceCb callback,
+        gpointer user_data)
+{
+    GumUserService *self = GUM_USER_SERVICE (
+            g_object_new (GUM_TYPE_USER_SERVICE, "offline", FALSE, NULL));
+
+    g_return_val_if_fail (self != NULL, NULL);
+    _create_op (self, callback, user_data);
+    _setup_idle_dbus_proxy_callback (self);
+    return self;
+}
+
+/**
+ * gum_user_service_create_sync:
+ * @offline: enables or disables the offline mode
+ *
+ * This method creates a new user service object. In case offline mode is
+ * enabled, then the object is created directly without using dbus otherwise
+ * the objects gets created over the DBus synchronously.
+ * NOTE: #GumUserService is a singleton object.
+ *
+ * Returns: (transfer full): #GumUserService newly created object
+ */
+GumUserService *
+gum_user_service_create_sync (
+        gboolean offline)
+{
+    GumUserService *self = GUM_USER_SERVICE (g_object_new (
+            GUM_TYPE_USER_SERVICE, "offline", offline, NULL));
+    _service_dbus_proxy_callback (self);
+    return self;
+}
+
+/**
+ * gum_user_service_get_user_list:
+ * @self: #GumUserService object
+ * @types: (transfer none): a string array of user types (e.g admin, normal etc)
+ * @callback: #GumUserServiceListCb to be invoked when user list is retrieved
+ * @user_data: user data
+ *
+ * This method gets the user over the DBus asynchronously. Callback is used
+ * to notify when the user list is retrieved.
+ *
+ * Returns: returns TRUE if the request has been pushed and is waiting for
+ * the response, FALSE otherwise. No callback is triggered, in case the
+ * function returns FALSE.
+ */
+gboolean
+gum_user_service_get_user_list (
+        GumUserService *self,
+        const gchar *const *types,
+        GumUserServiceListCb callback,
+        gpointer user_data)
+{
+    DBG ("");
+    g_return_val_if_fail (GUM_IS_USER_SERVICE (self), FALSE);
+
+    if (!self->priv->dbus_service) {
+        WARN ("Remote dbus object not valid");
+        return FALSE;
+    }
+    _create_op (self, (gpointer)callback, user_data);
+    gum_dbus_user_service_call_get_user_list (self->priv->dbus_service,
+            types, self->priv->cancellable, _on_get_user_list_cb, self);
+
+    return TRUE;
+}
+
+/**
+ * gum_user_service_get_user_list_sync:
+ * @self: #GumUserService object
+ * @types: (transfer none): a string array of user types (e.g admin, normal etc)
+ *
+ * This method gets the list of users based on the type. In case offline mode is
+ * enabled, then the users is retrieved directly without using dbus otherwise
+ * the users gets retrieved over the DBus synchronously.
+ *
+ * Returns: (transfer full): #GumUserList of #GumUser. use
+ * gum_user_list_free to free the list of the users.
+ */
+GumUserList *
+gum_user_service_get_user_list_sync (
+        GumUserService *self,
+        const gchar *const *types)
+{
+    GError *error = NULL;
+    gboolean rval = FALSE;
+    GumUserList *users = NULL;
+    GVariant *uids = NULL;
+
+    DBG ("");
+    g_return_val_if_fail (GUM_IS_USER_SERVICE (self), NULL);
+
+    if (self->priv->offline_service) {
+        uids = gumd_daemon_get_user_list (self->priv->offline_service,
+                types, &error);
+        if (uids) {
+            users = _uids_variant_to_user_list (uids, TRUE);
+            g_variant_unref (uids);
+        }
+    } else if (self->priv->dbus_service) {
+        rval = gum_dbus_user_service_call_get_user_list_sync (
+                self->priv->dbus_service, types, &uids, NULL, &error);
+        if (!rval && error) {
+            WARN ("Failed with error %d:%s", error->code, error->message);
+            g_error_free (error);
+            error = NULL;
+        } else {
+            users = _uids_variant_to_user_list (uids, FALSE);
+            g_variant_unref (uids);
+        }
+    }
+    return users;
+}
+
+/**
+ * gum_user_service_list_free:
+ * @users: #GList of #GumUser
+ *
+ * Frees the list and its elements completely.
+ *
+ */
+void
+gum_user_service_list_free (
+        GumUserList *users)
+{
+    if (users)
+        g_list_free_full (users, _gum_user_service_list_free);
+}
+
+/**
+ * gum_user_service_get_dbus_proxy:
+ * @self: #GumUserService object
+ *
+ * Gets the dbus proxy of the singleton #GumUserService object.
+ *
+ * Returns: (transfer none): #GDBusProxy object.
+ */
+GDBusProxy *
+gum_user_service_get_dbus_proxy (
+        GumUserService *self)
+{
+    g_return_val_if_fail (GUM_IS_USER_SERVICE (self) &&
+            self->priv->dbus_service, NULL);
+    return G_DBUS_PROXY (self->priv->dbus_service);
+
+}
+
diff --git a/src/lib/gum-user-service.h b/src/lib/gum-user-service.h
deleted file mode 100644 (file)
index ba6f0a7..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* vi: set et sw=4 ts=4 cino=t0,(0: */
-/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of gum
- *
- * Copyright (C) 2013 Intel Corporation.
- *
- * Contact: Imran Zaman <imran.zaman@intel.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-
-#ifndef __GUM_USER_SERVICE_H_
-#define __GUM_USER_SERVICE_H_
-
-#include <glib.h>
-#include "common/dbus/gum-dbus-user-service-gen.h"
-
-G_BEGIN_DECLS
-
-GumDbusUserService *
-gum_user_service_get_instance ();
-
-G_END_DECLS
-
-#endif /* __GUM_USER_SERVICE_H_ */
index 876902a..ccb88b1 100644 (file)
@@ -3,7 +3,7 @@
 /*
  * This file is part of gum
  *
- * Copyright (C) 2013 Intel Corporation.
+ * Copyright (C) 2013 - 2015 Intel Corporation.
  *
  * Contact: Imran Zaman <imran.zaman@intel.com>
  *
@@ -115,9 +115,9 @@ typedef struct {
 
 struct _GumUserPrivate
 {
-    GumDbusUserService *dbus_service;
-    GumDbusUser *dbus_user;
+    GumUserService *dbus_service;
     GumdDaemon *offline_service;
+    GumDbusUser *dbus_user;
     GumdDaemonUser *offline_user;
     GCancellable *cancellable;
     GumUserOp *op;
@@ -150,13 +150,16 @@ enum
 
 static GParamSpec *properties[N_PROPERTIES];
 
-
 static void
 _free_op (
         GumUser *self)
 {
     if (self &&
         self->priv->op) {
+        if (self->priv->op->cb_id > 0) {
+            g_source_remove (self->priv->op->cb_id);
+            self->priv->op->cb_id = 0;
+        }
         if (self->priv->op->error) g_error_free (self->priv->op->error);
         g_free (self->priv->op);
         self->priv->op = NULL;
@@ -216,7 +219,6 @@ _on_user_remote_object_destroyed(
 
     GUM_OBJECT_UNREF (self->priv->dbus_user);
 }
-
 static void
 _set_property (
         GObject *object,
@@ -231,7 +233,7 @@ _set_property (
                 self->priv->offline_service = gumd_daemon_new ();
             } else {
                 self->priv->cancellable = g_cancellable_new ();
-                self->priv->dbus_service = gum_user_service_get_instance ();
+                self->priv->dbus_service = gum_user_service_create_sync (FALSE);
             }
             break;
         }
@@ -276,12 +278,7 @@ static void
 _dispose (GObject *object)
 {
     GumUser *self = GUM_USER (object);
-
-    if (self->priv->op &&
-        self->priv->op->cb_id > 0) {
-        g_source_remove (self->priv->op->cb_id);
-        self->priv->op->cb_id = 0;
-    }
+    _free_op (self);
 
     if (self->priv->cancellable) {
         g_cancellable_cancel (self->priv->cancellable);
@@ -295,11 +292,8 @@ _dispose (GObject *object)
     }
 
     GUM_OBJECT_UNREF (self->priv->dbus_user);
-
     GUM_OBJECT_UNREF (self->priv->dbus_service);
-
     GUM_OBJECT_UNREF (self->priv->offline_user);
-
     GUM_OBJECT_UNREF (self->priv->offline_service);
 
     G_OBJECT_CLASS (gum_user_parent_class)->dispose (object);
@@ -308,10 +302,6 @@ _dispose (GObject *object)
 static void
 _finalize (GObject *object)
 {
-    GumUser *self = GUM_USER (object);
-
-    _free_op (self);
-
     G_OBJECT_CLASS (gum_user_parent_class)->finalize (object);
 }
 
@@ -541,12 +531,12 @@ _create_dbus_user (
         gchar *object_path,
         GError *error)
 {
+    GDBusProxy *serv_dbus_proxy = gum_user_service_get_dbus_proxy (
+            user->priv->dbus_service);
     user->priv->dbus_user = gum_dbus_user_proxy_new_sync (
-            g_dbus_proxy_get_connection (G_DBUS_PROXY (
-                    user->priv->dbus_service)),
-            G_DBUS_PROXY_FLAGS_NONE, g_dbus_proxy_get_name (
-            G_DBUS_PROXY (user->priv->dbus_service)), object_path,
-            user->priv->cancellable, &error);
+            g_dbus_proxy_get_connection (serv_dbus_proxy),
+            G_DBUS_PROXY_FLAGS_NONE, g_dbus_proxy_get_name (serv_dbus_proxy),
+            object_path, user->priv->cancellable, &error);
     if (!error) {
         g_signal_connect (G_OBJECT (user->priv->dbus_user), "unregistered",
             G_CALLBACK (_on_user_remote_object_destroyed),  user);
@@ -583,10 +573,11 @@ _sync_properties (
     GVariant *result = NULL;
 
     /* load all properties synchronously */
+    GDBusProxy *serv_dbus_proxy = gum_user_service_get_dbus_proxy (
+                user->priv->dbus_service);
     result = g_dbus_connection_call_sync (
-            g_dbus_proxy_get_connection (
-                    G_DBUS_PROXY (user->priv->dbus_service)),
-            g_dbus_proxy_get_name (G_DBUS_PROXY (user->priv->dbus_service)),
+            g_dbus_proxy_get_connection (serv_dbus_proxy),
+            g_dbus_proxy_get_name (serv_dbus_proxy),
             g_dbus_proxy_get_object_path (G_DBUS_PROXY (user->priv->dbus_user)),
             "org.freedesktop.DBus.Properties",
             "GetAll",
@@ -797,7 +788,9 @@ gum_user_create (
 
     g_return_val_if_fail (user && user->priv->dbus_service != NULL, NULL);
     _create_op (user, callback, user_data);
-    gum_dbus_user_service_call_create_new_user (user->priv->dbus_service,
+    gum_dbus_user_service_call_create_new_user (
+            (GumDbusUserService*) gum_user_service_get_dbus_proxy (
+                    user->priv->dbus_service),
             user->priv->cancellable, _on_new_user_cb, user);
     return user;
 }
@@ -833,8 +826,9 @@ gum_user_create_sync (
     g_return_val_if_fail (user->priv->dbus_service != NULL, NULL);
 
     if (gum_dbus_user_service_call_create_new_user_sync (
-                user->priv->dbus_service, &object_path, user->priv->cancellable,
-                &error)) {
+            (GumDbusUserService*) gum_user_service_get_dbus_proxy (
+                    user->priv->dbus_service), &object_path,
+                    user->priv->cancellable, &error)) {
         _create_dbus_user (user, object_path, error);
     }
 
@@ -875,8 +869,10 @@ gum_user_get (
     g_return_val_if_fail (user && user->priv->dbus_service != NULL, NULL);
 
     _create_op (user, callback, user_data);
-     gum_dbus_user_service_call_get_user (user->priv->dbus_service, uid,
-            user->priv->cancellable, _on_get_user_cb, user);
+     gum_dbus_user_service_call_get_user (
+             (GumDbusUserService*) gum_user_service_get_dbus_proxy (
+             user->priv->dbus_service), uid, user->priv->cancellable,
+             _on_get_user_cb, user);
 
     return user;
 }
@@ -911,8 +907,10 @@ gum_user_get_sync (
                 user->priv->offline_service, uid, &error);
     } else if (user->priv->dbus_service) {
 
-        if (gum_dbus_user_service_call_get_user_sync (user->priv->dbus_service,
-                uid, &object_path, user->priv->cancellable, &error)) {
+        if (gum_dbus_user_service_call_get_user_sync (
+                (GumDbusUserService*) gum_user_service_get_dbus_proxy (
+                user->priv->dbus_service), uid, &object_path,
+                user->priv->cancellable, &error)) {
             _create_dbus_user (user, object_path, error);
         }
         g_free (object_path);
@@ -958,8 +956,10 @@ gum_user_get_by_name (
     g_return_val_if_fail (user && user->priv->dbus_service != NULL, NULL);
 
     _create_op (user, callback, user_data);
-    gum_dbus_user_service_call_get_user_by_name (user->priv->dbus_service,
-            username, user->priv->cancellable, _on_get_user_by_name_cb, user);
+    gum_dbus_user_service_call_get_user_by_name (
+            (GumDbusUserService*) gum_user_service_get_dbus_proxy (
+            user->priv->dbus_service), username, user->priv->cancellable,
+            _on_get_user_by_name_cb, user);
     return user;
 }
 
@@ -998,7 +998,8 @@ gum_user_get_by_name_sync (
 
     } else if (user->priv->dbus_service) {
         if (gum_dbus_user_service_call_get_user_by_name_sync (
-                user->priv->dbus_service, username, &object_path,
+                (GumDbusUserService*) gum_user_service_get_dbus_proxy (
+                user->priv->dbus_service), username, &object_path,
                 user->priv->cancellable,  &error)) {
             _create_dbus_user (user, object_path, error);
         }
@@ -1017,7 +1018,7 @@ gum_user_get_by_name_sync (
 
 /**
  * gum_user_add:
- * @self: #GumUser object to be added; object should have either valid
+ * @self: #GumUser object to be added
  * #GumUser:username or #GumUser:nickname in addition to valid
  * #GumUser:usertype.
  * @callback: #GumUserCb to be invoked when user is added
index 1c419df..f54f913 100644 (file)
@@ -3,9 +3,9 @@
 /*
  * This file is part of gum
  *
- * Copyright (C) 2013 Intel Corporation.
+ * Copyright (C) 2013 - 2015 Intel Corporation.
  *
- * Contact: Imran Zaman <imran.zaman@gmail.com>
+ * Contact: Imran Zaman <imran.zaman@intel.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -26,6 +26,7 @@
 #include <stdlib.h>
 
 #include "gum-user.h"
+#include "gum-user-service.h"
 #include "common/gum-log.h"
 #include "common/gum-config.h"
 #include "common/gum-defines.h"
@@ -42,7 +43,7 @@
 typedef struct {
     uid_t uid;
     gid_t gid;
-    GumUserType usertype;
+    gchar *user_type;
     gchar *user_name;
     gchar *nick_name;
     gchar *real_name;
@@ -56,9 +57,9 @@ typedef struct {
 
 typedef struct {
     gid_t gid;
-    GumGroupType grouptype;
+    gchar *group_type;
     gchar *group_name;
-    gchar *grp_secret;
+    gchar *group_secret;
 
     uid_t mem_uid; /*used in adding/deleting a member from the group*/
 } InputGroup;
@@ -92,7 +93,7 @@ _free_test_user (
                g_free (user->nick_name); g_free (user->real_name);
                g_free (user->office); g_free (user->office_phone);
                g_free (user->home_phone); g_free (user->home_dir);
-               g_free (user->shell);
+               g_free (user->shell); g_free (user->user_type);
                g_free (user);
        }
 }
@@ -102,7 +103,8 @@ _free_test_group (
                InputGroup *group)
 {
     if (group) {
-        g_free (group->group_name); g_free (group->grp_secret);
+        g_free (group->group_name); g_free (group->group_secret);
+        g_free (group->group_type);
         g_free (group);
     }
 }
@@ -138,7 +140,10 @@ _set_user_prop (
         GumUser *guser,
         InputUser *user)
 {
-    g_object_set (G_OBJECT (guser), "usertype", user->usertype, NULL);
+    if (user->user_type) {
+        g_object_set (G_OBJECT (guser), "usertype",
+                gum_user_type_from_string (user->user_type), NULL);
+    }
     if (user->user_name) {
         g_object_set (G_OBJECT (guser), "username", user->user_name, NULL);
     }
@@ -155,10 +160,15 @@ static void
 _print_user_prop (
                GumUser *guser)
 {
+       if (!guser) return;
+
        InputUser *user = _create_test_user ();
+       GumUserType ut = GUM_USERTYPE_NONE;
        g_object_get (G_OBJECT (guser), "uid", &user->uid, NULL);
        g_object_get (G_OBJECT (guser), "gid", &user->gid, NULL);
     g_object_get (G_OBJECT (guser), "username", &user->user_name, NULL);
+    g_object_get (G_OBJECT (guser), "usertype", &ut, NULL);
+    user->user_type = g_strdup (gum_user_type_to_string (ut));
     g_object_get (G_OBJECT (guser), "nickname", &user->nick_name, NULL);
     g_object_get (G_OBJECT (guser), "realname", &user->real_name, NULL);
     g_object_get (G_OBJECT (guser), "office", &user->office, NULL);
@@ -171,6 +181,7 @@ _print_user_prop (
     INFO ("uid : %u", user->uid);
     INFO ("gid : %u", user->gid);
     INFO ("username : %s", user->user_name ? user->user_name : "UNKNOWN");
+    INFO ("usertype : %s", user->user_type ? user->user_type : "UNKNOWN");
     INFO ("nickname : %s", user->nick_name ? user->nick_name : "UNKNOWN");
     INFO ("realname : %s", user->real_name ? user->real_name : "UNKNOWN");
     INFO ("office : %s", user->office ? user->office : "UNKNOWN");
@@ -178,7 +189,7 @@ _print_user_prop (
                user->office_phone ? user->office_phone : "UNKNOWN");
     INFO ("homephone : %s", user->home_phone ? user->home_phone : "UNKNOWN");
     INFO ("homedir : %s", user->home_dir ? user->home_dir : "UNKNOWN");
-    INFO ("shell : %s", user->shell ? user->shell : "UNKNOWN");
+    INFO ("shell : %s\n", user->shell ? user->shell : "UNKNOWN");
 
     _free_test_user (user);
 }
@@ -349,21 +360,63 @@ _handle_user_get_by_name (
 }
 
 static void
+_handle_user_get_list (
+        const gchar *types)
+{
+    GumUserService *service = NULL;
+    GumUser *guser = NULL;
+    GumUserList *users = NULL;
+    gchar **strv = NULL;
+
+    service = gum_user_service_create_sync (offline_mode);
+    if (!service) return;
+
+    strv = g_strsplit (types, ",", -1);
+    users = gum_user_service_get_user_list_sync (service,
+            (const gchar *const *)strv);
+    g_strfreev (strv);
+    if (users) {
+        GumUserList *src_list = users;
+        for ( ; src_list != NULL; src_list = g_list_next (src_list)) {
+            guser = (GumUser*) src_list->data;
+            _print_user_prop (guser);
+        }
+        gum_user_service_list_free (users);
+    }
+
+    g_object_unref (service);
+}
+
+static void
 _set_group_update_prop (
         GumGroup *grp,
         InputGroup *group)
 {
-    if (group->grp_secret) {
-        g_object_set (G_OBJECT (grp), "secret", group->grp_secret, NULL);
+    if (group->group_secret) {
+        g_object_set (G_OBJECT (grp), "secret", group->group_secret, NULL);
     }
 }
 
+static GumGroupType
+_group_type_from_string (
+        const gchar *in_type)
+{
+    if (g_strcmp0 (in_type, "user") == 0)
+        return GUM_GROUPTYPE_USER;
+    else if (g_strcmp0 (in_type, "system") == 0)
+        return GUM_GROUPTYPE_SYSTEM;
+    return GUM_GROUPTYPE_NONE;
+}
+
 static void
 _set_group_prop (
         GumGroup *grp,
         InputGroup *group)
 {
-    g_object_set (G_OBJECT (grp), "grouptype", group->grouptype, NULL);
+    if (group->group_type) {
+        g_object_set (G_OBJECT (grp), "grouptype", _group_type_from_string (
+                group->group_type), NULL);
+    }
     if (group->group_name) {
         g_object_set (G_OBJECT (grp), "groupname", group->group_name, NULL);
     }
@@ -527,6 +580,10 @@ main (int argc, char *argv[])
     gboolean rval = FALSE;
     GumConfig *config = NULL;
     gchar *sysroot = NULL;
+    gchar *user_types = NULL;
+
+    gboolean is_user_list_op = FALSE;
+    GOptionGroup* user_serv_option = NULL;
 
     gboolean is_user_add_op = FALSE, is_user_del_op = FALSE;
     gboolean is_user_up_op = FALSE, is_user_get_op = FALSE;
@@ -547,15 +604,8 @@ main (int argc, char *argv[])
 
     GOptionEntry main_entries[] =
     {
-        { "offline", 'o', 0, G_OPTION_ARG_NONE, &offline_mode,
-                "when gum-utils is invoked in offline mode, it triggers "
-                "synchronous APIs in offline mode. Effectively libgum will "
-                "perform the sync op add/delete/update/get without (dbus) gumd",
-                NULL},
-        { "sysroot", 'q', 0, G_OPTION_ARG_STRING, &sysroot, "sysroot path "
-                "[Offline mode ONLY]", "sysroot"},
         { "add-user", 'a', 0, G_OPTION_ARG_NONE, &is_user_add_op, "add user"
-                " -- username (or nickname) and usertype is mandatory", NULL},
+                " -- username (or nickname) and user_type is mandatory", NULL},
         { "delete-user", 'd', 0, G_OPTION_ARG_NONE, &is_user_del_op,
                 "delete user -- uid is mandatory", NULL},
         { "update-user", 'u', 0, G_OPTION_ARG_NONE, &is_user_up_op,
@@ -569,7 +619,7 @@ main (int argc, char *argv[])
                         " mandatory", NULL},
 
         { "add-group", 'g', 0, G_OPTION_ARG_NONE, &is_group_add_op, "add group"
-                " -- groupname and grouptype are mandatory", NULL},
+                " -- groupname and group_type are mandatory", NULL},
         { "delete-group", 'h', 0, G_OPTION_ARG_NONE, &is_group_del_op,
                 "delete group -- gid is mandatory", NULL},
         { "update-group", 'i', 0, G_OPTION_ARG_NONE, &is_group_up_op,
@@ -588,16 +638,36 @@ main (int argc, char *argv[])
         { "write-nfc", 'p', 0, G_OPTION_ARG_NONE, &is_write_nfc,
                 "write username and secret to an NFC tag when creating or"
                 " updating a user", NULL},
+        { "offline", 'o', 0, G_OPTION_ARG_NONE, &offline_mode,
+                "offline mode triggers libgum synchronous APIs without (dbus) "
+                "gumd to perform op add/delete/update/get",
+                NULL},
+        { "sysroot", 'q', 0, G_OPTION_ARG_STRING, &sysroot, "sysroot path "
+                "[Offline mode ONLY]", "sysroot"},
+        { "user-list", 'r', 0, G_OPTION_ARG_NONE, &is_user_list_op,
+                "if user_types argument is specified, then the calls will "
+                "return the specified users only otherwise all the users will "
+                "be returned", NULL},
         { NULL }
     };
     
+    GOptionEntry user_serv_entries[] =
+    {
+        { "user_types", 0, 0, G_OPTION_ARG_STRING, &user_types,
+                "valid user_type can be system or admin or guest or normal."
+                "Multiple user types can be specified as comma separated "
+                "values e.g. normal,system",
+                "type"},
+        { NULL }
+    };
+
     GOptionEntry user_entries[] =
     {
         { "username", 0, 0, G_OPTION_ARG_STRING, &user->user_name,
                 "user name", "name"},
-        { "usertype", 0, 0, G_OPTION_ARG_INT, &user->usertype,
-                "usertype can be 1 (system), 2 (admin), 3 (guest), 4 (normal) ",
-                "type; only integer is accepted as type."},
+        { "user_type", 0, 0, G_OPTION_ARG_STRING, &user->user_type,
+                "valid user_type can be system or admin or guest or normal.",
+                "type"},
         { "uid", 0, 0, G_OPTION_ARG_INT, &user->uid, "user id", "uid"},
         { "ugid", 0, 0, G_OPTION_ARG_INT, &user->gid, "group id", "gid"},
         { "usecret", 0, 0, G_OPTION_ARG_STRING, &user->secret,
@@ -623,11 +693,10 @@ main (int argc, char *argv[])
     {
         { "groupname", 0, 0, G_OPTION_ARG_STRING, &group->group_name,
                 "group name", "name"},
-        { "grouptype", 0, 0, G_OPTION_ARG_INT, &group->grouptype,
-                "group type can be 1 (system), 2 (user). Only integer is "
-                "accepted as type.", "type"},
+        { "group_type", 0, 0, G_OPTION_ARG_STRING, &group->group_type,
+                "valid group type can be system or user", "type"},
         { "gid", 0, 0, G_OPTION_ARG_INT, &group->gid, "group id", "gid"},
-        { "gsecret", 0, 0, G_OPTION_ARG_STRING, &group->grp_secret,
+        { "gsecret", 0, 0, G_OPTION_ARG_STRING, &group->group_secret,
                 "group secret in plain text", "secret"},
         { "mem_uid", 0, 0, G_OPTION_ARG_INT, &group->mem_uid, "mem uid",
                        "mem_uid"},
@@ -640,11 +709,16 @@ main (int argc, char *argv[])
     
     context = g_option_context_new ("\n"
             "  To add user in non-offline mode, gum-utils -a --username=user1 "
-            "  --usertype=4\n"
+            "  --user_type=normal\n"
             "  To delete user in offline mode, gum-utils -o -d --uid=2001\n"
             "  NOTE: Only one command can be run at one time.");
     g_option_context_add_main_entries (context, main_entries, NULL);
 
+    user_serv_option = g_option_group_new("user-service-options", "User service "
+            "specific options", "User service specific options", NULL, NULL);
+    g_option_group_add_entries(user_serv_option, user_serv_entries);
+    g_option_context_add_group (context, user_serv_option);
+
     user_option = g_option_group_new("user-options", "User specific options",
             "User specific options", NULL, NULL);
     g_option_group_add_entries(user_option, user_entries);
@@ -681,6 +755,8 @@ main (int argc, char *argv[])
        _handle_user_get (user);
     } else if (is_user_get_by_name_op) {
        _handle_user_get_by_name (user);
+    } else if (is_user_list_op) {
+        _handle_user_get_list (user_types);
     }
 
     /* group */
@@ -705,6 +781,7 @@ main (int argc, char *argv[])
     if (config) g_object_unref (config);
     _free_test_user (user);
     _free_test_group (group);
+    g_free (user_types);
 
     return 0;
 }
index f771fa0..2a2ac0c 100644 (file)
@@ -41,6 +41,7 @@
 #include "common/gum-file.h"
 #include "common/gum-crypt.h"
 #include "common/gum-validate.h"
+#include "common/gum-user-types.h"
 #include "common/gum-lock.h"
 #include "common/gum-string-utils.h"
 #include "common/gum-defines.h"
@@ -850,6 +851,92 @@ START_TEST (test_dictionary)
 }
 END_TEST
 
+START_TEST (test_usertype)
+{
+    DBG("");
+    gchar** strv = NULL;
+    gchar* str = NULL;
+
+    fail_if (gum_user_type_from_string (NULL) != GUM_USERTYPE_NONE);
+    fail_if (gum_user_type_from_string ("") != GUM_USERTYPE_NONE);
+
+    fail_if (gum_user_type_from_string ("abcde") != GUM_USERTYPE_NONE);
+    fail_if (gum_user_type_from_string ("system") != GUM_USERTYPE_SYSTEM);
+    fail_if (gum_user_type_from_string ("admin") != GUM_USERTYPE_ADMIN);
+    fail_if (gum_user_type_from_string ("guest") != GUM_USERTYPE_GUEST);
+    fail_if (gum_user_type_from_string ("normal") != GUM_USERTYPE_NORMAL);
+
+    fail_if (gum_user_type_to_string (45) != NULL);
+    fail_if (gum_user_type_to_string (0) != NULL);
+    fail_if (g_strcmp0 (gum_user_type_to_string (GUM_USERTYPE_NONE),
+            "asdf") == 0);
+    fail_if (g_strcmp0 (gum_user_type_to_string (GUM_USERTYPE_NONE),
+            "none") == 0);
+    fail_if (g_strcmp0 (gum_user_type_to_string (GUM_USERTYPE_SYSTEM),
+            "system") != 0);
+    fail_if (g_strcmp0 (gum_user_type_to_string (GUM_USERTYPE_ADMIN),
+            "admin") != 0);
+    fail_if (g_strcmp0 (gum_user_type_to_string (GUM_USERTYPE_GUEST),
+            "guest") != 0);
+    fail_if (g_strcmp0 (gum_user_type_to_string (GUM_USERTYPE_NORMAL),
+            "normal") != 0);
+
+    strv = gum_user_type_to_strv (GUM_USERTYPE_NORMAL);
+    fail_if (strv == NULL || g_strv_length (strv) != 1);
+    str = g_strjoinv (",",strv);
+    fail_if (g_strcmp0 (str, "normal") != 0);
+    g_free (str); g_strfreev (strv);
+
+    strv = gum_user_type_to_strv (GUM_USERTYPE_NORMAL|GUM_USERTYPE_SYSTEM);
+    fail_if (strv == NULL || g_strv_length (strv) != 2);
+    str = g_strjoinv (",",strv);
+    fail_if (g_strcmp0 (str, "system,normal") != 0);
+    g_free (str); g_strfreev (strv);
+
+    strv = gum_user_type_to_strv (16);
+    fail_if (strv == NULL || g_strv_length (strv) != 0);
+    g_strfreev (strv);
+
+    strv = gum_user_type_to_strv (GUM_USERTYPE_NONE);
+    fail_if (strv == NULL || g_strv_length (strv) != 0);
+    g_strfreev (strv);
+
+    fail_if (gum_user_type_from_strv (NULL) != GUM_USERTYPE_NONE);
+
+    strv = gum_string_utils_append_string (NULL,"");
+    fail_if (gum_user_type_from_strv ((const gchar *const *)strv)
+            != GUM_USERTYPE_NONE);
+    g_strfreev (strv);
+
+    strv = gum_string_utils_append_string (NULL,"normal");
+    fail_if (gum_user_type_from_strv ((const gchar *const *)strv) !=
+            GUM_USERTYPE_NORMAL);
+    g_strfreev (strv);
+
+    strv = gum_string_utils_append_string (NULL,"guest");
+    fail_if (gum_user_type_from_strv ((const gchar *const *)strv) !=
+            GUM_USERTYPE_GUEST);
+    g_strfreev (strv);
+
+    strv = gum_string_utils_append_string (NULL,"dasdf");
+    fail_if (gum_user_type_from_strv ((const gchar *const *)strv) !=
+            GUM_USERTYPE_NONE);
+    g_strfreev (strv);
+
+    strv = gum_string_utils_append_string (NULL,"guest");
+    strv = gum_string_utils_append_string (strv,"normal");
+    fail_if (gum_user_type_from_strv ((const gchar *const *)strv) !=
+            (GUM_USERTYPE_NORMAL|GUM_USERTYPE_GUEST));
+    g_strfreev (strv);
+
+    strv = gum_string_utils_append_string (NULL,"guest");
+    strv = gum_string_utils_append_string (strv,"normalsdafsa");
+    fail_if (gum_user_type_from_strv ((const gchar *const *)strv) !=
+            GUM_USERTYPE_GUEST);
+    g_strfreev (strv);
+}
+END_TEST
+
 Suite* common_suite (void)
 {
     Suite *s = suite_create ("Common library");
@@ -866,6 +953,7 @@ Suite* common_suite (void)
     tcase_add_test (tc_core, test_crypt);
     tcase_add_test (tc_core, test_error);
     tcase_add_test (tc_core, test_dictionary);
+    tcase_add_test (tc_core, test_usertype);
     suite_add_tcase (s, tc_core);
     return s;
 }
index 76893a0..ec865fb 100644 (file)
@@ -45,6 +45,7 @@
 #include "common/gum-file.h"
 #include "common/gum-user-types.h"
 #include "common/gum-group-types.h"
+#include "common/gum-string-utils.h"
 #include "common/dbus/gum-dbus-user-service-gen.h"
 #include "common/dbus/gum-dbus-user-gen.h"
 #include "common/dbus/gum-dbus-group-service-gen.h"
@@ -89,6 +90,7 @@ _setup_env (void)
     gchar *fpath = NULL;
     gchar *cmd = NULL;
 
+    fail_if (g_setenv ("UM_CONF_FILE", GUM_TEST_DATA_DIR, TRUE) == FALSE);
     fail_if (g_setenv ("UM_DAEMON_TIMEOUT", "10", TRUE) == FALSE);
     fail_if (g_setenv ("UM_USER_TIMEOUT", "10", TRUE) == FALSE);
     fail_if (g_setenv ("UM_GROUP_TIMEOUT", "10", TRUE) == FALSE);
@@ -521,7 +523,17 @@ START_TEST (test_daemon_user)
     fail_unless (error == NULL);
     g_object_get (G_OBJECT (user), "uid", &uid, "gid", &gid, "realname",
             &str, NULL);
-    fail_unless (uid == gid);
+    DBG("uid=%d gid=%d", uid, gid);
+    fail_unless (uid != GUM_USER_INVALID_UID &&
+            uid >= gum_config_get_uint (config, GUM_CONFIG_GENERAL_SYS_UID_MIN,
+                    GUM_USER_INVALID_UID) &&
+            uid <= gum_config_get_uint (config, GUM_CONFIG_GENERAL_SYS_UID_MAX,
+                    GUM_USER_INVALID_UID));
+    fail_unless (gid != GUM_GROUP_INVALID_GID &&
+            gid >= gum_config_get_uint (config, GUM_CONFIG_GENERAL_SYS_GID_MIN,
+                    GUM_GROUP_INVALID_GID) &&
+            gid <= gum_config_get_uint (config, GUM_CONFIG_GENERAL_SYS_GID_MAX,
+                    GUM_GROUP_INVALID_GID));
     fail_unless (str != NULL);
     g_free (str);
 
@@ -534,8 +546,17 @@ START_TEST (test_daemon_user)
     fail_unless (gumd_daemon_user_add (user, &uid, &error) == TRUE);
     fail_unless (uid > 0);
     fail_unless (error == NULL);
-    g_object_get (G_OBJECT (user), "uid", &uid, "gid", &gid,NULL);
-    fail_unless (uid == gid);
+    g_object_get (G_OBJECT (user), "uid", &uid, "gid", &gid, NULL);
+    fail_unless (uid != GUM_USER_INVALID_UID &&
+            uid >= gum_config_get_uint (config, GUM_CONFIG_GENERAL_SYS_UID_MIN,
+                    GUM_USER_INVALID_UID) &&
+            uid <= gum_config_get_uint (config, GUM_CONFIG_GENERAL_SYS_UID_MAX,
+                    GUM_USER_INVALID_UID));
+    fail_unless (gid != GUM_GROUP_INVALID_GID &&
+            gid >= gum_config_get_uint (config, GUM_CONFIG_GENERAL_SYS_GID_MIN,
+                    GUM_GROUP_INVALID_GID) &&
+            gid <= gum_config_get_uint (config, GUM_CONFIG_GENERAL_SYS_GID_MAX,
+                    GUM_GROUP_INVALID_GID));
 
     /* case 12: add admin user */
     g_object_unref (user);
@@ -547,7 +568,17 @@ START_TEST (test_daemon_user)
     fail_unless (uid > 0);
     fail_unless (error == NULL);
     g_object_get (G_OBJECT (user), "uid", &uid, "gid", &gid, NULL);
-    fail_unless (uid == gid);
+    fail_unless (uid != GUM_USER_INVALID_UID &&
+            uid >= gum_config_get_uint (config, GUM_CONFIG_GENERAL_UID_MIN,
+                    GUM_USER_INVALID_UID) &&
+            uid <= gum_config_get_uint (config, GUM_CONFIG_GENERAL_UID_MAX,
+                    GUM_USER_INVALID_UID));
+    fail_unless (gid != GUM_GROUP_INVALID_GID &&
+            gid >= gum_config_get_uint (config, GUM_CONFIG_GENERAL_GID_MIN,
+                    GUM_GROUP_INVALID_GID) &&
+            gid <= gum_config_get_uint (config, GUM_CONFIG_GENERAL_GID_MAX,
+                    GUM_GROUP_INVALID_GID));
+
     hdir = g_build_filename (gum_config_get_string (config,
             GUM_CONFIG_GENERAL_HOME_DIR_PREF), "admin_daemon_user1", NULL);
     fail_unless (stat (hdir, &sb) == 0);
@@ -1905,6 +1936,93 @@ START_TEST (test_delete_group_member)
 }
 END_TEST
 
+START_TEST (test_get_user_list)
+{
+    DBG ("\n");
+    GError *error = NULL;
+    GDBusConnection *connection = NULL;
+    GumDbusUserService *user_service = NULL;
+    GumDbusUser *user_proxy = NULL;
+    GVariant *users = NULL;
+    gboolean res = FALSE;
+    uid_t user_id = GUM_USER_INVALID_UID;
+    gchar **strv = NULL;
+
+    connection = _get_bus_connection (&error);
+    fail_if (connection == NULL, "failed to get bus connection : %s",
+            error ? error->message : "(null)");
+
+    user_service = _get_user_service (connection, &error);
+    fail_if (user_service == NULL, "failed to get user_service : %s",
+            error ? error->message : "");
+
+    user_proxy = _create_new_user_proxy (user_service, &error);
+    fail_if (user_proxy == NULL, "Failed to create new user : %s",
+            error ? error->message : "");
+
+    g_object_set (G_OBJECT (user_proxy), "username", "test_userlist1",
+            "secret", "123456", "nickname", "nick1", "usertype",
+            GUM_USERTYPE_NORMAL, NULL);
+
+    res = gum_dbus_user_call_add_user_sync (user_proxy, &user_id, NULL,
+            &error);
+    fail_if (res == FALSE, "Failed to add new user : %s",
+            error ? error->message : "");
+    fail_unless (user_id != GUM_USER_INVALID_UID);
+
+    strv = gum_string_utils_append_string (NULL,"normal");
+    res = gum_dbus_user_service_call_get_user_list_sync (user_service,
+            (const gchar *const *)strv, &users, NULL, &error);
+    g_strfreev (strv);
+    fail_if (res == FALSE, "Failed to get users : %s",
+            error ? error->message : "");
+    fail_if (users == NULL, "Failed to get users");
+
+    fail_if (g_variant_n_children (users) <= 0,
+            "Expected no of users > 1, got '%d'", g_variant_n_children(users));
+
+    /*
+    GVariantIter iter;
+    GVariant *user = NULL;
+    g_variant_iter_init (&iter, users);
+    while ((user = g_variant_iter_next_value (&iter))) {
+        gchar *name, *type;
+        uid_t uid;
+        uid_t gid;
+        g_variant_get (user, "(u)", &uid);
+        DBG ("user uid %d", uid);
+        g_variant_unref (user);
+    }*/
+    g_variant_unref (users);
+
+    g_object_set (G_OBJECT (user_proxy), "username", "test_userlist2",
+            "secret", "123456", "nickname", "nick1", "usertype",
+            GUM_USERTYPE_SYSTEM, NULL);
+
+    res = gum_dbus_user_call_add_user_sync (user_proxy, &user_id, NULL,
+            &error);
+    fail_if (res == FALSE, "Failed to add new user : %s",
+            error ? error->message : "");
+    fail_unless (user_id != GUM_USER_INVALID_UID);
+
+    strv = gum_string_utils_append_string (NULL,"system");
+    res = gum_dbus_user_service_call_get_user_list_sync (user_service,
+            (const gchar *const *)strv, &users, NULL, &error);
+    g_strfreev (strv);
+    fail_if (res == FALSE, "Failed to get users : %s",
+            error ? error->message : "");
+    fail_if (users == NULL, "Failed to get users");
+
+    fail_if (g_variant_n_children (users) <= 0,
+            "Expected no of users > 1, got '%d'", g_variant_n_children(users));
+    g_variant_unref (users);
+
+    g_object_unref (user_proxy);
+    g_object_unref (user_service);
+    g_object_unref (connection);
+}
+END_TEST
+
 Suite* daemon_suite (void)
 {
     TCase *tc = NULL;
@@ -1934,6 +2052,8 @@ Suite* daemon_suite (void)
 
     tcase_add_test (tc, test_add_group_member);
     tcase_add_test (tc, test_delete_group_member);
+
+    tcase_add_test (tc, test_get_user_list);
     suite_add_tcase (s, tc);
 
     return s;
index 2943890..7c3eb9a 100644 (file)
@@ -65,29 +65,29 @@ DEFAULT_USR_GROUPS=
 # environment variable.
 #SKEL_DIR=/etc/skel
 
-# Minimum value for the automatic uid selection. Default value is: 2000
-#UID_MIN=2000
+# Minimum value for the automatic uid selection. Default value is: 1000
+#UID_MIN=1000
 
 # Maximum value for the automatic uid selection. Default value is: 60000
 #UID_MAX=60000
 
 # Minimum value for the automatic uid selection for system user. Default
-# value is: 200
-#SYS_UID_MIN=200
+# value is: 100
+#SYS_UID_MIN=100
 
 # Maximum value for the automatic uid selection for system user. Default value
 # is: 999
 #SYS_UID_MAX=999
 
-# Minimum value for the automatic gid selection. Default value is: 2000
-#GID_MIN=2000
+# Minimum value for the automatic gid selection. Default value is: 1000
+#GID_MIN=1000
 
 # Maximum value for the automatic gid selection. Default value is: 60000
 #GID_MAX=60000
 
 # Minimum value for the automatic gid selection for system user. Default value
-# is: 200
-#SYS_GID_MIN=200
+# is: 100
+#SYS_GID_MIN=100
 
 # Maximum value for the automatic gid selection for system user. Default value
 # is: 999
index 9336fb2..b676d56 100644 (file)
@@ -1,5 +1,5 @@
 <busconfig>
-    <type>session</type>
+    <type>system</type>
     <listen>unix:tmpdir=/tmp/</listen>
     <servicedir>/home/imran/work/um/gumd/test/data/services</servicedir>
     <policy context="default">
index 2a18d2e..49536e8 100644 (file)
 #include "common/gum-file.h"
 #include "common/gum-user-types.h"
 #include "common/gum-group-types.h"
+#include "common/gum-string-utils.h"
 #include "common/dbus/gum-dbus-user-service-gen.h"
 #include "common/dbus/gum-dbus-user-gen.h"
 #include "common/dbus/gum-dbus-group-service-gen.h"
 #include "common/dbus/gum-dbus-group-gen.h"
 #include "gum-user.h"
+#include "gum-user-service.h"
 #include "gum-group.h"
 
 #ifdef GUM_BUS_TYPE_P2P
@@ -88,6 +90,7 @@ _setup_env (void)
     gchar *fpath = NULL;
     gchar *cmd = NULL;
 
+    fail_if (g_setenv ("UM_CONF_FILE", GUM_TEST_DATA_DIR, TRUE) == FALSE);
     fail_if (g_setenv ("UM_DAEMON_TIMEOUT", "10", TRUE) == FALSE);
     fail_if (g_setenv ("UM_USER_TIMEOUT", "10", TRUE) == FALSE);
     fail_if (g_setenv ("UM_GROUP_TIMEOUT", "10", TRUE) == FALSE);
@@ -298,6 +301,18 @@ _on_user_op_failure (
 }
 
 static void
+_on_user_service_op_success (
+        GumUserService *service,
+        const GError *error,
+        gpointer user_data)
+{
+    _stop_mainloop ();
+
+    fail_if (error != NULL, "failed user service operation : %s",
+            error ? error->message : "(null)");
+}
+
+static void
 _on_group_op_success (
         GumGroup *group,
         const GError *error,
@@ -1004,6 +1019,113 @@ START_TEST (test_delete_group_member)
 }
 END_TEST
 
+static void
+_on_user_service_user_list_op_success (
+        GumUserService *service,
+        GumUserList *users,
+        const GError *error,
+        gpointer user_data)
+{
+    _stop_mainloop ();
+
+    fail_if (error != NULL, "failed user service user list operation : %s",
+            error ? error->message : "(null)");
+    gum_user_service_list_free (users);
+}
+
+static void
+_on_user_service_user_list_op_failure (
+        GumUserService *service,
+        GumUserList *users,
+        const GError *error,
+        gpointer user_data)
+{
+    _stop_mainloop ();
+
+    fail_if (error == NULL, "op should have failed for getting user list");
+    gum_user_service_list_free (users);
+}
+
+START_TEST (test_get_user_list)
+{
+    GumUserService *service = NULL;
+    gboolean rval = FALSE;
+    GumUserList *user_list = NULL;
+    gchar **strv = NULL;
+
+    DBG ("\n");
+
+    /* case 1: create async object */
+    service = gum_user_service_create (_on_user_service_op_success, NULL);
+    fail_if (service == NULL, "failed to create new user service");
+    _run_mainloop ();
+    fail_if (gum_user_service_get_dbus_proxy(service) == NULL, "no dbus proxy");
+    g_object_unref (service);
+
+    /* case 2: create sync object without offline */
+    service = gum_user_service_create_sync (FALSE);
+    fail_if (service == NULL, "failed to create new user service");
+    g_object_unref (service);
+
+    /* case 3 create sync object with offline */
+    service = gum_user_service_create_sync (TRUE);
+    fail_if (service == NULL, "failed to create new user service");
+    fail_if (gum_user_service_get_dbus_proxy(service) == NULL, "dbus proxy");
+    g_object_unref (service);
+
+    /* case 4: misc */
+    service = gum_user_service_create_sync (FALSE);
+    fail_if (service == NULL, "failed to create new user service");
+    fail_if (gum_user_service_get_dbus_proxy(service) == NULL, "no dbus proxy");
+    g_object_unref (service);
+
+    /* case 5: get user list async -- success */
+    service = gum_user_service_create_sync (FALSE);
+    fail_if (service == NULL, "failed to create new user service");
+    strv = gum_string_utils_append_string (NULL,"normal");
+    strv = gum_string_utils_append_string (strv,"system");
+    rval = gum_user_service_get_user_list (service, (const gchar *const *)strv,
+            _on_user_service_user_list_op_success, NULL);
+    g_strfreev (strv);
+    fail_if (rval == FALSE, "failed to get users uids");
+    _run_mainloop ();
+    g_object_unref (service);
+
+    /* case 6: get user list async -- failure */
+    service = gum_user_service_create_sync (FALSE);
+    fail_if (service == NULL, "failed to create new user service");
+    strv = gum_string_utils_append_string (NULL,"none");
+    rval = gum_user_service_get_user_list (service, (const gchar *const *)strv,
+            _on_user_service_user_list_op_failure, NULL);
+    g_strfreev (strv);
+    fail_if (rval == FALSE, "failed to get users uids");
+    _run_mainloop ();
+    g_object_unref (service);
+
+    /* case 7: get user list sync */
+    service = gum_user_service_create_sync (FALSE);
+    fail_if (service == NULL, "failed to create new user service");
+    strv = gum_string_utils_append_string (NULL,"none");
+    user_list = gum_user_service_get_user_list_sync (service,
+            (const gchar *const *)strv);
+    g_strfreev (strv);
+    fail_if (user_list != NULL, "failed to get users uids");
+    g_object_unref (service);
+
+    /* case 8: get user list sync -- success */
+    service = gum_user_service_create_sync (FALSE);
+    fail_if (service == NULL, "failed to create new user service");
+    strv = gum_string_utils_append_string (NULL,"normal");
+    user_list = gum_user_service_get_user_list_sync (service,
+            (const gchar *const *)strv);
+    g_strfreev (strv);
+    fail_if (user_list == NULL, "failed to get users uids");
+    fail_if (g_list_length (user_list) <= 0, "no normal users found");
+    gum_user_service_list_free (user_list);
+    g_object_unref (service);
+}
+END_TEST
+
 Suite* daemon_suite (void)
 {
     TCase *tc = NULL;
@@ -1031,6 +1153,7 @@ Suite* daemon_suite (void)
     tcase_add_test (tc, test_add_group_member);
     tcase_add_test (tc, test_delete_group_member);
 
+    tcase_add_test (tc, test_get_user_list);
     suite_add_tcase (s, tc);
 
     return s;