summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac16
-rw-r--r--dev/Makefile.am14
-rw-r--r--dev/ideviceclient.c9
-rw-r--r--include/libimobiledevice/installation_proxy.h3
-rw-r--r--include/libimobiledevice/mobilesync.h3
-rw-r--r--src/Makefile.am4
-rw-r--r--src/afc.c28
-rw-r--r--src/afc.h16
-rw-r--r--src/debug.c3
-rw-r--r--src/debug.h17
-rw-r--r--src/house_arrest.h2
-rw-r--r--src/lockdown.c5
-rw-r--r--src/mobilesync.c1
-rw-r--r--src/property_list_service.c5
-rw-r--r--src/restore.c1
-rw-r--r--src/userpref.c492
-rw-r--r--src/userpref.h19
-rw-r--r--tools/Makefile.am18
-rw-r--r--tools/ideviceimagemounter.c25
-rw-r--r--tools/ideviceinfo.c66
-rw-r--r--tools/idevicepair.c3
-rw-r--r--tools/idevicesyslog.c3
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
diff --git a/src/afc.c b/src/afc.c
index fd5143a..a0869ca 100644
--- a/src/afc.c
+++ b/src/afc.c
@@ -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)
diff --git a/src/afc.h b/src/afc.h
index 79078ec..c86828c 100644
--- a/src/afc.h
+++ b/src/afc.h
@@ -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;