16714dbc236bf5dccba6778aa83223ee8555a6157Ying Wang/*
26714dbc236bf5dccba6778aa83223ee8555a6157Ying Wang * dhcpcd - DHCP client daemon
32ce495a0a7986fcd458954f1cae8cd1b030091d0Ying Wang * Copyright (c) 2006-2015 Roy Marples <roy@marples.name>
42ce495a0a7986fcd458954f1cae8cd1b030091d0Ying Wang * All rights reserved
52ce495a0a7986fcd458954f1cae8cd1b030091d0Ying Wang
688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * Redistribution and use in source and binary forms, with or without
788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * modification, are permitted provided that the following conditions
888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * are met:
988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
102ce495a0a7986fcd458954f1cae8cd1b030091d0Ying Wang *    notice, this list of conditions and the following disclaimer.
1188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
1288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
1388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project *    documentation and/or other materials provided with the distribution.
1488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project *
1552d697d432e0684fb13884c94f7768c5ec8ef8ecDavid 'Digit' Turner * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1652d697d432e0684fb13884c94f7768c5ec8ef8ecDavid 'Digit' Turner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1752d697d432e0684fb13884c94f7768c5ec8ef8ecDavid 'Digit' Turner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1852d697d432e0684fb13884c94f7768c5ec8ef8ecDavid 'Digit' Turner * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1952d697d432e0684fb13884c94f7768c5ec8ef8ecDavid 'Digit' Turner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2052d697d432e0684fb13884c94f7768c5ec8ef8ecDavid 'Digit' Turner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2152d697d432e0684fb13884c94f7768c5ec8ef8ecDavid 'Digit' Turner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * SUCH DAMAGE.
2688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project */
2788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
2888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#include <arpa/inet.h>
2988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
3088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#include <ctype.h>
3188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#include <stdlib.h>
3288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#include <stdio.h>
3388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#include <string.h>
3488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#include <syslog.h>
3588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
3688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#include <dbus/dbus.h>
3788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
3888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#include "../config.h"
3988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#include "dbus-dict.h"
4076bf62d75e7d4680dac1522534c56f4b511e5cd1Raphael
4176bf62d75e7d4680dac1522534c56f4b511e5cd1Raphaelstatic dbus_bool_t
4276bf62d75e7d4680dac1522534c56f4b511e5cd1Raphaelappend_sanitized_string(DBusMessageIter *iter, const char *value)
432b537262fe884c11d7d27d208896a0849e72bd73synergydev{
4488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project	dbus_bool_t ret;
4588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project	int len = strlen(value);
462b537262fe884c11d7d27d208896a0849e72bd73synergydev	char *sanitized_value = NULL;
475d4bcb490e4261ab56d188cc5ac490af9cc4c826Jean-Baptiste Queru	int i;
4888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
4988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project	for (i = 0; i < len; i++) {
5088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		if (isascii(value[i]) || isprint(value[i])) {
5176bf62d75e7d4680dac1522534c56f4b511e5cd1Raphael			if (sanitized_value)
5288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project				sanitized_value[i] = value[i];
539ccacd7a6f27dbb38c8365b85fb07197d1fdbb29Ying Wang		} else {
549ccacd7a6f27dbb38c8365b85fb07197d1fdbb29Ying Wang			if (sanitized_value == NULL) {
559ccacd7a6f27dbb38c8365b85fb07197d1fdbb29Ying Wang				sanitized_value = malloc(len + 1);
569ccacd7a6f27dbb38c8365b85fb07197d1fdbb29Ying Wang				if (sanitized_value == NULL) {
579ccacd7a6f27dbb38c8365b85fb07197d1fdbb29Ying Wang					syslog(LOG_ERR, "DBus string parameter "
5888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project					       "sanitization failed due to "
5988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project					       "malloc failure");
6088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project					return FALSE;
6188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project				}
6288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project				memcpy(sanitized_value, value, i);
6388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project			}
64da12daf15f2e6aef7e94f340d23bc435ddc025f4Joe Onorato			sanitized_value[i] = '?';
6588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		}
6688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project	}
6788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project	if (sanitized_value) {
6877dc0a58e27fe7c3fcdb67bbee71010c59dd4344Joe Onorato		syslog(LOG_ERR, "DBus string parameter sanitization"
6977dc0a58e27fe7c3fcdb67bbee71010c59dd4344Joe Onorato                       " was invoked");
7077dc0a58e27fe7c3fcdb67bbee71010c59dd4344Joe Onorato		sanitized_value[i] = '\0';
7177dc0a58e27fe7c3fcdb67bbee71010c59dd4344Joe Onorato		ret = dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
72ad7fd29b312bf588b2be3f799715f34ff8a6d46bYing Wang	            &sanitized_value);
73ad7fd29b312bf588b2be3f799715f34ff8a6d46bYing Wang
74ad7fd29b312bf588b2be3f799715f34ff8a6d46bYing Wang		free(sanitized_value);
75ad7fd29b312bf588b2be3f799715f34ff8a6d46bYing Wang	} else {
76ad7fd29b312bf588b2be3f799715f34ff8a6d46bYing Wang		ret = dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
77ad7fd29b312bf588b2be3f799715f34ff8a6d46bYing Wang	            &value);
78ad7fd29b312bf588b2be3f799715f34ff8a6d46bYing Wang	}
79ad7fd29b312bf588b2be3f799715f34ff8a6d46bYing Wang
80ad7fd29b312bf588b2be3f799715f34ff8a6d46bYing Wang	return ret;
81ad7fd29b312bf588b2be3f799715f34ff8a6d46bYing Wang}
82ad7fd29b312bf588b2be3f799715f34ff8a6d46bYing Wang
83ad7fd29b312bf588b2be3f799715f34ff8a6d46bYing Wangstatic int
84ad7fd29b312bf588b2be3f799715f34ff8a6d46bYing Wangappend_config_value(DBusMessageIter *entry, int type,
85ad7fd29b312bf588b2be3f799715f34ff8a6d46bYing Wang    const char *data)
86ad7fd29b312bf588b2be3f799715f34ff8a6d46bYing Wang{
87ad7fd29b312bf588b2be3f799715f34ff8a6d46bYing Wang	int retval;
889566122c9d6b0c4844563f3af9185adf082c6155Daniel Sandler	DBusMessageIter var;
899566122c9d6b0c4844563f3af9185adf082c6155Daniel Sandler	unsigned char byte;
909566122c9d6b0c4844563f3af9185adf082c6155Daniel Sandler	dbus_uint16_t u16;
9188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project	dbus_uint32_t u32;
9288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project	dbus_int16_t i16;
9388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project	dbus_int32_t i32;
9488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project	struct in_addr in;
9502e31d240a9044b54ee793902ad958894f84e7a1Colin Cross
9602e31d240a9044b54ee793902ad958894f84e7a1Colin Cross	retval = -1;
9750e52fa11e802b4b4a8bf83072323ee48a75436dYing Wang	switch (type) {
9888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project	case DBUS_TYPE_BOOLEAN:
9988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		if (*data == '0' || *data == '\0')
10088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project			u32 = 0;
10188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		else
10288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project			u32 = 1;
10363d94fa3056066ba7be6754356975af6a1c82981Ying Wang		dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
10463d94fa3056066ba7be6754356975af6a1c82981Ying Wang		    DBUS_TYPE_BOOLEAN_AS_STRING, &var);
10563d94fa3056066ba7be6754356975af6a1c82981Ying Wang		if (dbus_message_iter_append_basic(&var,
106e35a445f2f7b32e39d88e0ba58b120aae6807bafJoe Onorato			DBUS_TYPE_BOOLEAN, &u32))
1071de66889ec97300eb92166e849c4f9251e0290c6Joe Onorato			retval = 0;
1081de66889ec97300eb92166e849c4f9251e0290c6Joe Onorato		break;
1091de66889ec97300eb92166e849c4f9251e0290c6Joe Onorato	case DBUS_TYPE_BYTE:
1101de66889ec97300eb92166e849c4f9251e0290c6Joe Onorato		byte = strtoul(data, NULL, 0);
1111de66889ec97300eb92166e849c4f9251e0290c6Joe Onorato		dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
11288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		    DBUS_TYPE_BYTE_AS_STRING, &var);
11388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		if (dbus_message_iter_append_basic(&var, DBUS_TYPE_BYTE,
11488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project			&byte))
11588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project			retval = 0;
11688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		break;
11788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project	case DBUS_TYPE_STRING:
11888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
11988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		    DBUS_TYPE_STRING_AS_STRING, &var);
12088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		if (append_sanitized_string(&var, data))
12188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project			retval = 0;
12288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		break;
12388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project	case DBUS_TYPE_INT16:
12488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		i16 = strtol(data, NULL, 0);
12588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
12688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		    DBUS_TYPE_INT16_AS_STRING, &var);
12788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		if (dbus_message_iter_append_basic(&var,
12888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project			DBUS_TYPE_INT16, &i16))
12988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project			retval = 0;
13088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		break;
13188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project	case DBUS_TYPE_UINT16:
13288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		u16 = strtoul(data, NULL, 0);
13388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
13488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		    DBUS_TYPE_UINT16_AS_STRING, &var);
13588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		if (dbus_message_iter_append_basic(&var,
13688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project			DBUS_TYPE_UINT16, &u16))
13788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project			retval = 0;
13888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		break;
13988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project	case DBUS_TYPE_INT32:
14088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		i32 = strtol(data, NULL, 0);
14188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
14288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		    DBUS_TYPE_INT32_AS_STRING, &var);
143e2d27887bef08b9c3297e765d32397c1a8f7df87Narayan Kamath		if (dbus_message_iter_append_basic(&var,
144e2d27887bef08b9c3297e765d32397c1a8f7df87Narayan Kamath			DBUS_TYPE_INT32, &i32))
145e2d27887bef08b9c3297e765d32397c1a8f7df87Narayan Kamath			retval = 0;
146e2d27887bef08b9c3297e765d32397c1a8f7df87Narayan Kamath		break;
147e2d27887bef08b9c3297e765d32397c1a8f7df87Narayan Kamath	case DBUS_TYPE_UINT32:
148e2d27887bef08b9c3297e765d32397c1a8f7df87Narayan Kamath		if (strchr(data, '.') != NULL && inet_aton(data, &in) == 1)
149e2d27887bef08b9c3297e765d32397c1a8f7df87Narayan Kamath			u32 = in.s_addr;
150e2d27887bef08b9c3297e765d32397c1a8f7df87Narayan Kamath		else
151e2d27887bef08b9c3297e765d32397c1a8f7df87Narayan Kamath			u32 = strtoul(data, NULL, 0);
152e2d27887bef08b9c3297e765d32397c1a8f7df87Narayan Kamath		dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT,
153e2d27887bef08b9c3297e765d32397c1a8f7df87Narayan Kamath		    DBUS_TYPE_UINT32_AS_STRING, &var);
1548d45e51803c0ca5194b07e493cb231e3a52db2caYing Wang		if (dbus_message_iter_append_basic(&var,
1558d45e51803c0ca5194b07e493cb231e3a52db2caYing Wang			DBUS_TYPE_UINT32, &u32))
1568d45e51803c0ca5194b07e493cb231e3a52db2caYing Wang			retval = 0;
1578d45e51803c0ca5194b07e493cb231e3a52db2caYing Wang		break;
158e2d27887bef08b9c3297e765d32397c1a8f7df87Narayan Kamath	default:
159d5fb7826823fa3fb45f8f06c9c1a781dd60210f8Narayan Kamath		retval = 1;
160d5fb7826823fa3fb45f8f06c9c1a781dd60210f8Narayan Kamath		break;
1618d45e51803c0ca5194b07e493cb231e3a52db2caYing Wang	}
162ad6909913145ba3daeb037f0170b95f855f7d08fYing Wang	if (retval == 0)
163e2d27887bef08b9c3297e765d32397c1a8f7df87Narayan Kamath		dbus_message_iter_close_container(entry, &var);
164e2d27887bef08b9c3297e765d32397c1a8f7df87Narayan Kamath	else if (retval == 1)
1650cf57dc99f7040a96e8d3da646adace12bcb58c7Brian Carlstrom		retval = 0;
1668d45e51803c0ca5194b07e493cb231e3a52db2caYing Wang
167e2d27887bef08b9c3297e765d32397c1a8f7df87Narayan Kamath	return retval;
168e2d27887bef08b9c3297e765d32397c1a8f7df87Narayan Kamath}
169ad6909913145ba3daeb037f0170b95f855f7d08fYing Wang
170ad6909913145ba3daeb037f0170b95f855f7d08fYing Wangstatic int
171ad6909913145ba3daeb037f0170b95f855f7d08fYing Wangappend_config_byte_array(DBusMessageIter *entry, const char *data)
172e2d27887bef08b9c3297e765d32397c1a8f7df87Narayan Kamath{
1738d45e51803c0ca5194b07e493cb231e3a52db2caYing Wang	DBusMessageIter var, array;
174304f5194fdfd999a5e8bceef1ff260958b041d52Tim Roes	dbus_bool_t ok = TRUE;
175304f5194fdfd999a5e8bceef1ff260958b041d52Tim Roes	uint8_t u8, u8_2;
176304f5194fdfd999a5e8bceef1ff260958b041d52Tim Roes	size_t len;
177304f5194fdfd999a5e8bceef1ff260958b041d52Tim Roes	const char *it, *end;
178304f5194fdfd999a5e8bceef1ff260958b041d52Tim Roes	const char *tsa, *ts;
179304f5194fdfd999a5e8bceef1ff260958b041d52Tim Roes
180304f5194fdfd999a5e8bceef1ff260958b041d52Tim Roes	tsa = DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING;
181304f5194fdfd999a5e8bceef1ff260958b041d52Tim Roes	ts = DBUS_TYPE_BYTE_AS_STRING;
182ad6909913145ba3daeb037f0170b95f855f7d08fYing Wang
183e2d27887bef08b9c3297e765d32397c1a8f7df87Narayan Kamath	dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT, tsa, &var);
184ad6909913145ba3daeb037f0170b95f855f7d08fYing Wang	dbus_message_iter_open_container(&var, DBUS_TYPE_ARRAY, ts, &array);
185ad6909913145ba3daeb037f0170b95f855f7d08fYing Wang
186e2d27887bef08b9c3297e765d32397c1a8f7df87Narayan Kamath	len = strlen(data);
187e2d27887bef08b9c3297e765d32397c1a8f7df87Narayan Kamath	it = data;
188e2d27887bef08b9c3297e765d32397c1a8f7df87Narayan Kamath	end = data + len;
189d5fb7826823fa3fb45f8f06c9c1a781dd60210f8Narayan Kamath
1908d45e51803c0ca5194b07e493cb231e3a52db2caYing Wang	/* "a12" is treated as "0a12" */
1918d45e51803c0ca5194b07e493cb231e3a52db2caYing Wang	if (len & 1) {
192e2d27887bef08b9c3297e765d32397c1a8f7df87Narayan Kamath		ok = (sscanf(it++, "%1hhx", &u8) == 1) &&
193e2d27887bef08b9c3297e765d32397c1a8f7df87Narayan Kamath			dbus_message_iter_append_basic(&array, DBUS_TYPE_BYTE,
194d5fb7826823fa3fb45f8f06c9c1a781dd60210f8Narayan Kamath						       &u8);
1958d45e51803c0ca5194b07e493cb231e3a52db2caYing Wang	}
1968d45e51803c0ca5194b07e493cb231e3a52db2caYing Wang
197e2d27887bef08b9c3297e765d32397c1a8f7df87Narayan Kamath	while (ok && it < end) {
198ad6909913145ba3daeb037f0170b95f855f7d08fYing Wang		/* sscanf("1z", "%2hhx", &u8) will store 0x01 in u8 and
1999d9f367895655411c42123177ae1c32f104b3c01Joe Onorato		 * will return 1 */
2009d9f367895655411c42123177ae1c32f104b3c01Joe Onorato		ok = (sscanf(it++, "%1hhx", &u8) == 1) &&
2019d9f367895655411c42123177ae1c32f104b3c01Joe Onorato			(sscanf(it++, "%1hhx", &u8_2) == 1);
2029d9f367895655411c42123177ae1c32f104b3c01Joe Onorato		if (!ok)
2039d9f367895655411c42123177ae1c32f104b3c01Joe Onorato			break;
2048d45e51803c0ca5194b07e493cb231e3a52db2caYing Wang
205ad6909913145ba3daeb037f0170b95f855f7d08fYing Wang		u8 = (u8 << 4) | u8_2;
2069d9f367895655411c42123177ae1c32f104b3c01Joe Onorato		ok = dbus_message_iter_append_basic(&array, DBUS_TYPE_BYTE, &u8);
2079d9f367895655411c42123177ae1c32f104b3c01Joe Onorato	}
2085d4bcb490e4261ab56d188cc5ac490af9cc4c826Jean-Baptiste Queru
2099d9f367895655411c42123177ae1c32f104b3c01Joe Onorato	dbus_message_iter_close_container(&var, &array);
2104a1c70e53be40fd1b2c14eb7c0acc93f6df865bcJeff Hamilton	dbus_message_iter_close_container(entry, &var);
2119d9f367895655411c42123177ae1c32f104b3c01Joe Onorato	return ok ? 0 : -1;
2129d9f367895655411c42123177ae1c32f104b3c01Joe Onorato}
2139d9f367895655411c42123177ae1c32f104b3c01Joe Onorato
2149d9f367895655411c42123177ae1c32f104b3c01Joe Onoratostatic int
2159d9f367895655411c42123177ae1c32f104b3c01Joe Onoratoappend_config_array(DBusMessageIter *entry, int type, const char *data)
2169d9f367895655411c42123177ae1c32f104b3c01Joe Onorato{
2179d9f367895655411c42123177ae1c32f104b3c01Joe Onorato	int retval;
2189d9f367895655411c42123177ae1c32f104b3c01Joe Onorato	char *ns, *p, *tok;
2198d45e51803c0ca5194b07e493cb231e3a52db2caYing Wang	const char *tsa, *ts;
220d5fb7826823fa3fb45f8f06c9c1a781dd60210f8Narayan Kamath	DBusMessageIter var, array;
2219d9f367895655411c42123177ae1c32f104b3c01Joe Onorato	dbus_bool_t ok;
2229d9f367895655411c42123177ae1c32f104b3c01Joe Onorato	dbus_uint32_t u32;
2235d4bcb490e4261ab56d188cc5ac490af9cc4c826Jean-Baptiste Queru	struct in_addr in;
2249d9f367895655411c42123177ae1c32f104b3c01Joe Onorato
2254a1c70e53be40fd1b2c14eb7c0acc93f6df865bcJeff Hamilton	if (type == DBUS_TYPE_BYTE)
2269d9f367895655411c42123177ae1c32f104b3c01Joe Onorato		return append_config_byte_array(entry, data);
2279d9f367895655411c42123177ae1c32f104b3c01Joe Onorato
2288d45e51803c0ca5194b07e493cb231e3a52db2caYing Wang	switch (type) {
229b036e955fcd9e5fd15ec37b208e112147641dd7aYing Wang	case DBUS_TYPE_STRING:
230478ba5e3f00bb1321cd022d744020231f2449287Ying Wang		tsa = DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING;
2311dcca61869ed1291879332e13771b13805ec4475Andrew Hsieh		ts = DBUS_TYPE_STRING_AS_STRING;
232478ba5e3f00bb1321cd022d744020231f2449287Ying Wang		break;
233478ba5e3f00bb1321cd022d744020231f2449287Ying Wang	case DBUS_TYPE_UINT32:
234478ba5e3f00bb1321cd022d744020231f2449287Ying Wang		tsa = DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_UINT32_AS_STRING;
235e35a445f2f7b32e39d88e0ba58b120aae6807bafJoe Onorato		ts = DBUS_TYPE_UINT32_AS_STRING;
236e35a445f2f7b32e39d88e0ba58b120aae6807bafJoe Onorato		break;
237e35a445f2f7b32e39d88e0ba58b120aae6807bafJoe Onorato	default:
238e35a445f2f7b32e39d88e0ba58b120aae6807bafJoe Onorato		return -1;
23974e883d1415f68dc52a7e679cd1ea1f486b8d8bbJoe Onorato	}
24074e883d1415f68dc52a7e679cd1ea1f486b8d8bbJoe Onorato
24174e883d1415f68dc52a7e679cd1ea1f486b8d8bbJoe Onorato	ns = p = strdup(data);
24274e883d1415f68dc52a7e679cd1ea1f486b8d8bbJoe Onorato	if (ns == NULL)
2437d8c535c1f63a97a9b77fa0b5d530778640a241cYing Wang		return -1;
2447d8c535c1f63a97a9b77fa0b5d530778640a241cYing Wang	retval = 0;
2457d8c535c1f63a97a9b77fa0b5d530778640a241cYing Wang
246b036e955fcd9e5fd15ec37b208e112147641dd7aYing Wang	dbus_message_iter_open_container(entry, DBUS_TYPE_VARIANT, tsa, &var);
247478ba5e3f00bb1321cd022d744020231f2449287Ying Wang	dbus_message_iter_open_container(&var, DBUS_TYPE_ARRAY, ts, &array);
2481de66889ec97300eb92166e849c4f9251e0290c6Joe Onorato	while ((tok = strsep(&p, " ")) != NULL) {
2491de66889ec97300eb92166e849c4f9251e0290c6Joe Onorato		if (*tok == '\0')
250b036e955fcd9e5fd15ec37b208e112147641dd7aYing Wang			continue;
251e35a445f2f7b32e39d88e0ba58b120aae6807bafJoe Onorato		switch(type) {
2521de66889ec97300eb92166e849c4f9251e0290c6Joe Onorato		case DBUS_TYPE_STRING:
2531de66889ec97300eb92166e849c4f9251e0290c6Joe Onorato			ok = append_sanitized_string(&array, tok);
25488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project			break;
25588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		case DBUS_TYPE_UINT32:
25688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project			if (strchr(tok, '.') != NULL &&
25731268316213d25b73288bee58cef686ba45640c9Ying Wang			    inet_aton(tok, &in) == 1)
258015edd2c1b4a4300ccccee4036ec2ca7e9ad798aYing Wang				u32 = in.s_addr;
259015edd2c1b4a4300ccccee4036ec2ca7e9ad798aYing Wang			else
260015edd2c1b4a4300ccccee4036ec2ca7e9ad798aYing Wang				u32 = strtoul(tok, NULL, 0);
261015edd2c1b4a4300ccccee4036ec2ca7e9ad798aYing Wang			ok = dbus_message_iter_append_basic(&array,
262015edd2c1b4a4300ccccee4036ec2ca7e9ad798aYing Wang			    DBUS_TYPE_UINT32, &u32);
263015edd2c1b4a4300ccccee4036ec2ca7e9ad798aYing Wang			break;
264015edd2c1b4a4300ccccee4036ec2ca7e9ad798aYing Wang		default:
265015edd2c1b4a4300ccccee4036ec2ca7e9ad798aYing Wang			ok = FALSE;
266015edd2c1b4a4300ccccee4036ec2ca7e9ad798aYing Wang			break;
267015edd2c1b4a4300ccccee4036ec2ca7e9ad798aYing Wang		}
268015edd2c1b4a4300ccccee4036ec2ca7e9ad798aYing Wang		if (!ok)
269015edd2c1b4a4300ccccee4036ec2ca7e9ad798aYing Wang			break;
270015edd2c1b4a4300ccccee4036ec2ca7e9ad798aYing Wang	}
271015edd2c1b4a4300ccccee4036ec2ca7e9ad798aYing Wang	dbus_message_iter_close_container(&var, &array);
272015edd2c1b4a4300ccccee4036ec2ca7e9ad798aYing Wang	dbus_message_iter_close_container(entry, &var);
273015edd2c1b4a4300ccccee4036ec2ca7e9ad798aYing Wang	free(ns);
27488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project	return retval;
275af4800c8a6a9266ceb7269bd2c6b0bb2f0965beaYing Wang}
276af4800c8a6a9266ceb7269bd2c6b0bb2f0965beaYing Wang
277af4800c8a6a9266ceb7269bd2c6b0bb2f0965beaYing Wangint
278af4800c8a6a9266ceb7269bd2c6b0bb2f0965beaYing Wangdict_append_config_item(DBusMessageIter *iter, const struct o_dbus *op,
279af4800c8a6a9266ceb7269bd2c6b0bb2f0965beaYing Wang    const char *data)
28088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project{
28188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project	int retval;
28288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project	DBusMessageIter entry;
283e7874c430895b9a4e631c89f1e7729da9264d167Ying Wang
284e7874c430895b9a4e631c89f1e7729da9264d167Ying Wang	retval = 0;
285e7874c430895b9a4e631c89f1e7729da9264d167Ying Wang	if (*data == '\0')
2866a185e453d423a8192f7b694cb0c707f9ec6c94bJoe Onorato		return retval;
28788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project	dbus_message_iter_open_container(iter,
28888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project	    DBUS_TYPE_DICT_ENTRY,
289d0244b395a583804137cd1fe2bff4f86d66b396bYing Wang	    NULL,
290d0244b395a583804137cd1fe2bff4f86d66b396bYing Wang	    &entry);
29188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project	append_sanitized_string(&entry, op->name);
29288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project	if (op->type == DBUS_TYPE_ARRAY)
29388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		retval = append_config_array(&entry, op->sub_type, data);
29488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project	else
29588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project		retval = append_config_value(&entry, op->type, data);
29688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project	dbus_message_iter_close_container(iter, &entry);
29788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project	return retval;
2982f31293ba78695cb48ac5a1cab835197ace58d47The Android Open Source Project}
2992f31293ba78695cb48ac5a1cab835197ace58d47The Android Open Source Project