diff options
| -rw-r--r-- | configure.ac | 28 | ||||
| -rw-r--r-- | dev/Makefile.am | 3 | ||||
| -rw-r--r-- | dev/main.c | 59 | ||||
| -rw-r--r-- | fdi/31-apple-mobile-device.fdi | 5 | ||||
| -rw-r--r-- | include/libiphone/libiphone.h | 5 | ||||
| -rw-r--r-- | src/AFC.c | 106 | ||||
| -rw-r--r-- | src/AFC.h | 40 | ||||
| -rw-r--r-- | src/Makefile.am | 4 | ||||
| -rw-r--r-- | src/NotificationProxy.c | 263 | ||||
| -rw-r--r-- | src/NotificationProxy.h | 31 | ||||
| -rw-r--r-- | src/usbmux.c | 7 | 
11 files changed, 529 insertions, 22 deletions
| diff --git a/configure.ac b/configure.ac index ec7e11a..a91d9f9 100644 --- a/configure.ac +++ b/configure.ac @@ -68,4 +68,32 @@ fi  AS_COMPILER_FLAGS(GLOBAL_CFLAGS, "-Wall -Wextra -Wmissing-declarations -Wredundant-decls -Wshadow -Wpointer-arith  -Wwrite-strings -Wswitch-default -Wno-unused-parameter")  AC_SUBST(GLOBAL_CFLAGS) +# check for large file support +AC_SYS_LARGEFILE +LFS_CFLAGS='' +if test "$enable_largefile" != no; then +    if test "$ac_cv_sys_file_offset_bits" != 'no'; then +	LFS_CFLAGS="$LFS_CFLAGS -D_FILE_OFFSET_BITS=$ac_cv_sys_file_offset_bits" +    else +	AC_MSG_CHECKING(for native large file support) +	AC_RUN_IFELSE([#include <unistd.h> +	  int main (int argc, char **argv) +	  { +	      exit(!(sizeof(off_t) == 8)); +	  }], +	[ac_cv_sys_file_offset_bits=64; AC_DEFINE(_FILE_OFFSET_BITS,64) +	 AC_MSG_RESULT(yes)], +	[AC_MSG_RESULT(no)]) +    fi +    if test "$ac_cv_sys_large_files" != 'no'; then +	LFS_CFLAGS="$LFS_CFLAGS -D_LARGE_FILES=1" +    fi +    AC_FUNC_FSEEKO +    if test "$ac_cv_sys_largefile_source" != 'no'; then +	LFS_CFLAGS="$LFS_CFLAGS -D_LARGEFILE_SOURCE=1" +    fi +fi +AC_SUBST(LFS_CFLAGS) +  AC_OUTPUT(Makefile src/Makefile include/Makefile fdi/Makefile dev/Makefile swig/Makefile libiphone-1.0.pc) + diff --git a/dev/Makefile.am b/dev/Makefile.am index f976ccc..f7d1109 100644 --- a/dev/Makefile.am +++ b/dev/Makefile.am @@ -1,6 +1,6 @@  INCLUDES = -I$(top_srcdir)/include -AM_CFLAGS = $(GLOBAL_CFLAGS) $(libusb_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) -g +AM_CFLAGS = $(GLOBAL_CFLAGS) $(libusb_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(LFS_CFLAGS)  AM_LDFLAGS = $(libusb_LIBS) $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS)  bin_PROGRAMS = iphoneclient lckd-client afccheck msyncclient @@ -22,3 +22,4 @@ msyncclient_SOURCES = msyncclient.c  msyncclient_CFLAGS = $(AM_CFLAGS)  msyncclient_LDFLAGS = $(AM_LDFLAGS)  msyncclient_LDADD = ../src/libiphone.la + @@ -27,12 +27,51 @@  #include <libiphone/libiphone.h>  #include "../src/utils.h" +void perform_syncWillStart(iphone_device_t phone, iphone_lckd_client_t control) +{ +	int nport = 0; +	iphone_np_client_t np; + +	iphone_lckd_start_service(control, "com.apple.mobile.notification_proxy", &nport); +	if (nport) { +		printf("::::::::::::::: np was started ::::::::::::\n"); +		iphone_np_new_client(phone, 3555, nport, &np); +		if (np) { +			printf("::::::::: PostNotification com.apple.itunes-mobdev.syncWillStart\n"); +			iphone_np_post_notification(np, "com.apple.itunes-mobdev.syncWillStart"); +			iphone_np_free_client(np); +		} +	} else { +		printf("::::::::::::::: np was NOT started ::::::::::::\n"); +	} +} + +void perform_syncDidStart(iphone_device_t phone, iphone_lckd_client_t control) +{ +	int nport = 0; +	iphone_np_client_t np; + +	iphone_lckd_start_service(control, "com.apple.mobile.notification_proxy", &nport); +	if (nport) { +		printf("::::::::::::::: np was started ::::::::::::\n"); +		sleep(1); +		iphone_np_new_client(phone, 3555, nport, &np); +		if (np) { +			printf("::::::::: PostNotification com.apple.itunes-mobdev.syncDidStart\n"); +			iphone_np_post_notification(np, "com.apple.itunes-mobdev.syncDidStart"); +			iphone_np_free_client(np); +		} +	} else { +		printf("::::::::::::::: np was NOT started ::::::::::::\n"); +	} +}  int main(int argc, char *argv[])  {  	int bytes = 0, port = 0, i = 0;  	iphone_lckd_client_t control = NULL;  	iphone_device_t phone = NULL; +	iphone_afc_file_t lockfile = NULL;  	if (argc > 1 && !strcasecmp(argv[1], "--debug")) {  		iphone_set_debug(1); @@ -64,6 +103,16 @@ int main(int argc, char *argv[])  		iphone_afc_client_t afc = NULL;  		iphone_afc_new_client(phone, 3432, port, &afc);  		if (afc) { +			perform_syncWillStart(phone, control); + +			iphone_afc_open_file(afc, "/com.apple.itunes.lock_sync", IPHONE_AFC_FILE_WRITE, &lockfile); +			if (lockfile) { +				printf("locking file\n"); +				iphone_afc_lock_file(afc, lockfile, 2 | 4); + +				perform_syncDidStart(phone, control); +			} +  			char **dirs = NULL;  			iphone_afc_get_dir_list(afc, "/eafaedf", &dirs);  			if (!dirs) @@ -138,7 +187,17 @@ int main(int argc, char *argv[])  				printf("Couldn't read!\n");  			free(threeletterword);  			iphone_afc_close_file(afc, my_file); +		} + +		if (lockfile) { +			printf("XXX sleeping 2 seconds\n"); +			sleep(2); + +			printf("XXX unlocking file\n"); +			iphone_afc_lock_file(afc, lockfile, 8 | 4); +			printf("XXX closing file\n"); +			iphone_afc_close_file(afc, lockfile);  		}  		iphone_afc_free_client(afc);  	} else { diff --git a/fdi/31-apple-mobile-device.fdi b/fdi/31-apple-mobile-device.fdi index 3e9ccc9..d598409 100644 --- a/fdi/31-apple-mobile-device.fdi +++ b/fdi/31-apple-mobile-device.fdi @@ -5,11 +5,12 @@        <match key="usb.vendor_id" int="0x05ac">          <match key="usb.product_id" compare_ge="0x1290">            <match key="usb.product_id" compare_le="0x1293"> -            <append key="info.capabilities" type="strlist">afc</append> +            <match key="usb.interface.number" int="0x1"> +              <append key="info.capabilities" type="strlist">afc</append> +            </match>            </match>          </match>        </match>      </match>    </device>  </deviceinfo> - diff --git a/include/libiphone/libiphone.h b/include/libiphone/libiphone.h index 9823bed..0035e2f 100644 --- a/include/libiphone/libiphone.h +++ b/include/libiphone/libiphone.h @@ -81,6 +81,9 @@ typedef struct iphone_afc_file_int *iphone_afc_file_t;  struct iphone_msync_client_int;  typedef struct iphone_msync_client_int *iphone_msync_client_t; +struct iphone_np_client_int; +typedef struct iphone_np_client_int *iphone_np_client_t; +  //debug related functions  #define DBGMASK_ALL        0xFFFF  #define DBGMASK_NONE       0x0000 @@ -124,6 +127,7 @@ iphone_error_t iphone_afc_get_dir_list ( iphone_afc_client_t client, const char  iphone_error_t iphone_afc_get_file_attr ( iphone_afc_client_t client, const char *filename, struct stat *stbuf );  iphone_error_t iphone_afc_open_file ( iphone_afc_client_t client, const char *filename, iphone_afc_file_mode_t file_mode, iphone_afc_file_t *file );  iphone_error_t iphone_afc_close_file ( iphone_afc_client_t client, iphone_afc_file_t file); +iphone_error_t iphone_afc_lock_file ( iphone_afc_client_t client, iphone_afc_file_t file, int operation);  iphone_error_t iphone_afc_read_file ( iphone_afc_client_t client, iphone_afc_file_t file, char *data, int length, uint32_t *bytes);  iphone_error_t iphone_afc_write_file ( iphone_afc_client_t client, iphone_afc_file_t file, const char *data, int length, uint32_t *bytes);  iphone_error_t iphone_afc_seek_file ( iphone_afc_client_t client, iphone_afc_file_t file, int seekpos); @@ -131,6 +135,7 @@ iphone_error_t iphone_afc_truncate_file ( iphone_afc_client_t client, iphone_afc  iphone_error_t iphone_afc_delete_file ( iphone_afc_client_t client, const char *path);  iphone_error_t iphone_afc_rename_file ( iphone_afc_client_t client, const char *from, const char *to);  iphone_error_t iphone_afc_mkdir ( iphone_afc_client_t client, const char *dir); +iphone_error_t iphone_afc_truncate(iphone_afc_client_t client, const char *path, off_t newsize); @@ -178,7 +178,7 @@ static int dispatch_AFC_packet(iphone_afc_client_t client, const char *data, int  		log_debug_msg("dispatch_AFC_packet: sent the first now go with the second\n");  		log_debug_msg("Length: %i\n", length - offset);  		log_debug_msg("Buffer: \n"); -		log_debug_msg(data + offset); +		log_debug_buffer(data + offset, length - offset);  		iphone_mux_send(client->connection, data + offset, length - offset, &bytes);  		return bytes; @@ -916,6 +916,63 @@ iphone_error_t iphone_afc_close_file(iphone_afc_client_t client, iphone_afc_file  	return IPHONE_E_SUCCESS;  } +/** Locks or unlocks a file on the phone.  + * + * makes use of flock, see + * http://developer.apple.com/documentation/Darwin/Reference/ManPages/man2/flock.2.html + * + * operation (same as in sys/file.h on linux): + * + * LOCK_SH   1    // shared lock + * LOCK_EX   2   // exclusive lock + * LOCK_NB   4   // don't block when locking + * LOCK_UN   8   // unlock + * + * @param client The client to close the file with. + * @param file A pointer to an AFCFile struct containing the file handle of the + *        file to close. + * @operation the lock or unlock operation to perform. + */ +iphone_error_t iphone_afc_lock_file(iphone_afc_client_t client, iphone_afc_file_t file, int operation) +{ +	if (!client || !file) +		return IPHONE_E_INVALID_ARG; +	char *buffer = malloc(16); +	uint32_t zero = 0; +	int bytes = 0; +	uint64_t op = operation; + +	afc_lock(client); + +	log_debug_msg("afc_lock_file: File handle %i\n", file->filehandle); + +	// Send command +	memcpy(buffer, &file->filehandle, sizeof(uint32_t)); +	memcpy(buffer + sizeof(uint32_t), &zero, sizeof(zero)); +	memcpy(buffer + 8, &op, 8); + +	client->afc_packet->operation = AFC_FILE_LOCK; +	client->afc_packet->entire_length = client->afc_packet->this_length = 0; +	bytes = dispatch_AFC_packet(client, buffer, 15); +	free(buffer); +	buffer = NULL; + +	if (bytes <= 0) { +		afc_unlock(client); +		log_debug_msg("fuck\n"); +		return IPHONE_E_UNKNOWN_ERROR; +	} +	// Receive the response +	bytes = receive_AFC_data(client, &buffer); +	log_debug_msg("%s: receiving response (%d bytes)\n", __func__, bytes); +	if (buffer) { +		log_debug_buffer(buffer, bytes); +		free(buffer); +	} +	afc_unlock(client); +	return IPHONE_E_SUCCESS; +} +  /** Seeks to a given position of a pre-opened file on the phone.    *    * @param client The client to use to seek to the position. @@ -1016,6 +1073,53 @@ iphone_error_t iphone_afc_truncate_file(iphone_afc_client_t client, iphone_afc_f  	}  } +/** Sets the size of a file on the phone without prior opening it. + *  + * @param client The client to use to set the file size. + * @param path The path of the file to be truncated. + * @param newsize The size to set the file to.  + *  + * @return IPHONE_E_SUCCESS if everything went well, IPHONE_E_INVALID_ARG + *         if arguments are NULL or invalid, IPHONE_E_NOT_ENOUGH_DATA otherwise. + */ +iphone_error_t iphone_afc_truncate(iphone_afc_client_t client, const char *path, off_t newsize) +{ +	char *response = NULL; +	char *send = (char *) malloc(sizeof(char) * (strlen(path) + 1 + 8)); +	int bytes = 0; +	uint64_t size_requested = newsize; + +	if (!client || !path || !client->afc_packet || !client->connection) +		return IPHONE_E_INVALID_ARG; + +	afc_lock(client); + +	// Send command +	memcpy(send, &size_requested, 8); +	memcpy(send + 8, path, strlen(path) + 1); +	client->afc_packet->entire_length = client->afc_packet->this_length = 0; +	client->afc_packet->operation = AFC_TRUNCATE; +	bytes = dispatch_AFC_packet(client, send, 8 + strlen(path)); +	free(send); +	if (bytes <= 0) { +		afc_unlock(client); +		return IPHONE_E_NOT_ENOUGH_DATA; +	} +	// Receive response +	bytes = receive_AFC_data(client, &response); +	if (response) +		free(response); + +	afc_unlock(client); + +	if (bytes < 0) { +		return IPHONE_E_NOT_ENOUGH_DATA; +	} else { +		return IPHONE_E_SUCCESS; +	} +} + +  uint32_t iphone_afc_get_file_handle(iphone_afc_file_t file)  {  	return file->filehandle; @@ -58,20 +58,34 @@ struct iphone_afc_file_int {  enum {  	AFC_ERROR = 0x00000001, -	AFC_GET_INFO = 0x0000000a, -	AFC_GET_DEVINFO = 0x0000000b, -	AFC_LIST_DIR = 0x00000003, -	AFC_MAKE_DIR = 0x00000009, -	AFC_DELETE = 0x00000008, -	AFC_RENAME = 0x00000018,  	AFC_SUCCESS_RESPONSE = 0x00000002, -	AFC_FILE_OPEN = 0x0000000d, -	AFC_FILE_CLOSE = 0x00000014, -	AFC_FILE_SEEK = 0x00000011, -	AFC_FILE_TRUNCATE = 0x00000015, -	AFC_FILE_HANDLE = 0x0000000e, -	AFC_READ = 0x0000000f, -	AFC_WRITE = 0x00000010 +	AFC_LIST_DIR = 0x00000003,      // ReadDir +	// 0x00000004                   // ReadFile +	// 0x00000005                   // WriteFile +	// 0x00000006                   // WritePart +	AFC_TRUNCATE = 0x00000007,      // Truncate +	AFC_DELETE = 0x00000008,        // RemovePath +	AFC_MAKE_DIR = 0x00000009,      // MakeDir +	AFC_GET_INFO = 0x0000000a,      // GetFileInfo +	AFC_GET_DEVINFO = 0x0000000b,   // GetDeviceInfo +	// 0x0000000c  // same as 5, but writes to temp file, then renames it. +	AFC_FILE_OPEN = 0x0000000d,     // FileRefOpen +	AFC_FILE_HANDLE = 0x0000000e,   // _unknownPacket +	AFC_READ = 0x0000000f,          // FileRefRead +	AFC_WRITE = 0x00000010,         // FileRefWrite +	AFC_FILE_SEEK = 0x00000011,     // FileRefSeek +	AFC_FILE_TELL = 0x00000012,     // FileRefTell +	// 0x00000013                   // _unknownPacket +	AFC_FILE_CLOSE = 0x00000014,    // FileRefClose +	AFC_FILE_TRUNCATE = 0x00000015, // FileRefSetFileSize (ftruncate) +	// 0x00000016                   // SetFatalError +	// 0x00000017                   // SetConnectionOptions +	AFC_RENAME = 0x00000018,        // RenamePath +	// 0x00000019                   // SetFSBlockSize (0x800000) +	// 0x0000001A                   // SetBlockSize (0x800000) +	AFC_FILE_LOCK = 0x0000001B,     // FileRefLock +	AFC_MAKE_LINK = 0x0000001C      // MakeLink  }; +  uint32_t iphone_afc_get_file_handle(iphone_afc_file_t file); diff --git a/src/Makefile.am b/src/Makefile.am index 039632f..71667ae 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,6 @@  INCLUDES = -I$(top_srcdir)/include -AM_CFLAGS = $(GLOBAL_CFLAGS) $(libusb_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(libplist_CFLAGS) -g +AM_CFLAGS = $(GLOBAL_CFLAGS) $(libusb_CFLAGS) $(libglib2_CFLAGS) $(libgnutls_CFLAGS) $(libtasn1_CFLAGS) $(libgthread2_CFLAGS) $(libplist_CFLAGS) $(LFS_CFLAGS)  AM_LDFLAGS = $(libusb_LIBS) $(libglib2_LIBS) $(libgnutls_LIBS) $(libtasn1_LIBS) $(libgthread2_LIBS) $(libplist_LIBS)  bin_PROGRAMS = libiphone-initconf @@ -12,4 +12,4 @@ libiphone_initconf_LDFLAGS = $(libgthread2_LIBS) $(AM_LDFLAGS)  lib_LTLIBRARIES = libiphone.la -libiphone_la_SOURCES = usbmux.c iphone.c lockdown.c AFC.c userpref.c utils.c MobileSync.c +libiphone_la_SOURCES = usbmux.c iphone.c lockdown.c AFC.c NotificationProxy.c userpref.c utils.c MobileSync.c diff --git a/src/NotificationProxy.c b/src/NotificationProxy.c new file mode 100644 index 0000000..eec7857 --- /dev/null +++ b/src/NotificationProxy.c @@ -0,0 +1,263 @@ +/* + * NotificationProxy.c + * Notification Proxy implementation. + * + * Copyright (c) 2009 Nikias Bassen, All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA  + */ + +#include <stdio.h> +#include <plist/plist.h> +#include "NotificationProxy.h" +#include "utils.h" + +/** Locks an NP client, done for thread safety stuff. + * + * @param client The NP + */ +static void np_lock(iphone_np_client_t client) +{ +	log_debug_msg("NP: Locked\n"); +	g_mutex_lock(client->mutex); +} + +/** Unlocks an NP client, done for thread safety stuff. + *  + * @param client The NP + */ +static void np_unlock(iphone_np_client_t client) +{ +	log_debug_msg("NP: Unlocked\n"); +	g_mutex_unlock(client->mutex); +} + +/** Makes a connection to the NP service on the phone.  + *  + * @param phone The iPhone to connect on. + * @param s_port The source port.  + * @param d_port The destination port.  + *  + * @return A handle to the newly-connected client or NULL upon error. + */ +iphone_error_t iphone_np_new_client ( iphone_device_t device, int src_port, int dst_port, iphone_np_client_t *client ) +{ +	int ret = IPHONE_E_SUCCESS; + +	//makes sure thread environment is available +	if (!g_thread_supported()) +		g_thread_init(NULL); +	iphone_np_client_t client_loc = (iphone_np_client_t) malloc(sizeof(struct iphone_np_client_int)); + +	if (!device) +		return IPHONE_E_INVALID_ARG; + +	// Attempt connection +	client_loc->connection = NULL; +	ret = iphone_mux_new_client(device, src_port, dst_port, &client_loc->connection); +	if (IPHONE_E_SUCCESS != ret || !client_loc->connection) { +		free(client_loc); +		return ret; +	} + +	client_loc->mutex = g_mutex_new(); + +	*client = client_loc; +	return IPHONE_E_SUCCESS;	 +} + +/** Disconnects an NP client from the phone. + *  + * @param client The client to disconnect. + */ +iphone_error_t iphone_np_free_client ( iphone_np_client_t client ) +{ +	if (!client || !client->connection ) +		return IPHONE_E_INVALID_ARG; + +	iphone_mux_free_client(client->connection); +	free(client); +	return IPHONE_E_SUCCESS; +} + +/** Sends a notification to the NP client. + * + * notification messages seen so far: + *   com.apple.itunes-mobdev.syncWillStart + *   com.apple.itunes-mobdev.syncDidStart + * + * @param client The client to send to + * @param notification The notification Message + */ +iphone_error_t iphone_np_post_notification( iphone_np_client_t client, const char *notification ) +{ +	char *XML_content = NULL; +	uint32_t length = 0; +	int bytes = 0; +	iphone_error_t ret; +	unsigned char sndbuf[4096]; +	int sndlen = 0; +	int nlen = 0; +	plist_t dict = NULL; + +	if (!client || !notification) { +		return IPHONE_E_INVALID_ARG; +	} +	np_lock(client); + +	dict = plist_new_dict(); +	plist_add_sub_key_el(dict, "Command"); +	plist_add_sub_string_el(dict, "PostNotification"); +	plist_add_sub_key_el(dict, "Name"); +	plist_add_sub_string_el(dict, notification); +	plist_to_xml(dict, &XML_content, &length); + +	nlen = htonl(length); + +	memcpy(sndbuf+sndlen, &nlen, 4); +	sndlen += 4; +	memcpy(sndbuf+sndlen, XML_content, length); +	sndlen += length; + +	plist_free(dict); +	dict = NULL; +	free(XML_content); +	XML_content = NULL; + +	dict = plist_new_dict(); +	plist_add_sub_key_el(dict, "Command"); +	plist_add_sub_string_el(dict, "Shutdown"); +	plist_to_xml(dict, &XML_content, &length); + +	nlen = htonl(length); + +	memcpy(sndbuf+sndlen, &nlen, 4); +	sndlen+=4; + +	memcpy(sndbuf+sndlen, XML_content, length); +	sndlen+=length; + +	plist_free(dict); +	dict = NULL; +	free(XML_content); +	XML_content = NULL; + +	log_debug_buffer(sndbuf, sndlen); + +	iphone_mux_send(client->connection, sndbuf, sndlen, &bytes); +        if (bytes <= 0) { +		np_unlock(client); +		return bytes; +	} + +	np_unlock(client); +	return bytes; +} + +/** Notifies the iphone to send a notification on certain events. + * + * observation messages seen so far: + *   com.apple.itunes-client.syncCancelRequest + *   com.apple.itunes-client.syncSuspendRequest + *   com.apple.itunes-client.syncResumeRequest + *   com.apple.mobile.lockdown.phone_number_changed + *   com.apple.mobile.lockdown.device_name_changed + *   com.apple.springboard.attemptactivation + *   com.apple.mobile.data_sync.domain_changed + *   com.apple.mobile.application_installed + *   com.apple.mobile.application_uninstalled + * + * @param client The client to send to + */ +iphone_error_t iphone_np_observe_notification( iphone_np_client_t client ) +{ +	plist_t dict = NULL; +	char *XML_content = NULL; +	uint32_t length = 0; +	int bytes = 0; +	iphone_error_t ret; +	unsigned char sndbuf[4096]; +	int sndlen = 0; +	int nlen = 0; +	int i=0; +	const char *notifications[10] = { +	    "com.apple.itunes-client.syncCancelRequest", +	    "com.apple.itunes-client.syncSuspendRequest", +	    "com.apple.itunes-client.syncResumeRequest", +	    "com.apple.mobile.lockdown.phone_number_changed", +	    "com.apple.mobile.lockdown.device_name_changed", +	    "com.apple.springboard.attemptactivation", +	    "com.apple.mobile.data_sync.domain_changed", +	    "com.apple.mobile.application_installed", +	    "com.apple.mobile.application_uninstalled", +	    NULL}; + +	sndlen = 0; + +	if (!client) { +		return IPHONE_E_INVALID_ARG; +	} +	np_lock(client); + +	while (notifications[i]) { + +		dict = plist_new_dict(); +		plist_add_sub_key_el(dict, "Command"); +		plist_add_sub_string_el(dict, "ObserveNotification"); +		plist_add_sub_key_el(dict, "Name"); +		plist_add_sub_string_el(dict, notifications[i++]); +		plist_to_xml(dict, &XML_content, &length); + +		nlen = htonl(length); +		memcpy(sndbuf+sndlen, &nlen, 4); +		sndlen += 4; +		memcpy(sndbuf+sndlen, XML_content, length); +		sndlen += length; +  +		plist_free(dict); +		dict = NULL; +		free(XML_content); +		XML_content = NULL; +	} + +	dict = plist_new_dict(); +	plist_add_sub_key_el(dict, "Command"); +	plist_add_sub_string_el(dict, "Shutdown"); +	plist_to_xml(dict, &XML_content, &length); + +	nlen = htonl(length); + +	memcpy(sndbuf+sndlen, &nlen, 4); +	sndlen+=4; + +	memcpy(sndbuf+sndlen, XML_content, length); +	sndlen+=length; + +	plist_free(dict); +	dict = NULL; +	free(XML_content); +	XML_content = NULL; + +	log_debug_buffer(sndbuf, sndlen); + +	iphone_mux_send(client->connection, sndbuf, sndlen, &bytes); +        if (bytes <= 0) { +		np_unlock(client); +		return bytes; +	} + +	np_unlock(client); +	return bytes; +} diff --git a/src/NotificationProxy.h b/src/NotificationProxy.h new file mode 100644 index 0000000..57ad751 --- /dev/null +++ b/src/NotificationProxy.h @@ -0,0 +1,31 @@ +/* + * NotificationProxy.h + * Notification Proxy header file. + * + * Copyright (c) 2009 Nikias Bassen, All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + *  + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + *  + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA  + */ +#include "libiphone/libiphone.h" +#include "usbmux.h" +#include "iphone.h" + +#include <glib.h> + +struct iphone_np_client_int { +	iphone_umux_client_t connection; +	GMutex *mutex; +}; + diff --git a/src/usbmux.c b/src/usbmux.c index 5eaa1d1..22ce588 100644 --- a/src/usbmux.c +++ b/src/usbmux.c @@ -309,7 +309,8 @@ iphone_error_t iphone_mux_recv(iphone_umux_client_t client, char *data, uint32_t  			}  			// Since we were able to fill the data straight from our buffer, we can just return datalen. See 2a above. -			return datalen; +			*recv_bytes = datalen; +			return IPHONE_E_SUCCESS;  		} else {  			memcpy(data, client->recv_buffer, client->r_len);  			free(client->recv_buffer);	// don't need to deal with anymore, but... @@ -362,10 +363,10 @@ iphone_error_t iphone_mux_recv(iphone_umux_client_t client, char *data, uint32_t  	if ((bytes - 28) > datalen) {  		// Copy what we need into the data, buffer the rest because we can.  		memcpy(data + offset, buffer + 28, datalen);	// data+offset: see #2b, above -		complex = client->r_len + (bytes - 28) - datalen; +		complex = client->r_len + ((bytes - 28) - datalen);  		client->recv_buffer = (char *) realloc(client->recv_buffer, (sizeof(char) * complex));  		client->r_len = complex; -		complex = client->r_len - (bytes - 28) - datalen; +		complex = client->r_len - ((bytes - 28) - datalen);  		memcpy(client->recv_buffer + complex, buffer + 28 + datalen, (bytes - 28) - datalen);  		free(buffer);  		client->header->ocnt += bytes - 28; | 
