diff options
| -rw-r--r-- | configure.ac | 16 | ||||
| -rw-r--r-- | dev/Makefile.am | 14 | ||||
| -rw-r--r-- | dev/ideviceclient.c | 9 | ||||
| -rw-r--r-- | include/libimobiledevice/installation_proxy.h | 3 | ||||
| -rw-r--r-- | include/libimobiledevice/mobilesync.h | 3 | ||||
| -rw-r--r-- | src/Makefile.am | 4 | ||||
| -rw-r--r-- | src/afc.c | 28 | ||||
| -rw-r--r-- | src/afc.h | 16 | ||||
| -rw-r--r-- | src/debug.c | 3 | ||||
| -rw-r--r-- | src/debug.h | 17 | ||||
| -rw-r--r-- | src/house_arrest.h | 2 | ||||
| -rw-r--r-- | src/lockdown.c | 5 | ||||
| -rw-r--r-- | src/mobilesync.c | 1 | ||||
| -rw-r--r-- | src/property_list_service.c | 5 | ||||
| -rw-r--r-- | src/restore.c | 1 | ||||
| -rw-r--r-- | src/userpref.c | 492 | ||||
| -rw-r--r-- | src/userpref.h | 19 | ||||
| -rw-r--r-- | tools/Makefile.am | 18 | ||||
| -rw-r--r-- | tools/ideviceimagemounter.c | 25 | ||||
| -rw-r--r-- | tools/ideviceinfo.c | 66 | ||||
| -rw-r--r-- | tools/idevicepair.c | 3 | ||||
| -rw-r--r-- | tools/idevicesyslog.c | 3 | 
22 files changed, 583 insertions, 170 deletions
| diff --git a/configure.ac b/configure.ac index 5078afd..98b0008 100644 --- a/configure.ac +++ b/configure.ac @@ -27,12 +27,15 @@ AC_PROG_LIBTOOL  # Checks for libraries.  PKG_CHECK_MODULES(libusbmuxd, libusbmuxd >= 0.1.4) -PKG_CHECK_MODULES(libglib2, glib-2.0 >= 2.14.1)  PKG_CHECK_MODULES(libgnutls, gnutls >= 2.2.0)  PKG_CHECK_MODULES(libtasn1, libtasn1 >= 1.1)  PKG_CHECK_MODULES(libplist, libplist >= 0.15)  PKG_CHECK_MODULES(libplistmm, libplist++ >= 0.15)  AC_CHECK_LIB(gcrypt, gcry_control, [AC_SUBST(libgcrypt_LIBS,[-lgcrypt])], [AC_MSG_ERROR([libgcrypt is required to build libimobiledevice])]) +AC_CHECK_LIB(pthread, [pthread_create, pthread_mutex_lock], [AC_SUBST(libpthread_LIBS,[-lpthread])], [AC_MSG_ERROR([libpthread is required to build libimobiledevice])]) + +PKG_CHECK_MODULES(libglib2, glib-2.0 >= 2.14.1, enable_glib2=yes, enable_glib2=no) +AM_CONDITIONAL([HAVE_GLIB2],[test "x$enable_glib2" == "xyes"])  # Checks for header files.  AC_HEADER_STDC @@ -51,6 +54,17 @@ AC_FUNC_MALLOC  AC_FUNC_REALLOC  AC_CHECK_FUNCS([strcasecmp strdup strerror strndup]) +AC_DEFINE(LITTLE_ENDIAN,0,[little endian]) +AC_DEFINE(BIG_ENDIAN,1,[big endian]) +AC_C_BIGENDIAN([ac_cv_c_bigendian="yes"], [ac_cv_c_bigendian="no"], [], []) +if test "x$ac_cv_c_bigendian" = "xyes"; then +    AC_DEFINE(BYTE_ORDER,1,[big endian byte order]) +else +    AC_DEFINE(BYTE_ORDER,0,[little endian byte order]) +fi + + +  AC_ARG_WITH([swig],              [AS_HELP_STRING([--without-swig],              [build Python bindings using swig (default is yes)])], diff --git a/dev/Makefile.am b/dev/Makefile.am index 72c00a3..c1d2b45 100644 --- a/dev/Makefile.am +++ b/dev/Makefile.am @@ -1,10 +1,14 @@  AM_CPPFLAGS = -I$(top_srcdir)/include -AM_CFLAGS = $(GLOBAL_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(LFS_CFLAGS) -AM_LDFLAGS = $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) +AM_CFLAGS = $(GLOBAL_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(LFS_CFLAGS) +AM_LDFLAGS = $(libgnutls_LIBS) $(libtasn1_LIBS) $(libpthread_LIBS)  if ENABLE_DEVTOOLS -noinst_PROGRAMS = ideviceclient lckd-client afccheck filerelaytest housearresttest +noinst_PROGRAMS = ideviceclient afccheck filerelaytest housearresttest + +if HAVE_GLIB2 +noinst_PROGRAMS += lckd-client +endif  ideviceclient_SOURCES = ideviceclient.c  ideviceclient_CFLAGS = $(AM_CFLAGS) @@ -12,8 +16,8 @@ ideviceclient_LDFLAGS = $(AM_LDFLAGS)  ideviceclient_LDADD = ../src/libimobiledevice.la  lckd_client_SOURCES = lckdclient.c -lckd_client_CFLAGS = $(AM_CFLAGS) -lckd_client_LDFLAGS = -lreadline $(AM_LDFLAGS) +lckd_client_CFLAGS = $(AM_CFLAGS) $(libglib2_CFLAGS) +lckd_client_LDFLAGS = -lreadline $(AM_LDFLAGS) $(libglib2_LIBS)  lckd_client_LDADD = ../src/libimobiledevice.la  afccheck_SOURCES = afccheck.c diff --git a/dev/ideviceclient.c b/dev/ideviceclient.c index d952594..0400fed 100644 --- a/dev/ideviceclient.c +++ b/dev/ideviceclient.c @@ -23,7 +23,6 @@  #include <stdlib.h>  #include <string.h>  #include <errno.h> -#include <glib.h>  #include <libimobiledevice/libimobiledevice.h>  #include <libimobiledevice/lockdown.h> @@ -138,18 +137,20 @@ int main(int argc, char *argv[])  			printf("Directory time.\n");  			for (i = 0; dirs[i]; i++) {  				printf("/%s\n", dirs[i]); +				free(dirs[i]);  			} - -			g_strfreev(dirs); +			if (dirs) +				free(dirs);  			dirs = NULL;  			afc_get_device_info(afc, &dirs);  			if (dirs) {  				for (i = 0; dirs[i]; i += 2) {  					printf("%s: %s\n", dirs[i], dirs[i + 1]); +					free(dirs[i]);  				} +				free(dirs);  			} -			g_strfreev(dirs);  			uint64_t my_file = 0;  			char **info = NULL; diff --git a/include/libimobiledevice/installation_proxy.h b/include/libimobiledevice/installation_proxy.h index f5f00e8..11fb66e 100644 --- a/include/libimobiledevice/installation_proxy.h +++ b/include/libimobiledevice/installation_proxy.h @@ -28,7 +28,6 @@ extern "C" {  #endif  #include <libimobiledevice/libimobiledevice.h> -#include <glib.h>  /** @name Error Codes */  /*@{*/ @@ -66,7 +65,7 @@ instproxy_error_t instproxy_restore(instproxy_client_t client, const char *appid  instproxy_error_t instproxy_remove_archive(instproxy_client_t client, const char *appid, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data);  plist_t instproxy_client_options_new(); -void instproxy_client_options_add(plist_t client_options, ...) G_GNUC_NULL_TERMINATED; +void instproxy_client_options_add(plist_t client_options, ...);  void instproxy_client_options_free(plist_t client_options);  #ifdef __cplusplus diff --git a/include/libimobiledevice/mobilesync.h b/include/libimobiledevice/mobilesync.h index 7658b7d..bd717ee 100644 --- a/include/libimobiledevice/mobilesync.h +++ b/include/libimobiledevice/mobilesync.h @@ -29,7 +29,6 @@ extern "C" {  #endif  #include <libimobiledevice/libimobiledevice.h> -#include <glib.h>  /** @name Error Codes */  /*@{*/ @@ -93,7 +92,7 @@ mobilesync_anchors_t mobilesync_anchors_new(const char *device_anchor, const cha  void mobilesync_anchors_free(mobilesync_anchors_t anchors);  plist_t mobilesync_actions_new(); -void mobilesync_actions_add(plist_t actions, ...) G_GNUC_NULL_TERMINATED; +void mobilesync_actions_add(plist_t actions, ...);  void mobilesync_actions_free(plist_t actions);  #ifdef __cplusplus diff --git a/src/Makefile.am b/src/Makefile.am index f42ac08..5531f8d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@  AM_CPPFLAGS = -I$(top_srcdir)/include -AM_CFLAGS = $(GLOBAL_CFLAGS) $(libusbmuxd_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(libplist_CFLAGS) $(LFS_CFLAGS) -AM_LDFLAGS = $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) $(libplist_LIBS) $(libusbmuxd_LIBS) $(libgcrypt_LIBS) +AM_CFLAGS = $(GLOBAL_CFLAGS) $(libusbmuxd_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libplist_CFLAGS) $(LFS_CFLAGS) +AM_LDFLAGS = $(libgnutls_LIBS) $(libtasn1_LIBS) $(libplist_LIBS) $(libusbmuxd_LIBS) $(libgcrypt_LIBS) ${libpthread_LIBS}  lib_LTLIBRARIES = libimobiledevice.la  libimobiledevice_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(LIBIMOBILEDEVICE_SO_VERSION) -no-undefined @@ -364,7 +364,7 @@ static afc_error_t afc_receive_data(afc_client_t client, char **dump_here, uint3  	}  	if (current_count >= sizeof(uint64_t)) { -		param1 = GUINT64_FROM_LE(*(uint64_t*)(*dump_here)); +		param1 = le64toh(*(uint64_t*)(*dump_here));  	}  	debug_info("packet data size = %i", current_count); @@ -577,8 +577,10 @@ afc_error_t afc_get_device_info_key(afc_client_t client, const char *key, char *  			break;  		}  	} - -	g_strfreev(kvps); +	for (ptr = kvps; *ptr; ptr++) { +		free(*ptr); +	} +	free(kvps);  	return ret;  } @@ -764,7 +766,7 @@ idevice_error_t  afc_file_open(afc_client_t client, const char *filename,  					 afc_file_mode_t file_mode, uint64_t *handle)  { -	uint64_t file_mode_loc = GUINT64_TO_LE(file_mode); +	uint64_t file_mode_loc = htole64(file_mode);  	uint32_t bytes = 0;  	char *data = (char *) malloc(sizeof(char) * (8 + strlen(filename) + 1));  	afc_error_t ret = AFC_E_UNKNOWN_ERROR; @@ -842,7 +844,7 @@ afc_file_read(afc_client_t client, uint64_t handle, char *data, uint32_t length,  		/* Send the read command */  		AFCFilePacket *packet = (AFCFilePacket *) malloc(sizeof(AFCFilePacket));  		packet->filehandle = handle; -		packet->size = GUINT64_TO_LE(((length - current_count) < MAXIMUM_READ_SIZE) ? (length - current_count) : MAXIMUM_READ_SIZE); +		packet->size = htole64(((length - current_count) < MAXIMUM_READ_SIZE) ? (length - current_count) : MAXIMUM_READ_SIZE);  		client->afc_packet->operation = AFC_OP_READ;  		client->afc_packet->entire_length = client->afc_packet->this_length = 0;  		ret = afc_dispatch_packet(client, (char *) packet, sizeof(AFCFilePacket), &bytes_loc); @@ -1035,7 +1037,7 @@ afc_error_t afc_file_lock(afc_client_t client, uint64_t handle, afc_lock_op_t op  {  	char *buffer = malloc(16);  	uint32_t bytes = 0; -	uint64_t op = GUINT64_TO_LE(operation); +	uint64_t op = htole64(operation);  	afc_error_t ret = AFC_E_UNKNOWN_ERROR;  	if (!client || (handle == 0)) @@ -1084,8 +1086,8 @@ afc_error_t afc_file_lock(afc_client_t client, uint64_t handle, afc_lock_op_t op  afc_error_t afc_file_seek(afc_client_t client, uint64_t handle, int64_t offset, int whence)  {  	char *buffer = (char *) malloc(sizeof(char) * 24); -	int64_t offset_loc = (int64_t)GUINT64_TO_LE(offset); -	uint64_t whence_loc = GUINT64_TO_LE(whence); +	int64_t offset_loc = (int64_t)htole64(offset); +	uint64_t whence_loc = htole64(whence);  	uint32_t bytes = 0;  	afc_error_t ret = AFC_E_UNKNOWN_ERROR; @@ -1156,7 +1158,7 @@ afc_error_t afc_file_tell(afc_client_t client, uint64_t handle, uint64_t *positi  	if (bytes > 0 && buffer) {  		/* Get the position */  		memcpy(position, buffer, sizeof(uint64_t)); -		*position = GUINT64_FROM_LE(*position); +		*position = le64toh(*position);  	}  	if (buffer)  		free(buffer); @@ -1182,7 +1184,7 @@ afc_error_t afc_file_truncate(afc_client_t client, uint64_t handle, uint64_t new  {  	char *buffer = (char *) malloc(sizeof(char) * 16);  	uint32_t bytes = 0; -	uint64_t newsize_loc = GUINT64_TO_LE(newsize); +	uint64_t newsize_loc = htole64(newsize);  	afc_error_t ret = AFC_E_UNKNOWN_ERROR;  	if (!client || (handle == 0)) @@ -1227,7 +1229,7 @@ afc_error_t afc_truncate(afc_client_t client, const char *path, uint64_t newsize  	char *response = NULL;  	char *send = (char *) malloc(sizeof(char) * (strlen(path) + 1 + 8));  	uint32_t bytes = 0; -	uint64_t size_requested = GUINT64_TO_LE(newsize); +	uint64_t size_requested = htole64(newsize);  	afc_error_t ret = AFC_E_UNKNOWN_ERROR;  	if (!client || !path || !client->afc_packet || !client->connection) @@ -1271,7 +1273,7 @@ afc_error_t afc_make_link(afc_client_t client, afc_link_type_t linktype, const c  	char *response = NULL;  	char *send = (char *) malloc(sizeof(char) * (strlen(target)+1 + strlen(linkname)+1 + 8));  	uint32_t bytes = 0; -	uint64_t type = GUINT64_TO_LE(linktype); +	uint64_t type = htole64(linktype);  	afc_error_t ret = AFC_E_UNKNOWN_ERROR;  	if (!client || !target || !linkname || !client->afc_packet || !client->connection) @@ -1319,7 +1321,7 @@ afc_error_t afc_set_file_time(afc_client_t client, const char *path, uint64_t mt  	char *response = NULL;  	char *send = (char *) malloc(sizeof(char) * (strlen(path) + 1 + 8));  	uint32_t bytes = 0; -	uint64_t mtime_loc = GUINT64_TO_LE(mtime); +	uint64_t mtime_loc = htole64(mtime);  	afc_error_t ret = AFC_E_UNKNOWN_ERROR;  	if (!client || !path || !client->afc_packet || !client->connection) @@ -33,16 +33,16 @@ typedef struct {  } AFCPacket;  #define AFCPacket_to_LE(x) \ - 	(x)->entire_length = GUINT64_TO_LE((x)->entire_length); \ -	(x)->this_length   = GUINT64_TO_LE((x)->this_length); \ -	(x)->packet_num    = GUINT64_TO_LE((x)->packet_num); \ -	(x)->operation     = GUINT64_TO_LE((x)->operation); + 	(x)->entire_length = htole64((x)->entire_length); \ +	(x)->this_length   = htole64((x)->this_length); \ +	(x)->packet_num    = htole64((x)->packet_num); \ +	(x)->operation     = htole64((x)->operation);  #define AFCPacket_from_LE(x) \ -	(x)->entire_length = GUINT64_FROM_LE((x)->entire_length); \ -	(x)->this_length   = GUINT64_FROM_LE((x)->this_length); \ -	(x)->packet_num    = GUINT64_FROM_LE((x)->packet_num); \ -	(x)->operation     = GUINT64_FROM_LE((x)->operation); +	(x)->entire_length = le64toh((x)->entire_length); \ +	(x)->this_length   = le64toh((x)->this_length); \ +	(x)->packet_num    = le64toh((x)->packet_num); \ +	(x)->operation     = le64toh((x)->operation);  typedef struct {  	uint64_t filehandle, size; diff --git a/src/debug.c b/src/debug.c index 26a9678..ece2b1d 100644 --- a/src/debug.c +++ b/src/debug.c @@ -29,6 +29,7 @@  #include <stdio.h>  #include <stdint.h>  #include <stdlib.h> +#include <time.h>  #include "debug.h"  #include "libimobiledevice/libimobiledevice.h" @@ -54,7 +55,7 @@ static void debug_print_line(const char *func, const char *file, int line, const  	time_t the_time;  	time(&the_time); -	str_time = g_new0 (gchar, 255); +	str_time = (char*)malloc(255);  	strftime(str_time, 254, "%H:%M:%S", localtime (&the_time));  	/* generate header text */ diff --git a/src/debug.h b/src/debug.h index 2fd0960..cb1bf97 100644 --- a/src/debug.h +++ b/src/debug.h @@ -24,7 +24,14 @@  #define DEBUG_H  #include <plist/plist.h> -#include <glib.h> + +#ifndef LIBIMOBILEDEVICE_INTERNAL +#ifdef WIN32 +#define LIBIMOBILEDEVICE_INTERNAL +#else +#define LIBIMOBILEDEVICE_INTERNAL __attribute__((visibility("hidden"))) +#endif +#endif  #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && !defined(STRIP_DEBUG_CODE)  #define debug_info(...) debug_info_real (__func__, __FILE__, __LINE__, __VA_ARGS__) @@ -37,14 +44,14 @@  #define debug_plist(a)  #endif -G_GNUC_INTERNAL inline void debug_info_real(const char *func, +LIBIMOBILEDEVICE_INTERNAL inline void debug_info_real(const char *func,  											const char *file,  											int	line,  											const char *format, ...); -G_GNUC_INTERNAL inline void debug_buffer(const char *data, const int length); -G_GNUC_INTERNAL inline void debug_buffer_to_file(const char *file, const char *data, const int length); -G_GNUC_INTERNAL inline void debug_plist_real(const char *func, +LIBIMOBILEDEVICE_INTERNAL inline void debug_buffer(const char *data, const int length); +LIBIMOBILEDEVICE_INTERNAL inline void debug_buffer_to_file(const char *file, const char *data, const int length); +LIBIMOBILEDEVICE_INTERNAL inline void debug_plist_real(const char *func,  											const char *file,  											int	line,  											plist_t plist); diff --git a/src/house_arrest.h b/src/house_arrest.h index 6d13a88..708f1b5 100644 --- a/src/house_arrest.h +++ b/src/house_arrest.h @@ -21,8 +21,6 @@  #ifndef IHOUSE_ARREST_H  #define IHOUSE_ARREST_H -#include <glib.h> -  #include "libimobiledevice/house_arrest.h"  #include "property_list_service.h" diff --git a/src/lockdown.c b/src/lockdown.c index 1783df6..424cf89 100644 --- a/src/lockdown.c +++ b/src/lockdown.c @@ -26,7 +26,6 @@  #define __USE_GNU 1  #include <stdio.h>  #include <ctype.h> -#include <glib.h>  #include <libtasn1.h>  #include <gnutls/x509.h>  #include <plist/plist.h> @@ -1200,8 +1199,8 @@ lockdownd_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datu  						memcpy(oroot_cert->data, pem_root_cert.data, pem_root_cert.size);  						oroot_cert->size = pem_root_cert.size; -						g_free(pem_root_cert.data); -						g_free(pem_host_cert.data); +						free(pem_root_cert.data); +						free(pem_host_cert.data);  						if (dev_pem.data)  							gnutls_free(dev_pem.data); diff --git a/src/mobilesync.c b/src/mobilesync.c index e600452..9b31ad5 100644 --- a/src/mobilesync.c +++ b/src/mobilesync.c @@ -27,7 +27,6 @@  #include <string.h>  #include <stdlib.h>  #include <stdio.h> -#include <glib.h>  #include "mobilesync.h"  #include "device_link_service.h" diff --git a/src/property_list_service.c b/src/property_list_service.c index 8af958e..47b119f 100644 --- a/src/property_list_service.c +++ b/src/property_list_service.c @@ -20,7 +20,6 @@   */  #include <stdlib.h>  #include <string.h> -#include <glib.h>  #include "property_list_service.h"  #include "idevice.h" @@ -138,7 +137,7 @@ static property_list_service_error_t internal_plist_send(property_list_service_c  		return PROPERTY_LIST_SERVICE_E_PLIST_ERROR;  	} -	nlen = GUINT32_TO_BE(length); +	nlen = htobe32(length);  	debug_info("sending %d bytes", length);  	idevice_connection_send(client->connection, (const char*)&nlen, sizeof(nlen), (uint32_t*)&bytes);  	if (bytes == sizeof(nlen)) { @@ -226,7 +225,7 @@ static property_list_service_error_t internal_plist_receive_timeout(property_lis  		debug_info("initial read failed!");  		return PROPERTY_LIST_SERVICE_E_MUX_ERROR;  	} else { -		pktlen = GUINT32_FROM_BE(pktlen); +		pktlen = be32toh(pktlen);  		if (pktlen < (1 << 24)) { /* prevent huge buffers */  			uint32_t curlen = 0;  			char *content = NULL; diff --git a/src/restore.c b/src/restore.c index 031eaea..eedddab 100644 --- a/src/restore.c +++ b/src/restore.c @@ -23,7 +23,6 @@  #include <errno.h>  #include <string.h>  #include <stdlib.h> -#include <glib.h>  #include <plist/plist.h>  #include "property_list_service.h" diff --git a/src/userpref.c b/src/userpref.c index 4aab67b..d44d5aa 100644 --- a/src/userpref.c +++ b/src/userpref.c @@ -19,9 +19,6 @@   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA   */ -#include <glib.h> -#include <glib/gstdio.h> -#include <glib/gprintf.h>  #include <stdio.h>  #include <stdint.h>  #include <stdlib.h> @@ -30,6 +27,15 @@  #include <gnutls/x509.h>  #include <gcrypt.h> +#include <dirent.h> +#include <libgen.h> +#include <sys/stat.h> +#include <errno.h> + +#ifdef WIN32 +#include <shlobj.h> +#endif +  #include "userpref.h"  #include "debug.h" @@ -41,18 +47,239 @@  #define LIBIMOBILEDEVICE_ROOT_CERTIF "RootCertificate.pem"  #define LIBIMOBILEDEVICE_HOST_CERTIF "HostCertificate.pem" +#ifdef WIN32 +#define DIR_SEP '\\' +#define DIR_SEP_S "\\" +#else +#define DIR_SEP '/' +#define DIR_SEP_S "/" +#endif + +static char __config_dir[512] = {0, }; + +#ifdef WIN32 +static char *userpref_utf16_to_utf8(wchar_t *unistr, long len, long *items_read, long *items_written) +{ +	if (!unistr || (len <= 0)) return NULL; +	char *outbuf = (char*)malloc(3*(len+1)); +	int p = 0; +	int i = 0; + +	wchar_t wc; + +	while (i < len) { +		wc = unistr[i++]; +		if (wc >= 0x800) { +			outbuf[p++] = (char)(0xE0 + ((wc >> 12) & 0xF)); +			outbuf[p++] = (char)(0x80 + ((wc >> 6) & 0x3F)); +			outbuf[p++] = (char)(0x80 + (wc & 0x3F)); +		} else if (wc >= 0x80) { +			outbuf[p++] = (char)(0xC0 + ((wc >> 6) & 0x1F)); +			outbuf[p++] = (char)(0x80 + (wc & 0x3F)); +		} else { +			outbuf[p++] = (char)(wc & 0x7F); +		} +	} +	if (items_read) { +		*items_read = i; +	} +	if (items_written) { +		*items_written = p; +	} +	outbuf[p] = 0; + +	return outbuf; +} +#endif + +static const char *userpref_get_config_dir() +{ +	if (__config_dir[0]) return __config_dir; +#ifdef WIN32 +	wchar_t path[MAX_PATH+1]; +	HRESULT hr; +	LPITEMIDLIST pidl = NULL; +	BOOL b = FALSE; + +	hr = SHGetSpecialFolderLocation (NULL, CSIDL_LOCAL_APPDATA, &pidl); +	if (hr == S_OK) { +		b = SHGetPathFromIDListW (pidl, path); +		if (b) { +			char *cdir = userpref_utf16_to_utf8 (path, wcslen(path), NULL, NULL); +			strcpy(__config_dir, cdir); +			free(cdir); +			CoTaskMemFree (pidl); +		} +	} +#else +	const char *cdir = getenv("XDG_CONFIG_HOME"); +	if (!cdir) { +		cdir = getenv("HOME"); +		strcpy(__config_dir, cdir); +		strcat(__config_dir, DIR_SEP_S); +		strcat(__config_dir, ".config"); +	} else { +		strcpy(__config_dir, cdir); +	} +#endif +	strcat(__config_dir, DIR_SEP_S); +	strcat(__config_dir, LIBIMOBILEDEVICE_CONF_DIR); + +	int i = strlen(__config_dir)-1;	 +	while ((i > 0) && (__config_dir[i] == DIR_SEP)) { +		__config_dir[i--] = '\0'; +	} + +	return __config_dir; +} + +static int mkdir_with_parents(const char *dir, int mode) +{ +	if (!dir) return -1; +	if (mkdir(dir, mode) == 0) { +		return 0; +	} else { +		if (errno == EEXIST) return 0;	 +	} +	int res; +	char *parent = strdup(dir); +	parent = dirname(parent); +	if (parent) { +		res = mkdir_with_parents(parent, mode); +	} else { +		res = -1;	 +	} +	free(parent); +	if (res == 0) { +		mkdir_with_parents(dir, mode); +	} +	return res; +} + +static int config_write(const char *cfgfile, plist_t dict) +{ +	if (!cfgfile || !dict || (plist_get_node_type(dict) != PLIST_DICT)) { +		return -1; +	} +	int res = -1; + +#if 1 // old style config +	plist_t hostid = plist_dict_get_item(dict, "HostID"); +	if (hostid && (plist_get_node_type(hostid) == PLIST_STRING)) { +		char *hostidstr = NULL; +		plist_get_string_val(hostid, &hostidstr); +		if (hostidstr) { +			FILE *fd = fopen(cfgfile, "w"); +			if (fd) { +				fprintf(fd, "\n[Global]\nHostID=%s\n", hostidstr); +				fclose(fd); +				res = 0; +			} +			free(hostidstr); +		} +	} +#endif +#if 0 +	char *xml = NULL; +	uint32_t length = 0; + +	plist_to_xml(dict, &xml, &length); +	if (!xml) { +		return res; +	} + +	FILE *fd = fopen(cfgfile, "w"); +	if (!fd) { +		free(xml); +		return res; +	} + +	if (fwrite(xml, 1, length, fd) == length) { +		res = 0; +	} else { +		fprintf(stderr, "%s: ERROR: failed to write configuration to '%s'\n", __func__, cfgfile); +	} +	fclose(fd); + +	free(xml); +#endif +	return res; +} + +static int config_read(const char *cfgfile, plist_t *dict) +{ +	if (!cfgfile || !dict) { +		return -1; +	} + +	int res = -1; +	FILE *fd = fopen(cfgfile, "r+"); +	if (!fd) { +		return -1; +	} + +	fseek(fd, 0, SEEK_END); +	unsigned long int size = ftell(fd); +	fseek(fd, 0, SEEK_SET); +	unsigned char *contents = NULL; + +	contents = malloc(size); +	if (fread(contents, 1, size, fd) != size) { +		free(contents); +		fclose(fd); +		return -1; +	} +	plist_t plist = NULL; + +	if (!memcmp(contents, "bplist00", 8)) { +		plist_from_bin((const char*)contents, (uint32_t)size, &plist); +		fclose(fd); +	} else { +		if (memchr(contents, '<', size)) { +			plist_from_xml((const char*)contents, (uint32_t)size, &plist); +		} +		if (plist) { +			fclose(fd); +		} else { +			// try parsing old format config file +			char line[256]; +			fseek(fd, 0, SEEK_SET); +			while (fgets(line, 256, fd)) { +				size_t llen = strlen(line)-1; +				while ((llen > 0) && ((line[llen] == '\n') || (line[llen] == '\r'))) { +					line[llen] = '\0'; +				} +				if (!strncmp(line, "HostID=", 7)) { +					plist = plist_new_dict(); +					plist_dict_insert_item(plist, "HostID", plist_new_string(line+7)); +					break; +				} +			} +			fclose(fd); +			if (plist) { +				// write new format config +				config_write(cfgfile, plist); +			} +		} +	} +	free(contents); +	if (plist) { +		*dict = plist; +		res = 0; +	} +	return res; +}  /**   * Creates a freedesktop compatible configuration directory.   */  static void userpref_create_config_dir(void)  { -	gchar *config_dir = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, NULL); - -	if (!g_file_test(config_dir, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) -		g_mkdir_with_parents(config_dir, 0755); - -	g_free(config_dir); +	const char *config_path = userpref_get_config_dir(); +	struct stat st; +	if (stat(config_path, &st) != 0) { +		mkdir_with_parents(config_path, 0755); +	}  }  static int get_rand(int min, int max) @@ -94,10 +321,8 @@ static char *userpref_generate_host_id()   */  static int userpref_set_host_id(const char *host_id)  { -	GKeyFile *key_file; -	gsize length; -	gchar *buf, *config_file; -	GIOChannel *file; +	const char *config_path; +	char *config_file;  	if (!host_id)  		return 0; @@ -105,24 +330,34 @@ static int userpref_set_host_id(const char *host_id)  	/* Make sure config directory exists */  	userpref_create_config_dir(); +	config_path = userpref_get_config_dir(); +	config_file = (char*)malloc(strlen(config_path)+1+strlen(LIBIMOBILEDEVICE_CONF_FILE)+1); +	strcpy(config_file, config_path); +	strcat(config_file, DIR_SEP_S); +	strcat(config_file, LIBIMOBILEDEVICE_CONF_FILE); +  	/* Now parse file to get the HostID */ -	key_file = g_key_file_new(); +	plist_t config = NULL; +	config_read(config_file, &config); +	if (!config) { +		config = plist_new_dict(); +		plist_dict_insert_item(config, "HostID", plist_new_string(host_id)); +	} else { +		plist_t n = plist_dict_get_item(config, "HostID"); +		if (n) { +			plist_set_string_val(n, host_id); +		} else { +			plist_dict_insert_item(config, "HostID", plist_new_string(host_id)); +		} +	}  	/* Store in config file */  	debug_info("setting hostID to %s", host_id); -	g_key_file_set_value(key_file, "Global", "HostID", host_id); - -	/* Write config file on disk */ -	buf = g_key_file_to_data(key_file, &length, NULL); -	config_file = -		g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, LIBIMOBILEDEVICE_CONF_FILE, NULL); -	file = g_io_channel_new_file(config_file, "w", NULL); -	g_free(config_file); -	g_io_channel_write_chars(file, buf, length, NULL, NULL); -	g_io_channel_shutdown(file, TRUE, NULL); -	g_io_channel_unref(file); - -	g_key_file_free(key_file); + +	config_write(config_file, config); +	plist_free(config); + +	free(config_file);  	return 1;  } @@ -135,23 +370,25 @@ static int userpref_set_host_id(const char *host_id)   */  void userpref_get_host_id(char **host_id)  { -	gchar *config_file; -	GKeyFile *key_file; -	gchar *loc_host_id; +	const char *config_path; +	char *config_file; -	config_file = -		g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, LIBIMOBILEDEVICE_CONF_FILE, NULL); +	config_path = userpref_get_config_dir(); +	config_file = (char*)malloc(strlen(config_path)+1+strlen(LIBIMOBILEDEVICE_CONF_FILE)+1); +	strcpy(config_file, config_path); +	strcat(config_file, DIR_SEP_S); +	strcat(config_file, LIBIMOBILEDEVICE_CONF_FILE);  	/* now parse file to get the HostID */ -	key_file = g_key_file_new(); -	if (g_key_file_load_from_file(key_file, config_file, G_KEY_FILE_KEEP_COMMENTS, NULL)) { -		loc_host_id = g_key_file_get_value(key_file, "Global", "HostID", NULL); -		if (loc_host_id) -			*host_id = strdup((char *) loc_host_id); -		g_free(loc_host_id); +	plist_t config = NULL; +	if (config_read(config_file, &config) == 0) { +		plist_t n_host_id = plist_dict_get_item(config, "HostID"); +		if (n_host_id && (plist_get_node_type(n_host_id) == PLIST_STRING)) { +			plist_get_string_val(n_host_id, host_id); +		}  	} -	g_key_file_free(key_file); -	g_free(config_file); +	plist_free(config); +	free(config_file);  	if (!*host_id) {  		/* no config, generate host_id */ @@ -173,15 +410,23 @@ void userpref_get_host_id(char **host_id)  int userpref_has_device_public_key(const char *uuid)  {  	int ret = 0; -	gchar *config_file; +	const char *config_path; +	char *config_file; +	struct stat st; + +	if (!uuid) return 0;  	/* first get config file */ -	gchar *device_file = g_strconcat(uuid, ".pem", NULL); -	config_file = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, device_file, NULL); -	if (g_file_test(config_file, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))) +	config_path = userpref_get_config_dir(); +	config_file = (char*)malloc(strlen(config_path)+1+strlen(uuid)+4+1); +	strcpy(config_file, config_path); +	strcat(config_file, DIR_SEP_S); +	strcat(config_file, uuid); +	strcat(config_file, ".pem"); + +	if ((stat(config_file, &st) == 0) && S_ISREG(st.st_mode))  		ret = 1; -	g_free(config_file); -	g_free(device_file); +	free(config_file);  	return ret;  } @@ -202,10 +447,13 @@ int userpref_has_device_public_key(const char *uuid)   */  userpref_error_t userpref_get_paired_uuids(char ***list, unsigned int *count)  { -	GDir *config_dir; -	gchar *config_path; -	const gchar *dir_file; -	GList *uuids = NULL; +	struct slist_t { +		char *name; +		void *next; +	}; +	DIR *config_dir; +	const char *config_path; +	struct slist_t *uuids = NULL;  	unsigned int i;  	unsigned int found = 0; @@ -218,29 +466,44 @@ userpref_error_t userpref_get_paired_uuids(char ***list, unsigned int *count)  		*count = 0;  	} -	config_path = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, NULL); - -	config_dir = g_dir_open(config_path,0,NULL); +	config_path = userpref_get_config_dir(); +	config_dir = opendir(config_path);  	if (config_dir) { -		while ((dir_file = g_dir_read_name(config_dir))) { -			if (g_str_has_suffix(dir_file, ".pem") && (strlen(dir_file) == 44)) { -				uuids = g_list_append(uuids, g_strndup(dir_file, strlen(dir_file)-4)); +		struct dirent *entry; +		struct slist_t *listp = uuids; +		while ((entry = readdir(config_dir))) { +			char *ext = strstr(entry->d_name, ".pem"); +			if (ext && ((ext - entry->d_name) == 40) && (strlen(entry->d_name) == 44)) { +				struct slist_t *ne = (struct slist_t*)malloc(sizeof(struct slist_t)); +				ne->name = (char*)malloc(41); +				strncpy(ne->name, entry->d_name, 40); +				ne->name[40] = 0; +				ne->next = NULL; +				if (!listp) { +					listp = ne; +					uuids = listp; +				} else { +					listp->next = ne; +					listp = listp->next; +				}  				found++;  			}  		} -		g_dir_close(config_dir); +		closedir(config_dir);  	}  	*list = (char**)malloc(sizeof(char*) * (found+1)); -	for (i = 0; i < found; i++) { -		(*list)[i] = g_list_nth_data(uuids, i); +	i = 0; +	while (uuids) { +		(*list)[i++] = uuids->name; +		struct slist_t *old = uuids; +		uuids = uuids->next; +		free(old);  	}  	(*list)[i] = NULL;  	if (count) {  		*count = found;  	} -	g_list_free(uuids); -	g_free(config_path);  	return USERPREF_E_SUCCESS;  } @@ -266,15 +529,18 @@ userpref_error_t userpref_set_device_public_key(const char *uuid, gnutls_datum_t  	userpref_create_config_dir();  	/* build file path */ -	gchar *device_file = g_strconcat(uuid, ".pem", NULL); -	gchar *pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, device_file, NULL); +	const char *config_path = userpref_get_config_dir(); +	char *pem = (char*)malloc(strlen(config_path)+1+strlen(uuid)+4+1); +	strcpy(pem, config_path); +	strcat(pem, DIR_SEP_S); +	strcat(pem, uuid); +	strcat(pem, ".pem");  	/* store file */  	FILE *pFile = fopen(pem, "wb");  	fwrite(public_key.data, 1, public_key.size, pFile);  	fclose(pFile); -	g_free(pem); -	g_free(device_file); +	free(pem);  	return USERPREF_E_SUCCESS;  } @@ -292,14 +558,17 @@ userpref_error_t userpref_remove_device_public_key(const char *uuid)  		return USERPREF_E_SUCCESS;  	/* build file path */ -	gchar *device_file = g_strconcat(uuid, ".pem", NULL); -	gchar *pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, device_file, NULL); +	const char *config_path = userpref_get_config_dir(); +	char *pem = (char*)malloc(strlen(config_path)+1+strlen(uuid)+4+1); +	strcpy(pem, config_path); +	strcat(pem, DIR_SEP_S); +	strcat(pem, uuid); +	strcat(pem, ".pem");  	/* remove file */ -	g_remove(pem); +	remove(pem); -	g_free(pem); -	g_free(device_file); +	free(pem);  	return USERPREF_E_SUCCESS;  } @@ -314,18 +583,50 @@ userpref_error_t userpref_remove_device_public_key(const char *uuid)   */  static int userpref_get_file_contents(const char *file, gnutls_datum_t * data)  { -	gboolean success; -	gsize size; -	char *content; -	gchar *filepath; +	int success; +	unsigned long int size = 0; +	unsigned char *content = NULL; +	const char *config_path; +	char *filepath; +	FILE *fd;  	if (NULL == file || NULL == data)  		return 0;  	/* Read file */ -	filepath = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, file, NULL); -	success = g_file_get_contents(filepath, &content, &size, NULL); -	g_free(filepath); +	config_path = userpref_get_config_dir(); +	filepath = (char*)malloc(strlen(config_path)+1+strlen(file)+1); +	strcpy(filepath, config_path); +	strcat(filepath, DIR_SEP_S); +	strcat(filepath, file); + +	fd = fopen(filepath, "rb"); +	if (fd) { +		fseek(fd, 0, SEEK_END); +		size = ftell(fd); +		fseek(fd, 0, SEEK_SET); + +		// prevent huge files +		if (size > 0xFFFFFF) { +			fprintf(stderr, "%s: file is too big (> 16MB). Refusing to read the contents to memory!", __func__); +		} else { +			size_t p = 0; +			content = (unsigned char*)malloc(size); +			while (!feof(fd)) { +				p += fread(content+p, 1, size-p, fd); +				if (ferror(fd) != 0) { +					break; +				} +				if (p >= size) { +					success = 1; +					break; +				} +			} +		} +		fclose(fd); +	} + +	free(filepath);  	/* Add it to the gnutls_datnum_t structure */  	if (success) { @@ -549,8 +850,8 @@ userpref_error_t userpref_get_certs_as_pem(gnutls_datum_t *pem_root_cert, gnutls  	if (userpref_get_file_contents(LIBIMOBILEDEVICE_ROOT_CERTIF, pem_root_cert) && userpref_get_file_contents(LIBIMOBILEDEVICE_HOST_CERTIF, pem_host_cert))  		return USERPREF_E_SUCCESS;  	else { -		g_free(pem_root_cert->data); -		g_free(pem_host_cert->data); +		gnutls_free(pem_root_cert->data); +		gnutls_free(pem_host_cert->data);  	}  	return USERPREF_E_INVALID_CONF;  } @@ -570,7 +871,8 @@ userpref_error_t userpref_get_certs_as_pem(gnutls_datum_t *pem_root_cert, gnutls  userpref_error_t userpref_set_keys_and_certs(gnutls_datum_t * root_key, gnutls_datum_t * root_cert, gnutls_datum_t * host_key, gnutls_datum_t * host_cert)  {  	FILE *pFile; -	gchar *pem; +	char *pem; +	const char *config_path;  	if (!root_key || !host_key || !root_cert || !host_cert)  		return USERPREF_E_INVALID_ARG; @@ -578,30 +880,44 @@ userpref_error_t userpref_set_keys_and_certs(gnutls_datum_t * root_key, gnutls_d  	/* Make sure config directory exists */  	userpref_create_config_dir(); +	config_path = userpref_get_config_dir(); +  	/* Now write keys and certificates to disk */ -	pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, LIBIMOBILEDEVICE_ROOT_PRIVKEY, NULL); +	pem = (char*)malloc(strlen(config_path)+1+strlen(LIBIMOBILEDEVICE_ROOT_PRIVKEY)+1); +	strcpy(pem, config_path); +	strcat(pem, DIR_SEP_S); +	strcat(pem, LIBIMOBILEDEVICE_ROOT_PRIVKEY);  	pFile = fopen(pem, "wb");  	fwrite(root_key->data, 1, root_key->size, pFile);  	fclose(pFile); -	g_free(pem); +	free(pem); -	pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, LIBIMOBILEDEVICE_HOST_PRIVKEY, NULL); +	pem = (char*)malloc(strlen(config_path)+1+strlen(LIBIMOBILEDEVICE_HOST_PRIVKEY)+1); +	strcpy(pem, config_path); +	strcat(pem, DIR_SEP_S); +	strcat(pem, LIBIMOBILEDEVICE_HOST_PRIVKEY);  	pFile = fopen(pem, "wb");  	fwrite(host_key->data, 1, host_key->size, pFile);  	fclose(pFile); -	g_free(pem); +	free(pem); -	pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, LIBIMOBILEDEVICE_ROOT_CERTIF, NULL); +	pem = (char*)malloc(strlen(config_path)+1+strlen(LIBIMOBILEDEVICE_ROOT_CERTIF)+1); +	strcpy(pem, config_path); +	strcat(pem, DIR_SEP_S); +	strcat(pem, LIBIMOBILEDEVICE_ROOT_CERTIF);  	pFile = fopen(pem, "wb");  	fwrite(root_cert->data, 1, root_cert->size, pFile);  	fclose(pFile); -	g_free(pem); +	free(pem); -	pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, LIBIMOBILEDEVICE_HOST_CERTIF, NULL); +	pem = (char*)malloc(strlen(config_path)+1+strlen(LIBIMOBILEDEVICE_HOST_CERTIF)+1); +	strcpy(pem, config_path); +	strcat(pem, DIR_SEP_S); +	strcat(pem, LIBIMOBILEDEVICE_HOST_CERTIF);  	pFile = fopen(pem, "wb");  	fwrite(host_cert->data, 1, host_cert->size, pFile);  	fclose(pFile); -	g_free(pem); +	free(pem);  	return USERPREF_E_SUCCESS;  } diff --git a/src/userpref.h b/src/userpref.h index f9d3913..e16fd65 100644 --- a/src/userpref.h +++ b/src/userpref.h @@ -23,7 +23,14 @@  #define USERPREF_H  #include <gnutls/gnutls.h> -#include <glib.h> + +#ifndef LIBIMOBILEDEVICE_INTERNAL +#ifdef WIN32 +#define LIBIMOBILEDEVICE_INTERNAL +#else +#define LIBIMOBILEDEVICE_INTERNAL __attribute__((visibility("hidden"))) +#endif +#endif  #define USERPREF_E_SUCCESS             0  #define USERPREF_E_INVALID_ARG        -1 @@ -34,12 +41,12 @@  typedef int16_t userpref_error_t; -G_GNUC_INTERNAL userpref_error_t userpref_get_keys_and_certs(gnutls_x509_privkey_t root_privkey, gnutls_x509_crt_t root_crt, gnutls_x509_privkey_t host_privkey, gnutls_x509_crt_t host_crt); -G_GNUC_INTERNAL userpref_error_t userpref_set_keys_and_certs(gnutls_datum_t * root_key, gnutls_datum_t * root_cert, gnutls_datum_t * host_key, gnutls_datum_t * host_cert); -G_GNUC_INTERNAL userpref_error_t userpref_get_certs_as_pem(gnutls_datum_t *pem_root_cert, gnutls_datum_t *pem_host_cert); -G_GNUC_INTERNAL userpref_error_t userpref_set_device_public_key(const char *uuid, gnutls_datum_t public_key); +LIBIMOBILEDEVICE_INTERNAL userpref_error_t userpref_get_keys_and_certs(gnutls_x509_privkey_t root_privkey, gnutls_x509_crt_t root_crt, gnutls_x509_privkey_t host_privkey, gnutls_x509_crt_t host_crt); +LIBIMOBILEDEVICE_INTERNAL userpref_error_t userpref_set_keys_and_certs(gnutls_datum_t * root_key, gnutls_datum_t * root_cert, gnutls_datum_t * host_key, gnutls_datum_t * host_cert); +LIBIMOBILEDEVICE_INTERNAL userpref_error_t userpref_get_certs_as_pem(gnutls_datum_t *pem_root_cert, gnutls_datum_t *pem_host_cert); +LIBIMOBILEDEVICE_INTERNAL userpref_error_t userpref_set_device_public_key(const char *uuid, gnutls_datum_t public_key);  userpref_error_t userpref_remove_device_public_key(const char *uuid); -G_GNUC_INTERNAL int userpref_has_device_public_key(const char *uuid); +LIBIMOBILEDEVICE_INTERNAL int userpref_has_device_public_key(const char *uuid);  userpref_error_t userpref_get_paired_uuids(char ***list, unsigned int *count);  void userpref_get_host_id(char **host_id); diff --git a/tools/Makefile.am b/tools/Makefile.am index bb13eb9..f23b0b1 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,9 +1,13 @@  AM_CPPFLAGS = -I$(top_srcdir)/include -AM_CFLAGS = $(GLOBAL_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(LFS_CFLAGS) -AM_LDFLAGS = $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) +AM_CFLAGS = $(GLOBAL_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(LFS_CFLAGS) +AM_LDFLAGS = $(libgnutls_LIBS) $(libtasn1_LIBS) -bin_PROGRAMS = idevice_id ideviceinfo idevicepair idevicesyslog idevicebackup idevicebackup2 ideviceimagemounter idevicescreenshot ideviceenterrecovery idevicedate +bin_PROGRAMS = idevice_id ideviceinfo idevicepair idevicesyslog ideviceimagemounter idevicescreenshot ideviceenterrecovery idevicedate + +if HAVE_GLIB2 +bin_PROGRAMS += idevicebackup idevicebackup2 +endif  ideviceinfo_SOURCES = ideviceinfo.c  ideviceinfo_CFLAGS = $(AM_CFLAGS) @@ -26,13 +30,13 @@ idevice_id_LDFLAGS = $(AM_LDFLAGS)  idevice_id_LDADD = ../src/libimobiledevice.la  idevicebackup_SOURCES = idevicebackup.c -idevicebackup_CFLAGS = $(AM_CFLAGS) -idevicebackup_LDFLAGS = $(AM_LDFLAGS) +idevicebackup_CFLAGS = $(AM_CFLAGS) $(libglib2_CFLAGS) +idevicebackup_LDFLAGS = $(AM_LDFLAGS) $(libglib2_LIBS)  idevicebackup_LDADD = ../src/libimobiledevice.la  idevicebackup2_SOURCES = idevicebackup2.c -idevicebackup2_CFLAGS = $(AM_CFLAGS) -idevicebackup2_LDFLAGS = $(AM_LDFLAGS) +idevicebackup2_CFLAGS = $(AM_CFLAGS) $(libglib2_CFLAGS) +idevicebackup2_LDFLAGS = $(AM_LDFLAGS) $(libglib2_LIBS)  idevicebackup2_LDADD = ../src/libimobiledevice.la  ideviceimagemounter_SOURCES = ideviceimagemounter.c diff --git a/tools/ideviceimagemounter.c b/tools/ideviceimagemounter.c index 3fb4ac5..b4512f5 100644 --- a/tools/ideviceimagemounter.c +++ b/tools/ideviceimagemounter.c @@ -28,8 +28,9 @@  #include <string.h>  #include <getopt.h>  #include <errno.h> -#include <glib.h>  #include <libgen.h> +#include <time.h> +#include <sys/time.h>  #include <libimobiledevice/libimobiledevice.h>  #include <libimobiledevice/lockdown.h> @@ -165,7 +166,7 @@ static void plist_node_to_string(plist_t node)  	double d;  	uint8_t b;  	uint64_t u = 0; -	GTimeVal tv = { 0, 0 }; +	struct timeval tv = { 0, 0 };  	plist_type t; @@ -214,9 +215,23 @@ static void plist_node_to_string(plist_t node)  	case PLIST_DATE:  		plist_get_date_val(node, (int32_t*)&tv.tv_sec, (int32_t*)&tv.tv_usec); -		s = g_time_val_to_iso8601(&tv); -		printf("%s\n", s); -		free(s); +		{ +			time_t ti = (time_t)tv.tv_sec; +			struct tm *btime = localtime(&ti); +			if (btime) { +				s = (char*)malloc(24); + 				memset(s, 0, 24); +				if (strftime(s, 24, "%Y-%m-%dT%H:%M:%SZ", btime) <= 0) { +					free (s); +					s = NULL; +				} +			} +		} +		if (s) { +			puts(s); +			free(s); +		} +		puts("\n");  		break;  	case PLIST_ARRAY: diff --git a/tools/ideviceinfo.c b/tools/ideviceinfo.c index c5c060e..6633459 100644 --- a/tools/ideviceinfo.c +++ b/tools/ideviceinfo.c @@ -23,7 +23,8 @@  #include <string.h>  #include <errno.h>  #include <stdlib.h> -#include <glib.h> +#include <time.h> +#include <sys/time.h>  #include <libimobiledevice/libimobiledevice.h>  #include <libimobiledevice/lockdown.h> @@ -58,6 +59,36 @@ static const char *domains[] = {  	NULL  }; +static const char base64_str[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char base64_pad = '='; + +static char *base64encode(const unsigned char *buf, size_t size) +{ +	if (!buf || !(size > 0)) return NULL; +	int outlen = (size / 3) * 4; +	char *outbuf = (char*)malloc(outlen+5); // 4 spare bytes + 1 for '\0' +	size_t n = 0; +	size_t m = 0; +	unsigned char input[3]; +	unsigned int output[4]; +	while (n < size) { +		input[0] = buf[n]; +		input[1] = (n+1 < size) ? buf[n+1] : 0; +		input[2] = (n+2 < size) ? buf[n+2] : 0; +		output[0] = input[0] >> 2; +		output[1] = ((input[0] & 3) << 4) + (input[1] >> 4); +		output[2] = ((input[1] & 15) << 2) + (input[2] >> 6); +		output[3] = input[2] & 63; +		outbuf[m++] = base64_str[(int)output[0]]; +		outbuf[m++] = base64_str[(int)output[1]]; +		outbuf[m++] = (n+1 < size) ? base64_str[(int)output[2]] : base64_pad; +		outbuf[m++] = (n+2 < size) ? base64_str[(int)output[3]] : base64_pad; +		n+=3; +	} +	outbuf[m] = 0; // 0-termination! +	return outbuf; +} +  static int indent_level = 0;  static int is_domain_known(char *domain) @@ -121,7 +152,7 @@ static void plist_node_to_string(plist_t node)  	double d;  	uint8_t b;  	uint64_t u = 0; -	GTimeVal tv = { 0, 0 }; +	struct timeval tv = { 0, 0 };  	plist_type t; @@ -161,10 +192,14 @@ static void plist_node_to_string(plist_t node)  	case PLIST_DATA:  		plist_get_data_val(node, &data, &u);  		if (u > 0) { -			s = g_base64_encode((guchar *)data, u); +			s = base64encode((unsigned char*)data, u);  			free(data); -			printf("%s\n", s); -			g_free(s); +			if (s) { +				printf("%s\n", s); +				free(s); +			} else { +				printf("\n"); +			}  		} else {  			printf("\n");  		} @@ -172,9 +207,24 @@ static void plist_node_to_string(plist_t node)  	case PLIST_DATE:  		plist_get_date_val(node, (int32_t*)&tv.tv_sec, (int32_t*)&tv.tv_usec); -		s = g_time_val_to_iso8601(&tv); -		printf("%s\n", s); -		free(s); +		{ +			time_t ti = (time_t)tv.tv_sec; +			struct tm *btime = localtime(&ti); +			if (btime) { +				s = (char*)malloc(24); + 				memset(s, 0, 24); +				if (strftime(s, 24, "%Y-%m-%dT%H:%M:%SZ", btime) <= 0) { +					free (s); +					s = NULL; +				} +			} +		} +		if (s) { +			printf("%s\n", s); +			free(s); +		} else { +			printf("\n"); +		}  		break;  	case PLIST_ARRAY: diff --git a/tools/idevicepair.c b/tools/idevicepair.c index b9676b9..9eebc5c 100644 --- a/tools/idevicepair.c +++ b/tools/idevicepair.c @@ -148,9 +148,10 @@ int main(int argc, char **argv)  		userpref_get_paired_uuids(&uuids, &count);  		for (i = 0; i < count; i++) {  			printf("%s\n", uuids[i]); +			free(uuids[i]);  		}  		if (uuids) -			g_strfreev(uuids); +			free(uuids);  		if (uuid)  			free(uuid);  		return EXIT_SUCCESS; diff --git a/tools/idevicesyslog.c b/tools/idevicesyslog.c index 30e0c55..05e614f 100644 --- a/tools/idevicesyslog.c +++ b/tools/idevicesyslog.c @@ -24,7 +24,6 @@  #include <errno.h>  #include <signal.h>  #include <stdlib.h> -#include <glib.h>  #include <libimobiledevice/libimobiledevice.h>  #include <libimobiledevice/lockdown.h> @@ -123,7 +122,7 @@ int main(int argc, char *argv[])  					break;  				} -				datalen = GUINT32_FROM_BE(datalen); +				datalen = be32toh(datalen);  				if (datalen == 0)  					continue; | 
