diff options
| author | 2008-07-29 01:13:51 -0700 | |
|---|---|---|
| committer | 2008-07-29 01:13:51 -0700 | |
| commit | 0f4aeb11abce2f36d840b19d028e5aa34ccf5aba (patch) | |
| tree | 978d11b1f46fb323db044fa76e2020c09aab89d4 /AFC.c | |
| parent | e2ff1128351d75eafd5426af7f96f9719c1af3e6 (diff) | |
| download | libplist-0f4aeb11abce2f36d840b19d028e5aa34ccf5aba.tar.gz libplist-0f4aeb11abce2f36d840b19d028e5aa34ccf5aba.tar.bz2 | |
Version 0.09, added ability to talk to 2.0 firmware.
Diffstat (limited to 'AFC.c')
| -rw-r--r-- | AFC.c | 162 | 
1 files changed, 132 insertions, 30 deletions
| @@ -17,7 +17,7 @@ AFClient *afc_connect(iPhone *phone, int s_port, int d_port) {  		if (client->afc_packet) {  			client->phone = phone;  			client->afc_packet->packet_num = 0; -			client->afc_packet->unknown1 = client->afc_packet->unknown2 = client->afc_packet->unknown3 = client->afc_packet->unknown4 = 0; +			client->afc_packet->unknown1 = client->afc_packet->unknown2 = client->afc_packet->unknown3 = client->afc_packet->unknown4 = client->afc_packet->entire_length = client->afc_packet->this_length = 0;  			client->afc_packet->header1 = 0x36414643;  			client->afc_packet->header2 = 0x4141504C;  			client->file_handle = 0; @@ -50,29 +50,55 @@ int count_nullspaces(char *string, int number) {  int dispatch_AFC_packet(AFClient *client, char *data, int length) {  	char *buffer; -	int bytes = 0; +	int bytes = 0, offset = 0;  	if (!client || !client->connection || !client->phone || !client->afc_packet) return 0;  	if (!data || !length) length = 0;  	client->afc_packet->packet_num++; -	client->afc_packet->entire_length = client->afc_packet->this_length = (length) ? sizeof(AFCPacket) + length + 1 : sizeof(AFCPacket); -	 -	if (!length) { -		bytes = mux_send(client->phone, client->connection, (char*)client->afc_packet, client->afc_packet->this_length); -		if (bytes <= 0) return 0; -		else return bytes; -	} else { -		buffer = (char*)malloc(sizeof(char) * client->afc_packet->this_length); -		memcpy(buffer, client->afc_packet, sizeof(AFCPacket)); -		memcpy(buffer+sizeof(AFCPacket), data, length); -		buffer[client->afc_packet->this_length-1] = '\0'; +	if (!client->afc_packet->entire_length) client->afc_packet->entire_length = client->afc_packet->this_length = (length) ? sizeof(AFCPacket) + length + 1 : sizeof(AFCPacket); +	if (!client->afc_packet->this_length) client->afc_packet->this_length = sizeof(AFCPacket); +		 +	if (client->afc_packet->this_length != client->afc_packet->entire_length) { +		// We want to send two segments; buffer+sizeof(AFCPacket) to this_length is the parameters +		// And everything beyond that is the next packet. (for writing) +		char *buffer = (char*)malloc(client->afc_packet->this_length); +		memcpy(buffer, (char*)client->afc_packet, sizeof(AFCPacket)); +		offset = client->afc_packet->this_length - sizeof(AFCPacket); +		if (debug) printf("dispatch_AFC_packet: Offset: %i\n", offset); +		if ((length) < (client->afc_packet->entire_length - client->afc_packet->this_length)) { +			if (debug) printf("dispatch_AFC_packet: Length did not resemble what it was supposed to based on the packet.\nlength minus offset: %i\nrest of packet: %i\n", length-offset, client->afc_packet->entire_length - client->afc_packet->this_length); +			free(buffer); +			return 0; +		} +		if (debug) printf("dispatch_AFC_packet: fucked-up packet method (probably a write)\n"); +		memcpy(buffer+sizeof(AFCPacket), data, offset); +		bytes = mux_send(client->phone, client->connection, buffer, client->afc_packet->this_length); +		free(buffer); +		if (bytes <= 0) { return 0; } +		if (debug) { +			printf("dispatch_AFC_packet: sent the first now go with the second\n"); +			printf("Length: %i\n", length-offset); +			printf("Buffer: \n"); +			fwrite(data+offset, 1, length-offset, stdout); +		} +		 +		bytes = mux_send(client->phone, client->connection, data+offset, length-offset); +		if (bytes <= 0) { return 0; } +		else { return bytes; } +	} else { +		if (debug) printf("dispatch_AFC_packet doin things the old way\n"); +		char *buffer = (char*)malloc(sizeof(char) * client->afc_packet->this_length); +		if (debug) printf("dispatch_AFC_packet packet length = %i\n", client->afc_packet->this_length); +		memcpy(buffer, (char*)client->afc_packet, sizeof(AFCPacket)); +		if (debug) printf("dispatch_AFC_packet packet data follows\n"); +		if (length > 0) { memcpy(buffer+sizeof(AFCPacket), data, length); buffer[sizeof(AFCPacket)+length] = '\0'; } +		if (debug) fwrite(buffer, 1, client->afc_packet->this_length, stdout); +		if (debug) printf("\n");  		bytes = mux_send(client->phone, client->connection, buffer, client->afc_packet->this_length); -		free(buffer); // don't need it  		if (bytes <= 0) return 0;  		else return bytes;  	} -	  	return 0;  } @@ -103,19 +129,23 @@ int receive_AFC_data(AFClient *client, char **dump_here) {  	uint32 param1 = buffer[sizeof(AFCPacket)];  	free(buffer); -	if (r_packet->operation == 0x01) { -		printf("Oops? Bad operation code received.\n"); -		if (param1 == 0) printf("... false alarm, but still\n"); -		else printf("Errno %i\n", param1); +	if (r_packet->operation == 0x01 && !((client->afc_packet->operation == AFC_DELETE && param1 == 7))) { +		if (debug) printf("Oops? Bad operation code received.\n"); +		if (param1 == 0) { +			if (debug) printf("... false alarm, but still\n"); +			return 1; +		} +		else { if (debug) printf("Errno %i\n", param1); }  		free(r_packet);  		*dump_here = NULL;  		return 0;  	} else { -		printf("Operation code %x\nFull length %i and this length %i\n", r_packet->operation, r_packet->entire_length, r_packet->this_length); +		if (debug) printf("Operation code %x\nFull length %i and this length %i\n", r_packet->operation, r_packet->entire_length, r_packet->this_length);  	}  	recv_len = r_packet->entire_length - r_packet->this_length;  	free(r_packet); +	if (!recv_len) return bytes;  	buffer = (char*)malloc(sizeof(char) * recv_len);  	bytes = mux_recv(client->phone, client->connection, buffer, recv_len);  	if (bytes <= 0) { @@ -133,6 +163,7 @@ char **afc_get_dir_list(AFClient *client, char *dir) {  	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; @@ -159,8 +190,49 @@ char **make_strings_list(char *tokens, int true_length) {  	return list;  } +int afc_delete_file(AFClient *client, const char *path) { +	if (!client || !path || !client->afc_packet || !client->phone ||!client->connection) return 0; + +	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; +	 +	bytes = receive_AFC_data(client, &receive); +	free(receive); +	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->phone || !client->connection) return 0; +	 +	char *receive = NULL; +	char *send = (char*)malloc(sizeof(char) * (strlen(from) + strlen(to) + 1 + sizeof(uint32))); +	int bytes = 0; +	 +	memcpy(send, from, strlen(from)+1); +	memcpy(send+strlen(from)+1, to, strlen(to)); +	fwrite(send, 1, strlen(from)+1+strlen(to), stdout); +	printf("\n"); +	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; +	 +	bytes = receive_AFC_data(client, &receive); +	free(receive); +	if (bytes <= 0) return 0; +	else return 1; +} + +	 +	  AFCFile *afc_get_file_info(AFClient *client, char *path) {  	client->afc_packet->operation = AFC_GET_INFO; +	client->afc_packet->entire_length = client->afc_packet->this_length = 0;  	dispatch_AFC_packet(client, path, strlen(path));  	char *received, **list; @@ -210,26 +282,24 @@ AFCFile *afc_open_file(AFClient *client, const char *filename, uint32 file_mode)  	int bytes = 0, length_thing = 0;  	client->afc_packet->operation = AFC_FILE_OPEN; +	client->afc_packet->entire_length = client->afc_packet->this_length = 0;  	bytes = dispatch_AFC_packet(client, further_data, 8+strlen(filename));  	free(further_data);  	if (bytes <= 0) { -		printf("didn't read enough\n"); +		if (debug) printf("didn't read enough\n");  		return NULL;  	} else { -		printf("O HAI\n");  		length_thing = receive_AFC_data(client, &further_data);  		if (length_thing && further_data) { -			printf("ARA\n");  			file_infos = afc_get_file_info(client, filename);  			memcpy(&file_infos->filehandle, further_data, 4); -			printf("gr\n");  			return file_infos;  		} else { -			printf("didn't get further data or something\n"); +			if (debug) printf("didn't get further data or something\n");  			return NULL;  		}  	} -	printf("what the fuck\n"); +	if (debug) printf("what the fuck\n");  	return NULL;  } @@ -243,14 +313,17 @@ int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) {  	int bytes = 0;  	client->afc_packet->operation = AFC_READ; -	bytes = dispatch_AFC_packet(client, packet, sizeof(AFCFilePacket)); +	client->afc_packet->entire_length = client->afc_packet->this_length = 0; +	bytes = dispatch_AFC_packet(client, (char*)packet, sizeof(AFCFilePacket));  	if (bytes > 0) {  		bytes = receive_AFC_data(client, &input);  		if (bytes <= 0) { +			if (input) free(input);  			return -1;  		} else {  			memcpy(data, input, (bytes > length) ? length : bytes); +			free(input);  			return (bytes > length) ? length : bytes;  		}  	} else { @@ -259,21 +332,50 @@ int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) {  	return 0;  } +int afc_write_file(AFClient *client, AFCFile *file, char *data, int length) { +	char *acknowledgement = NULL; +	if (!client ||!client->afc_packet ||!client->phone || !client->connection || !file) return -1; +	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; +	if (debug) printf("afc_write_file: Write length: %i\n", length); +	uint32 zero = 0, bytes = 0; +	 +	char *out_buffer = NULL; +	out_buffer = (char*)malloc(sizeof(char) * client->afc_packet->entire_length - sizeof(AFCPacket)); +	memcpy(out_buffer, (char*)&file->filehandle, sizeof(uint32)); +	memcpy(out_buffer+4, (char*)&zero, sizeof(uint32)); +	memcpy(out_buffer+8, data, length); +	 +	bytes = dispatch_AFC_packet(client, out_buffer, length + 8); +	if (!bytes) return -1; +	 +	zero = bytes; +	bytes = receive_AFC_data(client, &acknowledgement); +	if (bytes <= 0) { +		if (debug) printf("afc_write_file: uh oh?\n"); +	} +	 +	return zero; +} +  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);  	memcpy(buffer, &file->filehandle, sizeof(uint32)); -	memcpy(buffer, &zero, sizeof(zero)); +	memcpy(buffer+sizeof(uint32), &zero, sizeof(zero));  	client->afc_packet->operation = AFC_FILE_CLOSE;  	int bytes = 0; +	client->afc_packet->entire_length = client->afc_packet->this_length = 0;  	bytes = dispatch_AFC_packet(client, buffer, sizeof(char) * 8); +  	free(buffer); +	client->afc_packet->entire_length = client->afc_packet->this_length = 0;  	if (!bytes) return;  	bytes = receive_AFC_data(client, &buffer); -	if (bytes<=0 && !buffer) printf("closefile: all went as expected\n"); -	else { printf("We have a buffer!??!?\nLength %i\n", bytes); fwrite(buffer, 1, bytes, stdout); printf("\n"); } +	return;  	if (buffer) free(buffer); // we're *SUPPOSED* to get an "error" here.   } | 
