diff options
| author | 2008-08-06 21:04:09 -0700 | |
|---|---|---|
| committer | 2008-08-06 21:04:09 -0700 | |
| commit | bef655966045af34e1f20a7211f0cab2e7e79001 (patch) | |
| tree | 590b41891fab48af0c3f35431f7476bbc2b4b0a2 | |
| parent | d81a3c5c412cca9b8327d6d27625bc52650e9651 (diff) | |
| download | libimobiledevice-bef655966045af34e1f20a7211f0cab2e7e79001.tar.gz libimobiledevice-bef655966045af34e1f20a7211f0cab2e7e79001.tar.bz2 | |
Adds locking and fixes a minor bug in mux_recv
Signed-off-by: Matt Colyer <matt@colyer.name>
| -rw-r--r-- | src/AFC.c | 54 | ||||
| -rw-r--r-- | src/AFC.h | 1 | ||||
| -rw-r--r-- | src/ifuse.c | 2 | ||||
| -rw-r--r-- | src/iphone.c | 2 | ||||
| -rw-r--r-- | src/usbmux.c | 9 | 
5 files changed, 58 insertions, 10 deletions
| @@ -26,6 +26,21 @@ const int MAXIMUM_PACKET_SIZE = (2 << 15) - 32;  extern int debug; + +/* Locking, for thread-safety (well... kind of, hehe) */ +void afc_lock(AFClient *client) { +	while (client->lock) { +		sleep(200); +	} +	client->lock = 1; +} + +void afc_unlock(AFClient *client) { // just to be pretty  +	client->lock = 0;  +} + +/* main AFC functions */ +  AFClient *afc_connect(iPhone *phone, int s_port, int d_port) {  	if (!phone) return NULL;  	AFClient *client = (AFClient*)malloc(sizeof(AFClient)); @@ -39,6 +54,7 @@ AFClient *afc_connect(iPhone *phone, int s_port, int d_port) {  			client->afc_packet->header1 = 0x36414643;  			client->afc_packet->header2 = 0x4141504C;  			client->file_handle = 0; +			client->lock = 0;  			return client;  		} else {  			mux_close_connection(client->connection); @@ -184,6 +200,7 @@ int receive_AFC_data(AFClient *client, char **dump_here) {  	final_buffer = (char*)malloc(sizeof(char) * recv_len);  	while(current_count < recv_len){  		bytes = mux_recv(client->connection, buffer, recv_len-current_count); +		if (debug) printf("receive_AFC_data: still collecting packets\n");  		if (bytes < 0)  		{  			if(debug) printf("receive_AFC_data: mux_recv failed: %d\n", bytes); @@ -194,6 +211,12 @@ int receive_AFC_data(AFClient *client, char **dump_here) {  			if(debug) printf("receive_AFC_data: mux_recv delivered too much data\n");  			break;  		} +		if (strstr(buffer, "CFA6LPAA")) { +			if (debug) printf("receive_AFC_data: WARNING: there is AFC data in this packet at %i\n", strstr(buffer, "CFA6LPAA") - buffer); +			if (debug) printf("receive_AFC_data: the total packet length is %i\n", bytes); +			//continue; // but we do need to continue because packets/headers != data +		} +			  		memcpy(final_buffer+current_count, buffer, bytes);  		current_count += bytes;  	} @@ -211,18 +234,20 @@ int receive_AFC_data(AFClient *client, char **dump_here) {  }  char **afc_get_dir_list(AFClient *client, const char *dir) { +	afc_lock(client);  	client->afc_packet->operation = AFC_LIST_DIR;  	int bytes = 0;  	char *blah = NULL, **list = NULL;  	client->afc_packet->entire_length = client->afc_packet->this_length = 0;  	bytes = dispatch_AFC_packet(client, dir, strlen(dir)); -	if (!bytes) return NULL; +	if (!bytes) { afc_unlock(client); return NULL; }  	bytes = receive_AFC_data(client, &blah); -	if (!bytes && !blah) return NULL; +	if (!bytes && !blah) { afc_unlock(client); return NULL; }  	list = make_strings_list(blah, bytes);  	free(blah); +	afc_unlock(client);  	return list;  } @@ -243,23 +268,24 @@ char **make_strings_list(char *tokens, int true_length) {  int afc_delete_file(AFClient *client, const char *path) {  	if (!client || !path || !client->afc_packet || !client->connection) return 0; - +	afc_lock(client);  	char *receive = NULL;  	client->afc_packet->this_length = client->afc_packet->entire_length = 0;  	client->afc_packet->operation = AFC_DELETE;  	int bytes;  	bytes = dispatch_AFC_packet(client, path, strlen(path)); -	if (bytes <= 0) return 0; +	if (bytes <= 0) { afc_unlock(client); return 0; }  	bytes = receive_AFC_data(client, &receive);  	free(receive); -	if (bytes <= 0) return 0; +	afc_unlock(client); +	if (bytes <= 0) { return 0; }  	else return 1;  }  int afc_rename_file(AFClient *client, const char *from, const char *to) {  	if (!client || !from || !to || !client->afc_packet || !client->connection) return 0; -	 +	afc_lock(client);  	char *receive = NULL;  	char *send = (char*)malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32)));  	int bytes = 0; @@ -271,10 +297,11 @@ int afc_rename_file(AFClient *client, const char *from, const char *to) {  	client->afc_packet->entire_length = client->afc_packet->this_length = 0;  	client->afc_packet->operation = AFC_RENAME;  	bytes = dispatch_AFC_packet(client, send, strlen(to) + strlen(from) + 2); -	if (bytes <= 0) return 0; +	if (bytes <= 0) { afc_unlock(client); return 0; }  	bytes = receive_AFC_data(client, &receive);  	free(receive); +	afc_unlock(client);  	if (bytes <= 0) return 0;  	else return 1;  } @@ -284,6 +311,7 @@ int afc_rename_file(AFClient *client, const char *from, const char *to) {  AFCFile *afc_get_file_info(AFClient *client, const char *path) {  	client->afc_packet->operation = AFC_GET_INFO;  	client->afc_packet->entire_length = client->afc_packet->this_length = 0; +	afc_lock(client);  	dispatch_AFC_packet(client, path, strlen(path));  	char *received, **list; @@ -293,6 +321,7 @@ AFCFile *afc_get_file_info(AFClient *client, const char *path) {  	length = receive_AFC_data(client, &received);  	list = make_strings_list(received, length);  	free(received); +	afc_unlock(client); // the rest is just interpretation anyway  	if (list) {  		my_file = (AFCFile *)malloc(sizeof(AFCFile));  		for (i = 0; strcmp(list[i], ""); i++) { @@ -323,6 +352,7 @@ AFCFile *afc_get_file_info(AFClient *client, const char *path) {  AFCFile *afc_open_file(AFClient *client, const char *filename, uint32 file_mode) {  	if (file_mode != AFC_FILE_READ && file_mode != AFC_FILE_WRITE) return NULL;  	if (!client ||!client->connection || !client->afc_packet) return NULL; +	afc_lock(client);  	char *further_data = (char*)malloc(sizeof(char) * (8 + strlen(filename) + 1));  	AFCFile *file_infos = NULL;  	memcpy(further_data, &file_mode, 4); @@ -338,10 +368,12 @@ AFCFile *afc_open_file(AFClient *client, const char *filename, uint32 file_mode)  	free(further_data);  	if (bytes <= 0) {  		if (debug) printf("didn't read enough\n"); +		afc_unlock(client);  		return NULL;  	} else {  		length_thing = receive_AFC_data(client, &further_data);  		if (length_thing && further_data) { +			afc_unlock(client); // don't want to hang on the next call... and besides, it'll re-lock, do its thing, and unlock again anyway.  			file_infos = afc_get_file_info(client, filename);  			memcpy(&file_infos->filehandle, further_data, 4);  			return file_infos; @@ -357,6 +389,8 @@ AFCFile *afc_open_file(AFClient *client, const char *filename, uint32 file_mode)  int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) {  	if (!client || !client->afc_packet || !client->connection || !file) return -1;  	AFCFilePacket *packet = (AFCFilePacket*)malloc(sizeof(AFCFilePacket)); +	if (debug) printf("afc_read_file called for length %i\n"); +	afc_lock(client);  	char *input = NULL;  	packet->unknown1 = packet->unknown2 = 0;  	packet->filehandle = file->filehandle; @@ -369,6 +403,7 @@ int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) {  	if (bytes > 0) {  		bytes = receive_AFC_data(client, &input); +		afc_unlock(client);  		if (bytes < 0) {  			if (input) free(input);  			return -1; @@ -382,6 +417,7 @@ int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) {  			return (bytes > length) ? length : bytes;  		}  	} else { +		afc_unlock(client);  		return -1;  	}  	return 0; @@ -390,6 +426,7 @@ int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) {  int afc_write_file(AFClient *client, AFCFile *file, const char *data, int length) {  	char *acknowledgement = NULL;  	if (!client ||!client->afc_packet || !client->connection || !file) return -1; +	afc_lock(client);  	client->afc_packet->this_length = sizeof(AFCPacket) + 8;  	client->afc_packet->entire_length = client->afc_packet->this_length + length;  	client->afc_packet->operation = AFC_WRITE; @@ -407,6 +444,7 @@ int afc_write_file(AFClient *client, AFCFile *file, const char *data, int length  	zero = bytes;  	bytes = receive_AFC_data(client, &acknowledgement); +	afc_unlock(client);  	if (bytes <= 0) {  		if (debug) printf("afc_write_file: uh oh?\n");  	} @@ -418,6 +456,7 @@ void afc_close_file(AFClient *client, AFCFile *file) {  	char *buffer = malloc(sizeof(char) * 8);  	uint32 zero = 0;  	if (debug) printf("File handle %i\n", file->filehandle); +	afc_lock(client);  	memcpy(buffer, &file->filehandle, sizeof(uint32));  	memcpy(buffer+sizeof(uint32), &zero, sizeof(zero));  	client->afc_packet->operation = AFC_FILE_CLOSE; @@ -430,6 +469,7 @@ void afc_close_file(AFClient *client, AFCFile *file) {  	if (!bytes) return;  	bytes = receive_AFC_data(client, &buffer); +	afc_unlock(client);  	return;  	if (buffer) free(buffer); // we're *SUPPOSED* to get an "error" here.   } @@ -38,6 +38,7 @@ typedef struct {  	usbmux_connection *connection;  	AFCPacket *afc_packet;  	int file_handle; +	int lock;  } AFClient;  typedef struct { diff --git a/src/ifuse.c b/src/ifuse.c index f33eaaa..7d6f72a 100644 --- a/src/ifuse.c +++ b/src/ifuse.c @@ -41,7 +41,7 @@  GHashTable *file_handles;  int fh_index = 0; -int debug = 0; +int debug = 1;  static int ifuse_getattr(const char *path, struct stat *stbuf) {  	int res = 0; diff --git a/src/iphone.c b/src/iphone.c index 6000a19..426b629 100644 --- a/src/iphone.c +++ b/src/iphone.c @@ -163,7 +163,7 @@ int send_to_phone(iPhone *phone, char *data, int datalen) {   * @param data Where to put data read   * @param datalen How much data to read in   *  - * @returns How many bytes were read in, or -1 on error. + * @return How many bytes were read in, or -1 on error.   */  int recv_from_phone(iPhone *phone, char *data, int datalen) {  	if (!phone) return -1; diff --git a/src/usbmux.c b/src/usbmux.c index 235a1f2..d79ee47 100644 --- a/src/usbmux.c +++ b/src/usbmux.c @@ -301,8 +301,15 @@ int mux_recv(usbmux_connection *connection, char *data, uint32 datalen) {  		for (i = 0; i < connections; i++) {  			if (connlist[i]->header->sport == header->dport && connlist[i]->header->dport == header->sport) {  				// we have a winner. +				char *nfb = (char*)malloc(sizeof(char) * (connlist[i]->r_len + (bytes - 28))); +				if (connlist[i]->recv_buffer && connlist[i]->r_len) { +					memcpy(nfb, connlist[i]->recv_buffer, connlist[i]->r_len); +					free(connlist[i]->recv_buffer); +				}  				connlist[i]->r_len += bytes - 28; -				connlist[i]->recv_buffer = (char*)realloc(connlist[i]->recv_buffer, sizeof(char) * connection->r_len); // grow their buffer +				//connlist[i]->recv_buffer = (char*)realloc(connlist[i]->recv_buffer, sizeof(char) * connection->r_len); // grow their buffer +				connlist[i]->recv_buffer = nfb; +				nfb = NULL; // A cookie for you if you can guess what "nfb" means.   				complex = connlist[i]->r_len - (bytes - 28);  				memcpy(connlist[i]->recv_buffer+complex, buffer+28, bytes-28); // paste into their buffer  				connlist[i]->header->ocnt += bytes-28; | 
