Author: mvidner
Date: Fri Jul 10 15:25:08 2009
New Revision: 58020
URL: http://svn.opensuse.org/viewcvs/yast?rev=58020&view=rev
Log:
Merged the branch
http://svn.opensuse.org/svn/yast/branches/tmp/mvidner/core-dbus-values
(Use svn log/blame -g/--use-merge-history to see details)
Added:
trunk/core/dbus/namespace_service/testsuite/dbustest.py
- copied unchanged from r58019, branches/tmp/mvidner/core-dbus-values/dbus/namespace_service/testsuite/dbustest.py
trunk/core/dbus/namespace_service/testsuite/t2.py
- copied unchanged from r58019, branches/tmp/mvidner/core-dbus-values/dbus/namespace_service/testsuite/t2.py
trunk/core/dbus/namespace_service/testsuite/t3-unknown-method.py
- copied unchanged from r58019, branches/tmp/mvidner/core-dbus-values/dbus/namespace_service/testsuite/t3-unknown-method.py
trunk/core/dbus/namespace_service/testsuite/t4-bad-params.py
- copied unchanged from r58019, branches/tmp/mvidner/core-dbus-values/dbus/namespace_service/testsuite/t4-bad-params.py
trunk/core/dbus/namespace_service/testsuite/t5-params.py
- copied unchanged from r58019, branches/tmp/mvidner/core-dbus-values/dbus/namespace_service/testsuite/t5-params.py
Removed:
trunk/core/dbus/namespace_service/testsuite/t2
trunk/core/dbus/namespace_service/testsuite/t3-unknown-method
Modified:
trunk/core/ (props changed)
trunk/core/VERSION
trunk/core/dbus/SCR_service/DBusServer.cc
trunk/core/dbus/namespace_service/doc/org.opensuse.yast.modules.yapi.samba.policy (props changed)
trunk/core/dbus/namespace_service/src/DBusModulesServer.cc
trunk/core/dbus/namespace_service/src/DBusModulesServer.h
trunk/core/dbus/namespace_service/testsuite/ (props changed)
trunk/core/dbus/namespace_service/testsuite/Makefile.am
trunk/core/dbus/namespace_service/testsuite/test_all
trunk/core/dbus/namespace_service/testsuite/test_server
trunk/core/libscr/src/SCR.cc
trunk/core/liby2dbus/src/DBusMsg.cc
trunk/core/liby2dbus/src/DBusMsg.h
trunk/core/liby2dbus/src/DBusServerBase.cc
trunk/core/liby2dbus/src/DBusServerBase.h
trunk/core/package/yast2-core.changes
trunk/core/yast2-core.spec.in
Modified: trunk/core/VERSION
URL: http://svn.opensuse.org/viewcvs/yast/trunk/core/VERSION?rev=58020&r1=58019&r2=58020&view=diff
==============================================================================
--- trunk/core/VERSION (original)
+++ trunk/core/VERSION Fri Jul 10 15:25:08 2009
@@ -1 +1 @@
-2.18.14
+2.18.15
Modified: trunk/core/dbus/SCR_service/DBusServer.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/core/dbus/SCR_service/DBusServer.cc?rev=58020&r1=58019&r2=58020&view=diff
==============================================================================
--- trunk/core/dbus/SCR_service/DBusServer.cc (original)
+++ trunk/core/dbus/SCR_service/DBusServer.cc Fri Jul 10 15:25:08 2009
@@ -94,6 +94,8 @@
&& request.interface() == YAST_SCR_INTERFACE
&& request.path() == SCR_OBJECT_PATH)
{
+ try
+ {
std::string method(request.method());
YCPValue arg0;
@@ -118,7 +120,7 @@
}
else
{
- arg0 = request.getYCPValue(0);
+ arg0 = request.getYCPValue(0, Type::Path);
if (arg0.isNull() || !arg0->isPath())
{
@@ -141,8 +143,8 @@
if (check_ok)
{
- YCPValue arg = request.getYCPValue(1);
- YCPValue opt = request.getYCPValue(2);
+ YCPValue arg = request.getYCPValue(1, Type::Unspec);
+ YCPValue opt = request.getYCPValue(2, Type::Unspec);
std::string caller(request.sender());
@@ -188,6 +190,13 @@
else
reply.addYCPValue(YCPVoid());
}
+ }
+ catch (const DBusException& de)
+ {
+ y2error ("Caught: %s", de.message().c_str());
+ y2error ("Returning %s", de.name().c_str());
+ reply.createError(request, de.message(), de.name());
+ }
}
y2milestone("Finishing the callback");
@@ -205,30 +214,39 @@
ret.push_back(action_id);
- YCPValue path = msg.getYCPValue(0);
- YCPValue arg = msg.getYCPValue(1);
- YCPValue opt = msg.getYCPValue(2);
+ try
+ {
+ YCPValue path = msg.getYCPValue(0, Type::Path);
+ YCPValue arg = msg.getYCPValue(1, Type::Unspec);
+ YCPValue opt = msg.getYCPValue(2, Type::Unspec);
- std::string path_str, arg_str, opt_str;
+ std::string path_str, arg_str, opt_str;
- if (!path.isNull())
- {
- path_str = path->toString();
- }
-
- if (!arg.isNull() && arg->isString())
- {
- arg_str = arg->asString()->value();
- }
+ if (!path.isNull())
+ {
+ path_str = path->toString();
+ }
- if (!opt.isNull() && opt->isString())
+ if (!arg.isNull() && arg->isString())
+ {
+ arg_str = arg->asString()->value();
+ }
+
+ if (!opt.isNull() && opt->isString())
+ {
+ opt_str = opt->asString()->value();
+ }
+
+ action_id = PolKit::createActionId(POLKIT_PREFIX, path_str, msg.method(), arg_str, opt_str);
+
+ ret.push_back(action_id);
+ }
+ catch (const DBusException& de)
{
- opt_str = opt->asString()->value();
+ y2error ("Caught: %s", de.message().c_str());
+ y2error ("While trying to create action ID.");
}
- action_id = PolKit::createActionId(POLKIT_PREFIX, path_str, msg.method(), arg_str, opt_str);
-
- ret.push_back(action_id);
#endif
return ret;
Modified: trunk/core/dbus/namespace_service/src/DBusModulesServer.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/core/dbus/namespace_service/src/DBusModulesServer.cc?rev=58020&r1=58019&r2=58020&view=diff
==============================================================================
--- trunk/core/dbus/namespace_service/src/DBusModulesServer.cc (original)
+++ trunk/core/dbus/namespace_service/src/DBusModulesServer.cc Fri Jul 10 15:25:08 2009
@@ -407,6 +407,8 @@
bool found = false;
if (t)
{
+ try
+ {
constFunctionTypePtr fptr(t);
if (fptr)
@@ -433,7 +435,8 @@
while(index < reqarg)
{
- YCPValue arg = request.getYCPValue(index);
+ constTypePtr argtype(fptr->parameterType(index));
+ YCPValue arg = request.getYCPValue(index, argtype);
if (arg.isNull())
{
@@ -443,8 +446,6 @@
}
// check the data type compatibility
- constTypePtr argtype(fptr->parameterType(index));
-
if (argtype->matchvalue(arg) < 0)
{
if (interface == YAST_DBUS_RAW_INTERFACE)
@@ -490,6 +491,7 @@
}
else
{
+ // FIXME should be a dbus error
y2error("Wrong parameters to function %s::%s", object.c_str(), method.c_str());
}
}
@@ -500,17 +502,26 @@
y2error("Function %s::%s got %d parameters instead of %d", object.c_str(), method.c_str(), request.arguments(), fptr->parameterCount());
}
}
+ }
+ catch (const DBusException& de)
+ {
+ y2error ("Caught: %s", de.message().c_str());
+ y2error ("Returning %s", de.name().c_str());
+ reply.createError(request, de.message(), de.name());
+ return reply;
+ }
}
if (!found)
{
+// see also DBusServerBase::unknownRequest
y2internal("Function %s::%s was not found although it was registered", object.c_str(), method.c_str());
string msg = "Method '"+ interface + "." + method + "' "
"on object '" + object + "' doesn't exist";
// anyway, why didnt dbus itself cry?
reply.createError(request, // in reply to
msg,
- "org.freedesktop.DBus.Error.UnknownMethod");
+ DBUS_ERROR_UNKNOWN_METHOD);
return reply;
}
@@ -554,8 +565,6 @@
y2milestone("ModuleManager request: object: %s, method: %s, interface: %s",
object.c_str(), method.c_str(), interface.c_str());
- reply.createReply(request);
-
if (object == YAST_DBUS_OBJ_PREFIX)
{
if (interface == YAST_DBUS_MGR_INTERFACE)
@@ -564,7 +573,9 @@
{
if (request.arguments() == 1)
{
- YCPValue arg = request.getYCPValue(0);
+ try
+ {
+ YCPValue arg = request.getYCPValue(0, Type::String);
if (arg.isNull())
{
@@ -588,6 +599,7 @@
}
y2milestone("Result: %s", ret ? "true" : "false");
+ reply.createReply(request);
reply.addBoolean(ret);
}
else
@@ -595,20 +607,29 @@
y2error("Expecting 'string' parameter, got '%s'", Type::vt2type(arg->valuetype())->toString().c_str());
}
}
-
+ }
+ catch (const DBusException& de)
+ {
+ y2error ("Caught: %s", de.message().c_str());
+ y2error ("Returning %s", de.name().c_str());
+ reply.createError(request, de.message(), de.name());
+ }
}
else
{
y2error("ModuleManager function %s got %d parameters instead of 1", method.c_str(), request.arguments());
+ reply.createError(request, "Invalid number of parameters", DBUS_ERROR_INVALID_ARGS);
}
}
else if (method == YAST_DBUS_MANAGER_UNLOCK_METHOD)
{
unregister_client(request.sender());
+ reply.createReply(request);
}
else if (method == YAST_DBUS_MANAGER_LOCK_METHOD)
{
register_client(request.sender());
+ reply.createReply(request);
}
}
}
Modified: trunk/core/dbus/namespace_service/src/DBusModulesServer.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/core/dbus/namespace_service/src/DBusModulesServer.h?rev=58020&r1=58019&r2=58020&view=diff
==============================================================================
--- trunk/core/dbus/namespace_service/src/DBusModulesServer.h (original)
+++ trunk/core/dbus/namespace_service/src/DBusModulesServer.h Fri Jul 10 15:25:08 2009
@@ -35,6 +35,7 @@
virtual actionList createActionId(const DBusMsg &msg);
// handle unknown requests
+ // Tries to autoimport and retry
virtual DBusMsg unknownRequest(const DBusMsg &request);
private:
Modified: trunk/core/dbus/namespace_service/testsuite/Makefile.am
URL: http://svn.opensuse.org/viewcvs/yast/trunk/core/dbus/namespace_service/testsuite/Makefile.am?rev=58020&r1=58019&r2=58020&view=diff
==============================================================================
--- trunk/core/dbus/namespace_service/testsuite/Makefile.am (original)
+++ trunk/core/dbus/namespace_service/testsuite/Makefile.am Fri Jul 10 15:25:08 2009
@@ -3,6 +3,6 @@
SUBDIRS = modules
-EXTRA_DIST = $(wildcard *.test) test_all test_server t1 t2
+EXTRA_DIST = $(wildcard *.test) test_all test_server dbustest.py t1 $(wildcard t*.py)
CLEANFILES = $(wildcard *.test.reply)
Modified: trunk/core/dbus/namespace_service/testsuite/test_all
URL: http://svn.opensuse.org/viewcvs/yast/trunk/core/dbus/namespace_service/testsuite/test_all?rev=58020&r1=58019&r2=58020&view=diff
==============================================================================
--- trunk/core/dbus/namespace_service/testsuite/test_all (original)
+++ trunk/core/dbus/namespace_service/testsuite/test_all Fri Jul 10 15:25:08 2009
@@ -1,14 +1,36 @@
#! /bin/sh
# run all applicable test cases with proper setup
-# $0
+# $0 [-a: all, even failing]
# $0 ./a_single_testcase
-: ${CASES:=$@}
-# : ${CASES:=./t?} # t2 fails. also, it requires python
- : ${CASES:=./t1}
+# stress test iterations
+if [ "$1" = "-s" ]; then
+ STRESS=${2-10}
+ shift
+ shift
+fi
+
+if [ "$1" = "" ]; then
+ : ${CASES:=./t[12345]*}
+elif [ "$1" = "-a" ]; then
+ : ${CASES:=./t? ./t*-*}
+else
+ : ${CASES:=$@}
+fi
+CASES_A=($CASES) # make array
+CASES_A=(${CASES_A[@]/*~/}) # exclude backup files
+if ! which python; then
+ echo >&2 "Python not found, skipping those tests"
+ CASES_A=(${CASES_A[@]/*.py/}) # exclude python files
+fi
# load the modules from the current directory
export Y2DIR=.
+SVRDIR=../src
+SVR=$SVRDIR/yast_modules_dbus_server
+if [ -n "$STRESS" ]; then
+ SVR="-s $STRESS valgrind --leak-check=full $SVRDIR/.libs/yast_modules_dbus_server"
+fi
./test_server \
- ../src/yast_modules_dbus_server --disable-timer --test TEST \
+ $SVR --disable-timer --test TEST \
-- \
- $CASES
+ ${CASES_A[@]}
Modified: trunk/core/dbus/namespace_service/testsuite/test_server
URL: http://svn.opensuse.org/viewcvs/yast/trunk/core/dbus/namespace_service/testsuite/test_server?rev=58020&r1=58019&r2=58020&view=diff
==============================================================================
--- trunk/core/dbus/namespace_service/testsuite/test_server (original)
+++ trunk/core/dbus/namespace_service/testsuite/test_server Fri Jul 10 15:25:08 2009
@@ -5,6 +5,13 @@
# $0 server [arg1 arg2...] -- test1 test2...
set -o errexit
+# stress test iterations
+if [ "$1" = "-s" ]; then
+ STRESS=$2
+ shift
+ shift
+fi
+
while [ "$1" != "--" ]; do
SERVER="$SERVER $1"
shift
@@ -13,18 +20,39 @@
# This launches the bus daemon,
# exports DBUS_SESSION_BUS_ADDRESS and sets DBUS_SESSION_BUS_PID
-# FIXME dbus-launch is in dbus-1-x11, an unnecessary dependency
-eval $(dbus-launch --sh-syntax)
-# Clean up at exit. This will also kill the server.
-trap "kill $DBUS_SESSION_BUS_PID" EXIT TERM INT
+my_dbus_launch () {
+ # reimplementing dbus-launch because it is in dbus-1-x11.rpm
+ PF=`mktemp --tmpdir dbus.pid.XXXXXX` || exit
+ AF=`mktemp --tmpdir dbus.addr.XXXXXX` || exit
+
+ dbus-daemon --session --print-address=3 3>$AF --print-pid=4 4>$PF &
+ # wait for the daemon to print the info
+ while [ ! -s $AF -a ! -s $PF ]; do sleep 0.1; done
+ DBUS_SESSION_BUS_PID=$(cat $PF)
+ export DBUS_SESSION_BUS_ADDRESS=$(cat $AF)
+ # Clean up at exit. This will also kill the server.
+ trap "kill $DBUS_SESSION_BUS_PID; rm $AF $PF" EXIT TERM INT
+}
+my_dbus_launch
echo -n "Hey, server, get on da bus... "
# start the server
+# TODO watch for NameAcquired
$SERVER & sleep 3
+ # give valgrind more time, it is gonna take long anyway
+if [ -n "$STRESS" ]; then sleep 5; fi
echo "off we go!"
-while [ -n "$1" ]; do
- echo Running $1
- $1
- shift
+run_all () {
+ while [ -n "$1" ]; do
+ echo Running $1
+ $1
+ shift
+ done
+}
+
+: ${STRESS=1}
+for stress in `seq $STRESS -1 1`; do
+ echo Stress test, $stress iterations to go.
+ run_all "$@"
done
Modified: trunk/core/libscr/src/SCR.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/core/libscr/src/SCR.cc?rev=58020&r1=58019&r2=58020&view=diff
==============================================================================
--- trunk/core/libscr/src/SCR.cc (original)
+++ trunk/core/libscr/src/SCR.cc Fri Jul 10 15:25:08 2009
@@ -83,7 +83,15 @@
y2debug("Received reply type: %d", reply.type());
// return the first argument from the reply
- YCPValue ret = reply.getYCPValue(0);
+ YCPValue ret;
+ try
+ {
+ ret = reply.getYCPValue(0, Type::Unspec);
+ }
+ catch (const DBusException& de)
+ {
+ y2error ("Caught: %s: %s", de.name().c_str(), de.message().c_str());
+ }
// validate the reply (check for exceptions)
if (reply.type() != DBUS_MESSAGE_TYPE_METHOD_RETURN)
Modified: trunk/core/liby2dbus/src/DBusMsg.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/core/liby2dbus/src/DBusMsg.cc?rev=58020&r1=58019&r2=58020&view=diff
==============================================================================
--- trunk/core/liby2dbus/src/DBusMsg.cc (original)
+++ trunk/core/liby2dbus/src/DBusMsg.cc Fri Jul 10 15:25:08 2009
@@ -1,4 +1,3 @@
-
/*
DBusMsg
@@ -9,6 +8,8 @@
#include "YCP.h"
#include
#include
+#include
+using namespace stringutil;
DBusMsg::DBusMsg() : msg(NULL)
{
@@ -123,9 +124,9 @@
return addValue(DBUS_TYPE_INT32, &val);
}
-bool DBusMsg::addBoolean(bool val)
+bool DBusMsg::addBoolean(dbus_bool_t val)
{
- return addValue(DBUS_TYPE_INT64, &val);
+ return addValue(DBUS_TYPE_BOOLEAN, &val);
}
bool DBusMsg::addDouble(double val)
@@ -662,265 +663,358 @@
}
-YCPValue DBusMsg::getYCPValueRaw(DBusMessageIter *it, const std::string &ycp_type) const
+// returns NULL if "it" does not point to a string
+const char * DBusMsg::getString(DBusMessageIter *it) const
{
- YCPValue ret;
+ const char *s = NULL;
+ if (dbus_message_iter_get_arg_type (it) == DBUS_TYPE_STRING)
+ {
+ dbus_message_iter_get_basic(it, &s);
+ }
+ return s;
+}
- int type = dbus_message_iter_get_arg_type(it);
+// "it" is the inside iterator
+YCPList DBusMsg::getYCPValueList(DBusMessageIter *it, constTypePtr valuetype) const
+{
+ YCPList lst;
- // TODO support more types
- if (type == DBUS_TYPE_BOOLEAN)
+ while (dbus_message_iter_get_arg_type (it) != DBUS_TYPE_INVALID)
{
- bool b;
- dbus_message_iter_get_basic(it, &b);
- ret = YCPBoolean(b);
+ // FIXME this can fail
+ YCPValue list_val = getYCPValue(it, valuetype);
+ lst->add(list_val);
+
+ dbus_message_iter_next(it);
}
- else if (type == DBUS_TYPE_STRING)
- {
- const char *s;
- dbus_message_iter_get_basic(it, &s);
+ return lst;
+}
- static const char* block_prefix = "block ";
- static const int block_prefix_len = ::strlen(block_prefix);
+// "it" is the inside iterator
+YCPMap DBusMsg::getYCPValueMap(DBusMessageIter *it, constTypePtr keytype, constTypePtr valuetype) const
+{
+ YCPMap map;
- // use ycp_type to return the correct type
- if (ycp_type.empty() || ycp_type == "string")
- ret = YCPString(s);
- else if (ycp_type == "symbol")
- ret = YCPSymbol(s);
- else if (ycp_type == "path")
- ret = YCPPath(s);
- else if (std::string(ycp_type, 0, block_prefix_len) == block_prefix)
+ while (dbus_message_iter_get_arg_type (it) != DBUS_TYPE_INVALID)
+ {
+ // is it a map or a list?
+ if (dbus_message_iter_get_arg_type(it) == DBUS_TYPE_DICT_ENTRY)
{
- y2debug("Found YCP block");
+ DBusMessageIter mapit;
+ dbus_message_iter_recurse(it, &mapit);
- if (s == NULL || *s == '\0')
- {
- y2warning("The code block is empty");
- ret = YCPVoid();
- }
- else
- {
- // parse the string, recreate the YCPBlock again
- Parser parser(s);
- parser.setBuffered();
- YCodePtr p = parser.parse();
- YCPValue contents = YCPNull ();
-
- if (!p)
- {
- y2error("Parse error in YCP code: %s", s);
- }
- else
- {
- if (p->isBlock ())
- {
- contents = YCPCode (p);
- }
- else
- {
- contents = p->evaluate (true);
- }
- }
+ // DICT keys cannot be structs, skip Bsv
+ YCPValue key = getYCPValueRawType(&mapit, keytype);
- ret = !contents.isNull() ? contents : YCPVoid();
- }
+ dbus_message_iter_next(&mapit);
+
+ // read the value
+ YCPValue val = getYCPValue(&mapit, valuetype);
+
+ map->add(key, val);
}
- else
+ // else FIXME how to signal error
+
+ dbus_message_iter_next(it);
+ }
+ return map;
+}
+
+// returns YCPNull without an error if "it" does not point to an integer/byte
+YCPValue DBusMsg::getYCPValueInteger(DBusMessageIter *it) const
+{
+ int type = dbus_message_iter_get_arg_type(it);
+ YCPValue ret;
+
+ switch (type) {
+ case DBUS_TYPE_INT64:
{
- y2warning("Unknown STRING data, returning as YCPString");
- // default is YCPString
- ret = YCPString(s);
+ dbus_int64_t i;
+ dbus_message_iter_get_basic(it, &i);
+ ret = YCPInteger(i);
+ break;
+ }
+ case DBUS_TYPE_UINT64:
+ {
+ // warning: YCPInteger is signed!
+ dbus_uint64_t i;
+ dbus_message_iter_get_basic(it, &i);
+ ret = YCPInteger(i);
+ break;
+ }
+ case DBUS_TYPE_INT32:
+ {
+ dbus_int32_t i;
+ dbus_message_iter_get_basic(it, &i);
+ ret = YCPInteger(i);
+ break;
+ }
+ case DBUS_TYPE_UINT32:
+ {
+ dbus_uint32_t i;
+ dbus_message_iter_get_basic(it, &i);
+ ret = YCPInteger(i);
+ break;
+ }
+ case DBUS_TYPE_INT16:
+ {
+ dbus_int16_t i;
+ dbus_message_iter_get_basic(it, &i);
+ ret = YCPInteger(i);
+ break;
+ }
+ case DBUS_TYPE_UINT16:
+ {
+ dbus_uint16_t i;
+ dbus_message_iter_get_basic(it, &i);
+ ret = YCPInteger(i);
+ break;
+ }
+ case DBUS_TYPE_BYTE:
+ {
+ unsigned char i;
+ dbus_message_iter_get_basic(it, &i);
+ ret = YCPInteger(i);
+ break;
}
}
- else if (type == DBUS_TYPE_ARRAY)
- {
- DBusMessageIter sub;
- dbus_message_iter_recurse(it, &sub);
+ return ret;
+}
- // DBUS_TYPE_ARRAY is used for YCPList and YCPMap
- if (ycp_type == "list")
- {
- y2debug("Found an YCPList container");
- YCPList lst;
+// here ycptype is NOT Type::Unspec
+YCPValue DBusMsg::getYCPValueRawType(DBusMessageIter *it, constTypePtr ycptype) const
+{
+ if (ycptype->isAny())
+ return getYCPValueRawAny(it);
- while (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID)
- {
- YCPValue list_val = getYCPValue(&sub);
- lst->add(list_val);
+ YCPValue ret;
- dbus_message_iter_next(&sub);
- }
+ int type = dbus_message_iter_get_arg_type(it);
+ bool mismatch = true;
- ret = lst;
+ if (ycptype->isBoolean())
+ {
+ if (type == DBUS_TYPE_BOOLEAN)
+ {
+ bool b;
+ dbus_message_iter_get_basic(it, &b);
+ ret = YCPBoolean(b);
+ mismatch = false;
}
- else if (ycp_type == "map")
+ }
+ else if (ycptype->isInteger())
+ {
+ ret = getYCPValueInteger(it);
+ mismatch = ret.isNull();
+ }
+ else if (ycptype->isFloat())
+ {
+ if (type == DBUS_TYPE_DOUBLE)
{
- y2debug("Found an YCPMap container");
- YCPMap map;
-
- while (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID)
- {
- // is it a map or a list?
- if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_DICT_ENTRY)
- {
- DBusMessageIter mapit;
- dbus_message_iter_recurse(&sub, &mapit);
-
- // read the key without the header
- YCPValue key = getYCPValueRaw(&mapit);
-
- dbus_message_iter_next(&mapit);
+ double d;
+ dbus_message_iter_get_basic(it, &d);
+ ret = YCPFloat(d);
+ mismatch = false;
+ }
+ }
+ else if (ycptype->isList())
+ {
+ // DBUS_TYPE_ARRAY is used for YCPList and YCPMap
+ // TODO sending a dict where a list is expected will confusingly complain about value type mismatch
+ if (type == DBUS_TYPE_ARRAY)
+ {
+ DBusMessageIter sub;
+ dbus_message_iter_recurse(it, &sub);
- // read the value
- YCPValue val = getYCPValue(&mapit);
+ constListTypePtr list_type = (constListTypePtr) ycptype;
+ constTypePtr valuetype = list_type->type();
- map->add(key, val);
- }
+ // FIXME this can fail
+ ret = getYCPValueList(&sub, valuetype);
+ mismatch = false;
+ }
+ }
+ else if (ycptype->isMap())
+ {
+ if (type == DBUS_TYPE_ARRAY)
+ {
+ DBusMessageIter sub;
+ dbus_message_iter_recurse(it, &sub);
- dbus_message_iter_next(&sub);
- }
+ constMapTypePtr map_type = (constMapTypePtr) ycptype;
+ constTypePtr keytype = map_type->keytype();
+ constTypePtr valuetype = map_type->valuetype();
- ret = map;
+ ret = getYCPValueMap(&sub, keytype, valuetype);
+ mismatch = false;
}
- else if (ycp_type == "term")
+ }
+ else if (ycptype->isTerm())
+ {
+ // array with first item being the name
+ if (type == DBUS_TYPE_ARRAY)
{
- y2debug("Found an YCPTerm container");
+ DBusMessageIter sub;
+ dbus_message_iter_recurse(it, &sub);
- YCPList term_list;
std::string term_name;
+ YCPList term_list;
- int index = 0;
- while (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID)
+ if (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID)
{
- YCPValue list_val = getYCPValue(&sub);
-
- if (index == 0)
+ YCPValue ytn = getYCPValue(&sub, Type::String);
+ if (!ytn.isNull() && ytn->isString())
{
- if (!list_val.isNull() && list_val->isString())
- {
- term_name = list_val->asString()->value();
- }
- else
- {
- y2error("Expecting string (term name) in the list");
- return YCPVoid();
- }
+ term_name = ytn->asString()->value();
+ dbus_message_iter_next(&sub);
+
+ term_list = getYCPValueList(&sub, Type::Unspec);
+
+ y2debug("Received TERM: name: %s, list: %s", term_name.c_str(), term_list->toString().c_str());
+
+ ret = YCPTerm(term_name, term_list);
+ mismatch = false;
}
else
{
- term_list->add(list_val);
+ y2error("Expecting string (term name) in the list");
+ return YCPVoid(); // FIXME
}
-
- dbus_message_iter_next(&sub);
- index++;
}
-
- y2debug("Received TERM: name: %s, list: %s", term_name.c_str(), term_list->toString().c_str());
-
- YCPTerm term(term_name, term_list);
- ret = term;
}
- else if (ycp_type.empty())
+ }
+ else if (ycptype->isString())
+ {
+ const char *s = getString(it);
+ if (s != NULL)
{
- y2debug("Reading RAW DBus array");
-
- // is the container a map or a list?
- if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_DICT_ENTRY)
+ ret = YCPString(s);
+ mismatch = false;
+ }
+ }
+ else if (ycptype->isSymbol())
+ {
+ const char *s = getString(it);
+ if (s != NULL)
+ {
+ ret = YCPSymbol(s);
+ mismatch = false;
+ }
+ }
+ else if (ycptype->isPath())
+ {
+ const char *s = getString(it);
+ if (s != NULL)
+ {
+ ret = YCPPath(s);
+ mismatch = false;
+ }
+ }
+ // parsed YCP code, wow.
+ //FIXME does the execution precede auth checks?!
+ else if (ycptype->isBlock())
+ {
+ const char *s = getString(it);
+ if (s != NULL)
+ {
+ if (*s == '\0')
{
- y2debug("Found a map");
-
- YCPMap map;
-
- while (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID)
- {
- // is it a map or a list?
- if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_DICT_ENTRY)
- {
- DBusMessageIter mapit;
- dbus_message_iter_recurse(&sub, &mapit);
-
- // read the key without the header
- YCPValue key = getYCPValueRaw(&mapit);
-
- dbus_message_iter_next(&mapit);
-
- // read the value
- YCPValue val = getYCPValueRaw(&mapit);
-
- map->add(key, val);
- }
-
- dbus_message_iter_next(&sub);
- }
-
- ret = map;
+ y2warning("The code block is empty");
+ ret = YCPVoid();
}
else
{
- y2debug("Found a list");
-
- YCPList lst;
+ // parse the string, recreate the YCPBlock again
+ Parser parser(s);
+ parser.setBuffered();
+ YCodePtr p = parser.parse();
- while (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID)
+ if (!p)
{
- YCPValue list_val = getYCPValue(&sub);
- lst->add(list_val);
-
- dbus_message_iter_next(&sub);
+ y2error("Parse error in YCP code: %s", s);
+ ret = YCPVoid();
+ }
+ else
+ {
+ ret = p->isBlock ()? YCPCode (p): p->evaluate (true);
}
-
- ret = lst;
}
+ mismatch = false;
}
- else
- {
- y2error("Unknown container type for DBUS_TYPE_ARRAY: %s", ycp_type.c_str());
- ret = YCPVoid();
- }
- }
- else if (type == DBUS_TYPE_DOUBLE)
- {
- double d;
- dbus_message_iter_get_basic(it, &d);
- ret = YCPFloat(d);
}
- else if (type == DBUS_TYPE_INT64)
+ else
{
- dbus_int64_t i;
- dbus_message_iter_get_basic(it, &i);
- ret = YCPInteger(i);
+ y2error ("Missing code to convert DBus data to YCP type %s",
+ ycptype->toString().c_str());
}
- else if (type == DBUS_TYPE_UINT64)
+
+ if (mismatch)
{
- // warning: YCPInteger is signed!
- dbus_uint64_t i;
- dbus_message_iter_get_basic(it, &i);
- ret = YCPInteger(i);
+ string e = form("Data mismatch, "
+ "expecting YCP type %s, got DBus type %c",
+ ycptype->toString().c_str(), (char)type);
+ throw DBusException(DBUS_ERROR_INVALID_ARGS, e);
}
- else if (type == DBUS_TYPE_INT32)
+
+ return ret;
+}
+
+YCPValue DBusMsg::getYCPValueRawAny(DBusMessageIter *it) const
+{
+ YCPValue ret;
+
+ int type = dbus_message_iter_get_arg_type(it);
+ // TODO support more types
+ if (type == DBUS_TYPE_BOOLEAN)
{
- dbus_int32_t i;
- dbus_message_iter_get_basic(it, &i);
- ret = YCPInteger(i);
+ bool b;
+ dbus_message_iter_get_basic(it, &b);
+ ret = YCPBoolean(b);
}
- else if (type == DBUS_TYPE_UINT32)
+ else if (type == DBUS_TYPE_STRING)
{
- dbus_uint32_t i;
- dbus_message_iter_get_basic(it, &i);
- ret = YCPInteger(i);
+ const char *s;
+ dbus_message_iter_get_basic(it, &s);
+ ret = YCPString(s);
+
}
- else if (type == DBUS_TYPE_INT16)
+ else if (type == DBUS_TYPE_ARRAY)
{
- dbus_int16_t i;
- dbus_message_iter_get_basic(it, &i);
- ret = YCPInteger(i);
+ DBusMessageIter sub;
+ dbus_message_iter_recurse(it, &sub);
+
+ // DBUS_TYPE_ARRAY is used for YCPList and YCPMap
+ y2debug("Reading RAW DBus array");
+
+ // is the container a map or a list?
+ // An empty map is indistinguishable from a list!
+ if (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_DICT_ENTRY)
+ {
+ y2debug("Found a map");
+ ret = getYCPValueMap(&sub, Type::Any, Type::Unspec);
+ }
+ else
+ {
+ y2debug("Found a list");
+
+ YCPList lst;
+
+ while (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID)
+ {
+ YCPValue list_val = getYCPValue(&sub, Type::Unspec);
+ lst->add(list_val);
+
+ dbus_message_iter_next(&sub);
+ }
+
+ ret = lst;
+ }
}
- else if (type == DBUS_TYPE_UINT16)
+ else if (type == DBUS_TYPE_DOUBLE)
{
- dbus_uint16_t i;
- dbus_message_iter_get_basic(it, &i);
- ret = YCPInteger(i);
+ double d;
+ dbus_message_iter_get_basic(it, &d);
+ ret = YCPFloat(d);
}
else if (type == DBUS_TYPE_VARIANT)
{
@@ -933,42 +1027,58 @@
// there should be just one value inside the container
if (dbus_message_iter_get_arg_type (&sub) != DBUS_TYPE_INVALID)
{
- val = getYCPValueRaw(&sub);
+ val = getYCPValueRawAny(&sub);
}
-
+ // FIXME YCPNull possible
ret = val;
}
else
{
- y2error("Unsupported DBus type: %d (%c)", type, (char)type);
- ret = YCPVoid();
+ ret = getYCPValueInteger(it);
+ if (ret.isNull())
+ {
+ string e = form("Unsupported DBus type: %d (%c)", type, (char)type);
+ throw DBusException(DBUS_ERROR_INVALID_ARGS, e);
+ }
}
return ret;
}
-YCPValue DBusMsg::getYCPValue(DBusMessageIter *it) const
+// main getter dispatcher
+YCPValue DBusMsg::getYCPValue(DBusMessageIter *it, constTypePtr ycptype) const
{
int type = dbus_message_iter_get_arg_type(it);
y2debug("Found DBus type: %d (%c)", type, (char)type);
+ YCPValue ret;
if (type != DBUS_TYPE_STRUCT)
{
- YCPValue ret = getYCPValueRaw(it, "");
- if (ret.isNull())
- {
- ret = YCPVoid();
- }
+ if (ycptype->isUnspec())
+ ret = getYCPValueRawAny(it);
+ else
+ ret = getYCPValueRawType(it, ycptype);
- y2milestone("Using RAW dbus value '%s' instead of (bsv) YCPValue structure", ret->toString().c_str());
+// y2milestone("Using RAW dbus value '%s' instead of (bsv) YCPValue structure", ret->toString().c_str());
+ }
+ else
+ ret = getYCPValueBsv(it, ycptype);
- return ret;
+ if (ret.isNull()) // TODO unify
+ {
+ ret = YCPVoid();
}
+ return ret;
+}
+// "it" must point to a struct
+// May throw a DBusException
+YCPValue DBusMsg::getYCPValueBsv(DBusMessageIter *it, constTypePtr ycptype) const
+{
DBusMessageIter struct_iter;
dbus_message_iter_recurse(it, &struct_iter);
- type = dbus_message_iter_get_arg_type(&struct_iter);
+ int type = dbus_message_iter_get_arg_type(&struct_iter);
bool received_nil = false;
// read the nil flag at the beginning
@@ -987,26 +1097,43 @@
}
else
{
- y2error("Missing nil flag in the response");
- return YCPVoid();
+ string e = form("1st field in BSV must be a boolean nil flag (seen '%c')", (char) type);
+ throw DBusException(DBUS_ERROR_INVALID_ARGS, e);
}
// read the data type in the header
dbus_message_iter_next(&struct_iter);
- std::string ycp_type;
+ constTypePtr vycptype = Type::Unspec;
type = dbus_message_iter_get_arg_type(&struct_iter);
if (type == DBUS_TYPE_STRING)
{
const char *str;
dbus_message_iter_get_basic(&struct_iter, &str);
y2debug("HEADER: type: %s", str);
- ycp_type = str;
+
+ std::string ycp_type = str;
+ if (ycp_type == "string" || ycp_type.empty())
+ vycptype = Type::String;
+ else if (ycp_type == "symbol")
+ vycptype = Type::Symbol;
+ else if (ycp_type == "path")
+ vycptype = Type::Path;
+ else if (ycp_type == "list")
+ vycptype = Type::List;
+ else if (ycp_type == "map")
+ vycptype = Type::Map;
+ else if (ycp_type == "block")
+ vycptype = Type::Block;
+ else {
+ string e = form("Dunno how to translate BSV type '%s' to YCP type", str);
+ throw DBusException(DBUS_ERROR_INVALID_SIGNATURE, e);
+ }
}
else
{
- y2error("Missing datatype flag in the response");
- return YCPVoid();
+ string e = form("2nd field in BSV must be a string YCP type name (seen %d, '%c')", type, (char) type);
+ throw DBusException(DBUS_ERROR_INVALID_ARGS, e);
}
// read the YCP value in the variant container
@@ -1016,19 +1143,20 @@
if (type != DBUS_TYPE_VARIANT)
{
- y2error("Expecting VARIANT type in the response");
- return YCPVoid();
+ string e = form("3rd field in BSV must be a variant payload (seen %d, '%c')", type, (char) type);
+ throw DBusException(DBUS_ERROR_INVALID_ARGS, e);
}
DBusMessageIter variant_iter;
dbus_message_iter_recurse(&struct_iter, &variant_iter);
- YCPValue ret = getYCPValueRaw(&variant_iter, ycp_type);
+ YCPValue ret = getYCPValueRawType(&variant_iter, vycptype);
return (received_nil) ? YCPVoid() : ret;
}
-YCPValue DBusMsg::getYCPValue(int index) const
+// the public getter: idx
+YCPValue DBusMsg::getYCPValue(int index, constTypePtr ycptype) const
{
YCPValue ret = YCPNull();
@@ -1046,6 +1174,7 @@
int i = 0;
// iterate over the other arguments
+//wasteful API?
while (i < index && dbus_message_iter_next(&it))
{
i++;
@@ -1053,7 +1182,7 @@
if (i == index)
{
- ret = getYCPValue(&it);
+ ret = getYCPValue(&it, ycptype);
}
else
{
Modified: trunk/core/liby2dbus/src/DBusMsg.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/core/liby2dbus/src/DBusMsg.h?rev=58020&r1=58019&r2=58020&view=diff
==============================================================================
--- trunk/core/liby2dbus/src/DBusMsg.h (original)
+++ trunk/core/liby2dbus/src/DBusMsg.h Fri Jul 10 15:25:08 2009
@@ -1,4 +1,3 @@
-
/*
DBusMsg
*/
@@ -12,6 +11,8 @@
#include
class YCPValue;
+class YCPList;
+class YCPMap;
// DBusMessage wrapper
class DBusMsg
@@ -41,13 +42,14 @@
bool addString(const std::string &val);
bool addInt64(dbus_int64_t val);
bool addInt32(dbus_int32_t val);
- bool addBoolean(bool val);
+ bool addBoolean(dbus_bool_t val);
bool addDouble(double val);
bool addYCPValue(const YCPValue &val);
bool addValueAs(const YCPValue &val, constTypePtr rettype = NULL);
- YCPValue getYCPValue(int index) const;
+ // ycptype may be Type::Any
+ YCPValue getYCPValue(int index, constTypePtr ycptype) const;
bool isMethodCall(const std::string &interface, const std::string &method) const;
int arguments() const;
@@ -78,8 +80,27 @@
int typeInt(const YCPValue &val) const;
std::string typeStr(const YCPValue &val, bool bsv_enc = true) const;
- YCPValue getYCPValue(DBusMessageIter *it) const;
- YCPValue getYCPValueRaw(DBusMessageIter *it, const std::string &ycp_type = std::string()) const;
+ YCPValue getYCPValue(DBusMessageIter *it, constTypePtr ycptype) const;
+ YCPValue getYCPValueRawType(DBusMessageIter *it, constTypePtr ycptype) const;
+ YCPValue getYCPValueRawAny(DBusMessageIter *it) const;
+ YCPValue getYCPValueBsv(DBusMessageIter *it, constTypePtr ycptype) const;
+
+ const char * getString(DBusMessageIter *it) const;
+ YCPList getYCPValueList(DBusMessageIter *it, constTypePtr valuetype) const;
+ YCPMap getYCPValueMap(DBusMessageIter *it, constTypePtr keytype, constTypePtr valuetype) const;
+ YCPValue getYCPValueInteger(DBusMessageIter *it) const;
+
+};
+
+class DBusException
+{
+ std::string m_name;
+ std::string m_message;
+public:
+ DBusException(const std::string& name, const std::string& message)
+ :m_name(name), m_message(message) {}
+ std::string name() const { return m_name; }
+ std::string message() const { return m_message; }
};
class SignatureException : std::exception
@@ -89,4 +110,3 @@
};
#endif
-
Modified: trunk/core/liby2dbus/src/DBusServerBase.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/core/liby2dbus/src/DBusServerBase.cc?rev=58020&r1=58019&r2=58020&view=diff
==============================================================================
--- trunk/core/liby2dbus/src/DBusServerBase.cc (original)
+++ trunk/core/liby2dbus/src/DBusServerBase.cc Fri Jul 10 15:25:08 2009
@@ -474,12 +474,14 @@
// check the policy here
if (policykit.isDBusUserAuthorized(*it, msg.sender(), connection.getConnection(), err))
{
- y2security("User is authorized to do action %s", it->c_str());
+ y2security("User %s is authorized to do action %s",
+ msg.sender().c_str(), it->c_str());
return true;
}
else
{
- y2security("User is NOT authorized to do action %s", it->c_str());
+ y2security("User %s is NOT authorized to do action %s",
+ msg.sender().c_str(), it->c_str());
}
}
Modified: trunk/core/liby2dbus/src/DBusServerBase.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/core/liby2dbus/src/DBusServerBase.h?rev=58020&r1=58019&r2=58020&view=diff
==============================================================================
--- trunk/core/liby2dbus/src/DBusServerBase.h (original)
+++ trunk/core/liby2dbus/src/DBusServerBase.h Fri Jul 10 15:25:08 2009
@@ -56,6 +56,7 @@
virtual actionList createActionId(const DBusMsg &msg);
// handle unknown requests
+ // Some servers will try to autoload and retry
virtual DBusMsg unknownRequest(const DBusMsg &request);
std::string service_name;
Modified: trunk/core/package/yast2-core.changes
URL: http://svn.opensuse.org/viewcvs/yast/trunk/core/package/yast2-core.changes?rev=58020&r1=58019&r2=58020&view=diff
==============================================================================
--- trunk/core/package/yast2-core.changes (original)
+++ trunk/core/package/yast2-core.changes Fri Jul 10 15:25:08 2009
@@ -1,4 +1,15 @@
-------------------------------------------------------------------
+Thu Jul 2 17:02:39 CEST 2009 - mvidner@suse.cz
+
+- Enhanced DBus -> YCP value conversion by considering
+ also the expected YCP type.
+ Otherwise it is impossible to tell whether an empty array
+ should become an empty map or an empty list (bnc#516492).
+- Removed the dependency on dbus-1-x11
+ by calling dbus-daemon directly without dbus-launch.
+- 2.18.15
+
+-------------------------------------------------------------------
Fri Jun 26 14:52:05 CEST 2009 - mvidner@suse.cz
- yast_modules_dbus_server: return org.freedesktop.DBus.Error.UnknownMethod
Modified: trunk/core/yast2-core.spec.in
URL: http://svn.opensuse.org/viewcvs/yast/trunk/core/yast2-core.spec.in?rev=58020&r1=58019&r2=58020&view=diff
==============================================================================
--- trunk/core/yast2-core.spec.in (original)
+++ trunk/core/yast2-core.spec.in Fri Jul 10 15:25:08 2009
@@ -25,7 +25,9 @@
BuildRequires: libxcrypt-devel
# for SCR DBus service
-BuildRequires: dbus-1-devel dbus-1-x11 PolicyKit-devel
+BuildRequires: dbus-1-devel PolicyKit-devel
+# for DBus testing
+BuildRecommends: python-base dbus-1-python
Summary: YaST2 - Core Libraries
Requires: perl = %{perl_version}
--
To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org
For additional commands, e-mail: yast-commit+help@opensuse.org