static void iniPair_init( IniPair* pair, const char* key, int keyLen, const char* value, int valueLen ) { AARRAY_NEW(pair->key, keyLen + valueLen + 2); memcpy(pair->key, key, keyLen); pair->key[keyLen] = 0; pair->value = pair->key + keyLen + 1; memcpy(pair->value, value, valueLen); pair->value[valueLen] = 0; }
/* receive a new message from a client, and dispatch it to * the real service implementation. */ static void qemud_client_recv( void* opaque, uint8_t* msg, int msglen ) { QemudClient* c = opaque; /* no framing, things are simple */ if (!c->framing) { if (c->clie_recv) c->clie_recv( c->clie_opaque, msg, msglen, c ); return; } /* framing */ #if 1 /* special case, in 99% of cases, everything is in * the incoming message, and we can do all we need * directly without dynamic allocation. */ if (msglen > FRAME_HEADER_SIZE && c->need_header == 1 && qemud_sink_needed(c->header) == 0) { int len = hex2int( msg, FRAME_HEADER_SIZE ); if (len >= 0 && msglen == len + FRAME_HEADER_SIZE) { if (c->clie_recv) c->clie_recv( c->clie_opaque, msg+FRAME_HEADER_SIZE, msglen-FRAME_HEADER_SIZE, c ); return; } } #endif while (msglen > 0) { uint8_t *data; /* read the header */ if (c->need_header) { int frame_size; uint8_t* data; if (!qemud_sink_fill(c->header, (const uint8_t**)&msg, &msglen)) break; frame_size = hex2int(c->header0, 4); if (frame_size == 0) { D("%s: ignoring empty frame", __FUNCTION__); continue; } if (frame_size < 0) { D("%s: ignoring corrupted frame header '.*s'", __FUNCTION__, FRAME_HEADER_SIZE, c->header0 ); continue; } AARRAY_NEW(data, frame_size+1); /* +1 for terminating zero */ qemud_sink_reset(c->payload, frame_size, data); c->need_header = 0; c->header->len = 0; } /* read the payload */ if (!qemud_sink_fill(c->payload, (const uint8_t**)&msg, &msglen)) break; c->payload->buff[c->payload->size] = 0; c->need_header = 1; data = c->payload->buff; /* Technically, calling 'clie_recv' can destroy client object 'c' * if it decides to close the connection, so ensure we don't * use/dereference it after the call. */ if (c->clie_recv) c->clie_recv( c->clie_opaque, c->payload->buff, c->payload->size, c ); AFREE(data); } }