Updated diagnostic logging. Optimized logging when debugging disabled. Added 'silent' switch to exists(), _afc_get_file_info(). Changed buffer for device name from fixed size to variable size.

This commit is contained in:
Gregory Riker 2014-03-19 11:05:22 -07:00
parent 7bf63b3290
commit 48c0a77c53

View File

@ -184,7 +184,9 @@ class libiMobileDevice():
def __init__(self, **kwargs):
self.verbose = kwargs.get('verbose', False)
if not self.verbose:
self._log = self.__null
self._log_location = self.__null
self._log_location()
self.afc = None
self.app_version = 0
@ -230,7 +232,7 @@ class libiMobileDevice():
src: file on local filesystem
dst: file to be created on iOS filesystem
'''
self._log_location("src=%s, dst=%s" % (repr(src), repr(dst)))
self._log_location("src:{0} dst:{1}".format(repr(src), repr(dst)))
mode = 'rb'
with open(src, mode) as f:
content = bytearray(f.read())
@ -239,7 +241,7 @@ class libiMobileDevice():
handle = self._afc_file_open(str(dst), mode=mode)
if handle is not None:
success = self._afc_file_write(handle, content, mode=mode)
self._log(" success: %s" % success)
self._log(" success: {0}".format(success))
self._afc_file_close(handle)
else:
self._log(" could not create copy")
@ -251,7 +253,10 @@ class libiMobileDevice():
src: path to file on iDevice
dst: file object on local filesystem
'''
self._log_location("src='%s', dst='%s'" % (src, dst.name))
self._log_location()
self._log("src: {0}".format(repr(src)))
self._log("dst: {0}".format(dst.name))
BUFFER_SIZE = 10 * 1024 * 1024
data = None
mode = 'rb'
@ -287,7 +292,7 @@ class libiMobileDevice():
else:
self._log(" could not open file")
raise libiMobileDeviceIOException("could not open file %s for reading" % repr(src))
raise libiMobileDeviceIOException("could not open file {0} for reading".format(repr(src)))
def disconnect_idevice(self):
'''
@ -310,14 +315,14 @@ class libiMobileDevice():
self._idevice_free()
self.device_mounted = False
def exists(self, path):
def exists(self, path, silent=False):
'''
Determine if path exists
Returns file_info or {}
'''
self._log_location("'%s'" % path)
return self._afc_get_file_info(path)
self._log_location("{0}".format(repr(path)))
return self._afc_get_file_info(path, silent=silent)
def get_device_info(self):
'''
@ -408,7 +413,7 @@ class libiMobileDevice():
Return a list containing the names of the entries in the iOS directory
given by path.
'''
self._log_location("'%s'" % path)
self._log_location("{0}".format(repr(path)))
return self._afc_read_directory(path, get_stats=get_stats)
def load_library(self):
@ -438,8 +443,8 @@ class libiMobileDevice():
self.plist_lib = cdll.LoadLibrary('libplist.dll')
self._log_location(env)
self._log(" libimobiledevice loaded from '%s'" % self.lib._name)
self._log(" libplist loaded from '%s'" % self.plist_lib._name)
self._log(" libimobiledevice loaded from '{0}'".format(self.lib._name))
self._log(" libplist loaded from '{0}'".format(self.plist_lib._name))
if False:
self._idevice_set_debug_level(DEBUG)
@ -449,7 +454,7 @@ class libiMobileDevice():
Mimic mkdir(), creating a directory at path. Does not create
intermediate folders
'''
self._log_location("'%s'" % path)
self._log_location("{0}".format(repr(path)))
return self._afc_make_directory(path)
def mount_ios_app(self, app_name=None, app_id=None):
@ -481,7 +486,7 @@ class libiMobileDevice():
self._instproxy_client_free()
if not app_name in self.installed_apps:
self._log(" '%s' not installed on this iDevice" % app_name)
self._log(" {0} not installed on this iDevice".format(repr(app_name)))
self.disconnect_idevice()
else:
# Mount the app's Container
@ -517,9 +522,9 @@ class libiMobileDevice():
self.disconnect_idevice()
if self.device_mounted:
self._log_location("'%s' mounted" % (app_name if app_name else app_id))
self._log_location("'{0}' mounted".format(app_name if app_name else app_id))
else:
self._log_location("unable to mount '%s'" % (app_name if app_name else app_id))
self._log_location("unable to mount '{0}'".format(app_name if app_name else app_id))
return self.device_mounted
def mount_ios_media_folder(self):
@ -559,7 +564,7 @@ class libiMobileDevice():
Use for small files.
For larger files copied to local file, use copy_from_idevice()
'''
self._log_location("'%s', mode='%s'" % (path, mode))
self._log_location("{0} mode='{1}'".format(repr(path), mode))
data = None
handle = self._afc_file_open(path, mode)
@ -569,7 +574,7 @@ class libiMobileDevice():
self._afc_file_close(handle)
else:
self._log(" could not open file")
raise libiMobileDeviceIOException("could not open file %s for reading" % repr(path))
raise libiMobileDeviceIOException("could not open file {0} for reading".format(repr(path)))
return data
@ -581,13 +586,13 @@ class libiMobileDevice():
from_name: (const char *) The fully-qualified path to rename from
to_name: (const char *) The fully-qualified path to rename to
'''
self._log_location("from: '%s' to: '%s'" % (from_name, to_name))
self._log_location("from: {0} to: {1}".format(repr(from_name), repr(to_name)))
error = self.lib.afc_rename_path(byref(self.afc),
str(from_name),
str(to_name))
if error:
self._log(" ERROR: %s" % self._afc_error(error))
self._log(" ERROR: {0}".format(self._afc_error(error)))
def remove(self, path):
'''
@ -596,12 +601,12 @@ class libiMobileDevice():
client (afc_client_t) The client to use
path (const char *) The fully-qualified path to delete
'''
self._log_location("'%s'" % path)
self._log_location("{0}".format(repr(path)))
error = self.lib.afc_remove_path(byref(self.afc), str(path))
if error:
self._log_error(" ERROR: %s path:%s" % (self._afc_error(error), repr(path)))
self._log_error(" ERROR: {0} path:{1}".format(self._afc_error(error), repr(path)))
def stat(self, path):
'''
@ -615,19 +620,19 @@ class libiMobileDevice():
'st_birthtime': xxx.yyy}
'''
self._log_location("'%s'" % path)
self._log_location("{0}".format(repr(path)))
return self._afc_get_file_info(path)
def write(self, content, destination, mode='w'):
'''
Convenience method to write to path on iDevice
'''
self._log_location(destination)
self._log_location("{0}".format(repr(destination)))
handle = self._afc_file_open(destination, mode=mode)
if handle is not None:
success = self._afc_file_write(handle, content, mode=mode)
self._log(" success: %s" % success)
self._log(" success: {0}".format(success))
self._afc_file_close(handle)
else:
self._log(" could not open file for writing")
@ -650,7 +655,7 @@ class libiMobileDevice():
error = self.lib.afc_client_free(byref(self.afc)) & 0xFFFF
if error:
self._log_error(" ERROR: %s" % self._afc_error(error))
self._log_error(" ERROR: {0}".format(self._afc_error(error)))
def _afc_client_new(self):
'''
@ -805,12 +810,12 @@ class libiMobileDevice():
File closed
'''
self._log_location(handle.value)
self._log_location("handle:{0}".format(handle.value))
error = self.lib.afc_file_close(byref(self.afc),
handle) & 0xFFFF
if error:
self._log_error(" ERROR: %s handle:%s" % (self._afc_error(error), handle))
self._log_error(" ERROR: {0} handle:{1}".format(self._afc_error(error), handle))
def _afc_file_open(self, filename, mode='r'):
'''
@ -834,7 +839,7 @@ class libiMobileDevice():
error: (afc_error_t) AFC_E_SUCCESS (0) on success or AFC_E_* error value
'''
self._log_location("%s, mode='%s'" % (repr(filename), mode))
self._log_location("{0} mode='{1}'".format(repr(filename), mode))
handle = c_ulonglong(0)
@ -850,7 +855,7 @@ class libiMobileDevice():
byref(handle)) & 0xFFFF
if error:
self._log_error(" ERROR: %s filename:%s" % (self._afc_error(error), repr(filename)))
self._log_error(" ERROR: {0} filename:{1}".format(self._afc_error(error), repr(filename)))
return None
else:
return handle
@ -874,7 +879,7 @@ class libiMobileDevice():
error (afc_error_t) AFC_E_SUCCESS (0) on success or AFC_E_* error value
'''
self._log_location("%s, size=%d, mode='%s'" % (handle.value, size, mode))
self._log_location("handle:{0} size:{1:,} mode='{2}'".format(handle.value, size, mode))
bytes_read = c_uint(0)
@ -887,13 +892,13 @@ class libiMobileDevice():
size,
byref(bytes_read)) & 0xFFFF
if error:
self._log_error(" ERROR: %s handle:%s" % (self._afc_error(error), handle))
self._log_error(" ERROR: {0} handle:{1}".format(self._afc_error(error), handle))
return data
else:
data = create_string_buffer(size)
error = self.lib.afc_file_read(byref(self.afc), handle, byref(data), size, byref(bytes_read))
if error:
self._log_error(" ERROR: %s handle:%s" % (self._afc_error(error), handle))
self._log_error(" ERROR: {0} handle:{1}".format(self._afc_error(error), handle))
return data.value
def _afc_file_write(self, handle, content, mode='w'):
@ -915,7 +920,7 @@ class libiMobileDevice():
error: (afc_error_t) AFC_E_SUCCESS (0) on success or AFC_E_* error value
'''
self._log_location("handle=%d, mode='%s'" % (handle.value, mode))
self._log_location("handle:{0} mode='{1}'".format(handle.value, mode))
bytes_written = c_uint(0)
@ -933,7 +938,7 @@ class libiMobileDevice():
len(content),
byref(bytes_written)) & 0xFFFF
if error:
self._log_error(" ERROR: %s handle:%s" % (self._afc_error(error), handle))
self._log_error(" ERROR: {0} handle:{1}".format(self._afc_error(error), handle))
return False
return True
@ -976,12 +981,12 @@ class libiMobileDevice():
for key in device_info.keys():
self._log("{0:>16}: {1}".format(key, device_info[key]))
else:
self._log(" ERROR: %s" % self._afc_error(error))
self._log(" ERROR: {0}".format(self._afc_error(error)))
else:
self._log(" ERROR: AFC not initialized, can't get device info")
return device_info
def _afc_get_file_info(self, path):
def _afc_get_file_info(self, path, silent=False):
'''
Gets information about a specific file
@ -1003,7 +1008,7 @@ class libiMobileDevice():
'st_birthtime': xxx.yyy}
'''
self._log_location("'%s'" % path)
self._log_location("{0}".format(repr(path)))
infolist_p = c_char * 1024
infolist = POINTER(POINTER(infolist_p))()
@ -1012,7 +1017,8 @@ class libiMobileDevice():
byref(infolist)) & 0xFFFF
file_stats = {}
if error:
self._log_error(" ERROR: %s path:%s" % (self._afc_error(error), repr(path)))
if not silent or self.verbose:
self._log_error(" ERROR: {0} path:{1}".format(self._afc_error(error), repr(path)))
else:
num_items = 0
item_list = []
@ -1023,14 +1029,14 @@ class libiMobileDevice():
if item_list[i].contents.value in ['st_mtime', 'st_birthtime']:
integer = item_list[i+1].contents.value[:10]
decimal = item_list[i+1].contents.value[10:]
value = float("%s.%s" % (integer, decimal))
value = float("{0}.{1}".format(integer, decimal))
else:
value = item_list[i+1].contents.value
file_stats[item_list[i].contents.value] = value
if False and self.verbose:
for key in file_stats.keys():
self._log(" %s: %s" % (key, file_stats[key]))
self._log(" {0}: {1}".format(key, file_stats[key]))
return file_stats
def _afc_make_directory(self, path):
@ -1044,12 +1050,12 @@ class libiMobileDevice():
Result:
error: AFC_E_SUCCESS on success or an AFC_E_* error value
'''
self._log_location("%s" % repr(path))
self._log_location("{0}".format(repr(path)))
error = self.lib.afc_make_directory(byref(self.afc),
str(path)) & 0xFFFF
if error:
self._log_error(" ERROR: %s path:%s" % (self._afc_error(error), repr(path)))
self._log_error(" ERROR: {0} path: {1}".format(self._afc_error(error), repr(path)))
return error
@ -1070,7 +1076,7 @@ class libiMobileDevice():
{'<path_basename>': {<file_stats>} ...}
'''
self._log_location("'%s'" % directory)
self._log_location("{0}".format(repr(directory)))
file_stats = {}
dirs_p = c_char_p
@ -1079,7 +1085,7 @@ class libiMobileDevice():
str(directory),
byref(dirs)) & 0xFFFF
if error:
self._log_error(" ERROR: %s directory:%s" % (self._afc_error(error), repr(directory)))
self._log_error(" ERROR: {0} directory: {1}".format(self._afc_error(error), repr(directory)))
else:
num_dirs = 0
dir_list = []
@ -1130,7 +1136,7 @@ class libiMobileDevice():
error = self.lib.house_arrest_client_free(byref(self.house_arrest)) & 0xFFFF
if error:
error = error - 0x10000
self._log_error(" ERROR: %s" % self._house_arrest_error(error))
self._log_error(" ERROR: {0}".format(self._house_arrest_error(error)))
def _house_arrest_client_new(self):
'''
@ -1222,9 +1228,9 @@ class libiMobileDevice():
# To determine success, we need to inspect the returned plist
if 'Status' in result:
self._log(" STATUS: %s" % result['Status'])
self._log(" STATUS: {0}".format(result['Status']))
elif 'Error' in result:
self._log(" ERROR: %s" % result['Error'])
self._log(" ERROR: {0}".format(result['Error']))
raise libiMobileDeviceException(result['Error'])
def _house_arrest_send_command(self, command=None, appid=None):
@ -1248,12 +1254,12 @@ class libiMobileDevice():
to call house_arrest_get_result().
'''
self._log_location("command='%s' appid='%s'" % (command, appid))
self._log_location("command={0} appid={1}".format(repr(command), repr(appid)))
commands = ['VendContainer', 'VendDocuments']
if command not in commands:
self._log(" ERROR: available commands: %s" % ', '.join(commands))
self._log(" ERROR: available commands: {0}".format(', '.join(commands)))
return
_command = create_string_buffer(command)
@ -1306,7 +1312,7 @@ class libiMobileDevice():
if error:
error = error - 0x10000
self._log_error(" ERROR: %s" % self._idevice_error(error))
self._log_error(" ERROR: {0}".format(self._idevice_error(error)))
def _idevice_get_device_list(self):
'''
@ -1330,7 +1336,7 @@ class libiMobileDevice():
self._log(" no connected devices")
else:
device_list = None
self._log_error(" ERROR: %s" % self._idevice_error(error))
self._log_error(" ERROR: {0}".format(self._idevice_error(error)))
else:
index = 0
while devices[index]:
@ -1338,7 +1344,7 @@ class libiMobileDevice():
if devices[index].contents.value not in device_list:
device_list.append(devices[index].contents.value)
index += 1
self._log(" %s" % repr(device_list))
self._log(" {0}".format(repr(device_list)))
#self.lib.idevice_device_list_free()
return device_list
@ -1372,8 +1378,8 @@ class libiMobileDevice():
if idevice_t.contents.conn_type == 1:
self._log(" conn_type: CONNECTION_USBMUXD")
else:
self._log(" conn_type: Unknown (%d)" % idevice_t.contents.conn_type)
self._log(" udid: %s" % idevice_t.contents.udid)
self._log(" conn_type: Unknown ({0})".format(idevice_t.contents.conn_type))
self._log(" udid: {0}".format(idevice_t.contents.udid))
return idevice_t.contents
def _idevice_set_debug_level(self, debug):
@ -1410,7 +1416,7 @@ class libiMobileDevice():
else:
# Get the number of apps
#app_count = self.lib.plist_array_get_size(apps)
#self._log(" app_count: %d" % app_count)
#self._log(" app_count: {0}".format(app_count))
# Convert the app plist to xml
xml = POINTER(c_void_p)()
@ -1428,7 +1434,7 @@ class libiMobileDevice():
else:
self._log(" unable to find app name in bundle:")
for key in sorted(app.keys()):
self._log(" %s %s" % (repr(key), repr(app[key])))
self._log(" {0} {1}".format(repr(key), repr(app[key])))
continue
if not applist:
@ -1487,7 +1493,7 @@ class libiMobileDevice():
'''
Specify the type of apps we want to browse
'''
self._log_location("'%s', '%s'" % (app_type, domain))
self._log_location("{0}, {1}".format(repr(app_type), repr(domain)))
self.lib.instproxy_client_options_add(self.client_options,
app_type, domain, None)
@ -1579,11 +1585,11 @@ class libiMobileDevice():
self._log_location()
lockdownd_client_t = POINTER(LOCKDOWND_CLIENT_T)()
SERVICE_NAME = create_string_buffer('calibre')
#SERVICE_NAME = create_string_buffer('calibre')
SERVICE_NAME = c_void_p()
error = self.lib.lockdownd_client_new_with_handshake(byref(self.device),
byref(lockdownd_client_t),
SERVICE_NAME) & 0xFFFF
if error:
error = error - 0x10000
error_description = self.LIB_ERROR_TEMPLATE.format(
@ -1653,8 +1659,7 @@ class libiMobileDevice():
'''
self._log_location()
device_name_b = c_char * 32
device_name_p = POINTER(device_name_b)()
device_name_p = c_char_p()
device_name = None
error = self.lib.lockdownd_get_device_name(byref(self.control),
byref(device_name_p)) & 0xFFFF
@ -1666,8 +1671,8 @@ class libiMobileDevice():
desc=self._lockdown_error(error))
raise libiMobileDeviceException(error_description)
else:
device_name = device_name_p.contents.value
self._log(" device_name: %s" % device_name)
device_name = device_name_p.value
self._log(" device_name: {0}".format(device_name))
return device_name
def _lockdown_get_value(self, requested_items=[]):
@ -1815,7 +1820,7 @@ class libiMobileDevice():
if self.control:
error = self.lib.lockdownd_goodbye(byref(self.control)) & 0xFFFF
error = error - 0x10000
self._log(" ERROR: %s" % self.error_lockdown(error))
self._log(" ERROR: {0}".format(self.error_lockdown(error)))
else:
self._log(" connection already closed")
@ -1855,11 +1860,8 @@ class libiMobileDevice():
'''
Print msg to console
'''
if not self.verbose:
return
if msg:
debug_print(" %s" % msg)
debug_print(" {0}".format(msg))
else:
debug_print()
@ -1880,9 +1882,6 @@ class libiMobileDevice():
def _log_location(self, *args):
'''
'''
if not self.verbose:
return
arg1 = arg2 = ''
if len(args) > 0:
@ -1892,3 +1891,6 @@ class libiMobileDevice():
debug_print(self.LOCATION_TEMPLATE.format(cls=self.__class__.__name__,
func=sys._getframe(1).f_code.co_name, arg1=arg1, arg2=arg2))
def __null(self, *args, **kwargs):
pass