debugserver_error_t debugserver_client_receive_with_timeout(debugserver_client_t client, char* data, uint32_t size, uint32_t *received, unsigned int timeout) { debugserver_error_t res = DEBUGSERVER_E_UNKNOWN_ERROR; int bytes = 0; if (!client || !data || (size == 0)) { return DEBUGSERVER_E_INVALID_ARG; } res = debugserver_error(service_receive_with_timeout(client->parent, data, size, (uint32_t*)&bytes, timeout)); if (bytes <= 0) { debug_info("Could not read data, error %d", res); } if (received) { *received = (uint32_t)bytes; } return res; }
LIBIMOBILEDEVICE_API syslog_relay_error_t syslog_relay_receive_with_timeout(syslog_relay_client_t client, char* data, uint32_t size, uint32_t *received, unsigned int timeout) { syslog_relay_error_t res = SYSLOG_RELAY_E_UNKNOWN_ERROR; int bytes = 0; if (!client || !data || (size == 0)) { return SYSLOG_RELAY_E_INVALID_ARG; } res = syslog_relay_error(service_receive_with_timeout(client->parent, data, size, (uint32_t*)&bytes, timeout)); if (bytes <= 0) { debug_info("Could not read data, error %d", res); } if (received) { *received = (uint32_t)bytes; } return res; }
/** * Receives a plist using the given property list service client. * Internally used generic plist receive function. * * @param client The property list service client to use for receiving * @param plist pointer to a plist_t that will point to the received plist * upon successful return * @param timeout Maximum time in milliseconds to wait for data. * * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, * PROPERTY_LIST_SERVICE_E_INVALID_ARG when client or *plist is NULL, * PROPERTY_LIST_SERVICE_E_PLIST_ERROR when the received data cannot be * converted to a plist, PROPERTY_LIST_SERVICE_E_MUX_ERROR when a * communication error occurs, or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR * when an unspecified error occurs. */ static property_list_service_error_t internal_plist_receive_timeout(property_list_service_client_t client, plist_t *plist, unsigned int timeout) { property_list_service_error_t res = PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR; uint32_t pktlen = 0; uint32_t bytes = 0; if (!client || (client && !client->parent) || !plist) { return PROPERTY_LIST_SERVICE_E_INVALID_ARG; } *plist = NULL; service_error_t serr = service_receive_with_timeout(client->parent, (char*)&pktlen, sizeof(pktlen), &bytes, timeout); if ((serr == SERVICE_E_SUCCESS) && (bytes == 0)) { return PROPERTY_LIST_SERVICE_E_RECEIVE_TIMEOUT; } debug_info("initial read=%i", bytes); if (bytes < 4) { debug_info("initial read failed!"); return PROPERTY_LIST_SERVICE_E_MUX_ERROR; } else { uint32_t curlen = 0; char *content = NULL; pktlen = be32toh(pktlen); debug_info("%d bytes following", pktlen); content = (char*)malloc(pktlen); if (!content) { debug_info("out of memory when allocating %d bytes", pktlen); return PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR; } while (curlen < pktlen) { service_receive(client->parent, content+curlen, pktlen-curlen, &bytes); if (bytes <= 0) { res = PROPERTY_LIST_SERVICE_E_MUX_ERROR; break; } debug_info("received %d bytes", bytes); curlen += bytes; } if (curlen < pktlen) { debug_info("received incomplete packet (%d of %d bytes)", curlen, pktlen); if (curlen > 0) { debug_info("incomplete packet following:"); debug_buffer(content, curlen); } free(content); return res; } if ((pktlen > 8) && !memcmp(content, "bplist00", 8)) { plist_from_bin(content, pktlen, plist); } else if ((pktlen > 5) && !memcmp(content, "<?xml", 5)) { /* iOS 4.3+ hack: plist data might contain invalid characters, thus we convert those to spaces */ for (bytes = 0; bytes < pktlen-1; bytes++) { if ((content[bytes] >= 0) && (content[bytes] < 0x20) && (content[bytes] != 0x09) && (content[bytes] != 0x0a) && (content[bytes] != 0x0d)) content[bytes] = 0x20; } plist_from_xml(content, pktlen, plist); } else { debug_info("WARNING: received unexpected non-plist content"); debug_buffer(content, pktlen); } if (*plist) { debug_plist(*plist); res = PROPERTY_LIST_SERVICE_E_SUCCESS; } else { res = PROPERTY_LIST_SERVICE_E_PLIST_ERROR; } free(content); content = NULL; } return res; }
/** * Receives data using the given service client. * * @param client The service client to use for receiving * @param data Buffer that will be filled with the data received * @param size Number of bytes to receive * @param received Number of bytes received (can be NULL to ignore) * * @return SERVICE_E_SUCCESS on success, * SERVICE_E_INVALID_ARG when one or more parameters are * invalid, SERVICE_E_MUX_ERROR when a communication error * occurs, or SERVICE_E_UNKNOWN_ERROR when an unspecified * error occurs. */ service_error_t service_receive(service_client_t client, char* data, uint32_t size, uint32_t *received) { return service_receive_with_timeout(client, data, size, received, 10000); }