static ssh_string asn1_get_int(ssh_buffer buffer) { ssh_string str; unsigned char type; uint32_t size; if (buffer_get_data(buffer, &type, 1) == 0 || type != ASN1_INTEGER) { return NULL; } size = asn1_get_len(buffer); if (size == 0) { return NULL; } str = string_new(size); if (str == NULL) { return NULL; } if (buffer_get_data(buffer, str->string, size) == 0) { string_free(str); return NULL; } return str; }
/* VPN_recv */ int32_t VPN_recv(int32_t fd, Buffer * buffer, uint32_t size, uint32_t flags) { int32_t ret; if(_client_check(NULL, fd) == NULL) return -1; #ifdef DEBUG fprintf(stderr, "DEBUG: %s(%d, buf, %u, %u)\n", __func__, fd, size, flags); #endif if(buffer_set_size(buffer, size) != 0) return -1; /* FIXME implement flags */ ret = recv(fd, buffer_get_data(buffer), size, 0); #ifdef DEBUG fprintf(stderr, "DEBUG: %s(%d, buf, %u, %u) => %d\n", __func__, fd, size, flags, ret); #endif if(buffer_set_size(buffer, (ret < 0) ? 0 : ret) != 0) { memset(buffer_get_data(buffer), 0, size); return -1; } return ret; }
char * util_alloc_envvar( const char * value ) { if (value == NULL) return NULL; else { buffer_type * buffer = buffer_alloc( 1024 ); /* Start by filling up a buffer instance with the current content of @value. */ buffer_fwrite_char_ptr( buffer , value ); buffer_fwrite_char( buffer , '\0' ); buffer_rewind( buffer ); while (true) { if (buffer_strchr( buffer , '$')) { const char * data = buffer_get_data( buffer ); int offset = buffer_get_offset( buffer ) + 1; /* Points at the first character following the '$' */ int var_length = 0; /* Find the length of the variable name */ while (true) { char c; c = data[offset + var_length]; if (!(isalnum( c ) || c == '_')) /* Any character which is NOT in the set [a-Z,0-9_] marks the end of the variable. */ break; if (c == '\0') /* The end of the string. */ break; var_length += 1; } { char * var_name = util_alloc_substring_copy( data , offset - 1 , var_length + 1); /* Include the leading $ */ const char * var_value = getenv( &var_name[1] ); if (var_value != NULL) buffer_search_replace( buffer , var_name , var_value); /* The actual string replacement. */ else buffer_fseek( buffer , var_length , SEEK_CUR ); /* The variable is not defined, and we leave the $name. */ free( var_name ); } } else break; /* No more $ to replace */ } buffer_shrink_to_fit( buffer ); { char * expanded_value = buffer_get_data( buffer ); buffer_free_container( buffer ); return expanded_value; } } }
static int _x509_from_request(char const * filename, Buffer * csr, Buffer * x509) { FILE * fp; int fd[2]; pid_t pid; if((fp = fopen(filename, "w")) == NULL) return error_set_code(1, "%s%s%s", filename, strerror(errno)); if(fwrite(buffer_get_data(csr), sizeof(char), buffer_get_size(csr), fp) != buffer_get_size(csr)) { fclose(fp); return error_set_code(1, "%s%s%s", filename, strerror(errno)); } if(fclose(fp) != 0) return error_set_code(1, "%s%s%s", filename, strerror(errno)); if(pipe(fd) != 0) return error_set_code(1, "%s%s", "pipe: ", strerror(errno)); if((pid = fork()) == -1) { close(fd[0]); close(fd[1]); return error_set_code(1, "%s%s", "fork: ", strerror(errno)); } if(pid == 0) { close(fd[0]); _request_child(filename, fd[1]); exit(0); } close(fd[1]); return _request_parent(x509, pid, fd[0]); }
static void remove_subj_trailers(buffer_t *buf, size_t start_pos, bool *is_reply_or_forward_r) { const char *data; size_t orig_size, size; /* subj-trailer = "(fwd)" / WSP */ data = buffer_get_data(buf, &orig_size); if (orig_size < 1) /* size includes trailing \0 */ return; for (size = orig_size-1; size > start_pos; ) { if (data[size-1] == ' ') size--; else if (size >= 5 && memcmp(data + size - 5, "(FWD)", 5) == 0) { *is_reply_or_forward_r = TRUE; size -= 5; } else { break; } } if (size != orig_size-1) { buffer_set_used_size(buf, size); buffer_append_c(buf, '\0'); } }
int framer_get_frame(framer_t *framer, char **data, size_t *size) { int tmp_index, delta; char *tmp_data; size_t tmp_size; tmp_index = framer->head->index; if (tmp_index > framer->buffer_index) { /* Remove data before stanza (e.g. \r\n between stanzas) */ delta = tmp_index - framer->buffer_index; buffer_remove_data(framer->buffer, delta); framer->buffer_index += delta; } tmp_size = framer->head->size; tmp_data = (char*) malloc(tmp_size); if (tmp_data == NULL) goto Error; buffer_get_data(framer->buffer, (unsigned char*) tmp_data, tmp_size); buffer_remove_data(framer->buffer, tmp_size); framer_remove_frame(framer); framer->buffer_index += tmp_size; *data = tmp_data; *size = tmp_size; return 1; Error: return 0; }
/* variable_new_deserialize_buffer */ Variable * variable_new_deserialize_buffer(size_t * size, Buffer const * buffer) { char const * data; data = buffer_get_data(buffer); return variable_new_deserialize(size, data); }
static int asn1_check_sequence(ssh_buffer buffer) { unsigned char *j = NULL; unsigned char tmp; int i; uint32_t size; uint32_t padding; if (buffer_get_data(buffer, &tmp, 1) == 0 || tmp != ASN1_SEQUENCE) { return 0; } size = asn1_get_len(buffer); if ((padding = buffer_get_len(buffer) - buffer->pos - size) > 0) { for (i = buffer_get_len(buffer) - buffer->pos - size, j = (unsigned char*)buffer_get(buffer) + size + buffer->pos; i; i--, j++) { if (*j != padding) { /* padding is allowed */ return 0; /* but nothing else */ } } } return 1; }
/* register */ int32_t Directory_register(String const * title, Buffer * csr, Buffer * x509) { static const char cacert_csr[] = "/cacert.csr"; static const char begin[] = "-----BEGIN CERTIFICATE REQUEST-----\n"; int ret; struct stat st; size_t len; char * filename; /* validate title */ if(*title == '\0' || *title == '.' || strchr(title, '/') != NULL) return 1; /* validate request */ if((len = buffer_get_size(csr)) < sizeof(begin)) return error_set_print(PACKAGE, 1, "%s", "Request too short"); if(memcmp(buffer_get_data(csr), begin, sizeof(begin) - 1) != 0) return error_set_print(PACKAGE, 1, "%s", "Incorrect request"); /* verify the title is unique */ if(lstat(title, &st) != -1 || errno != ENOENT) return error_set_print(PACKAGE, 1, "%s%s%s", title, ": ", strerror(EEXIST)); /* request certificate */ if(mkdir(title, 0777) != 0) return error_set_print(PACKAGE, 1, "%s%s%s", title, ": ", strerror(errno)); if((filename = malloc(strlen(title) + sizeof(cacert_csr))) == NULL) return error_set_print(PACKAGE, 1, "%s", strerror(errno)); sprintf(filename, "%s%s", title, cacert_csr); ret = _x509_from_request(filename, csr, x509); free(filename); return ret; }
bool tcp_write_checksum(uint8_t * tcp_segment, buffer_t * ip_psh) { struct tcphdr * tcp_header = (struct tcphdr *) tcp_segment; size_t size_ip = buffer_get_size(ip_psh), size_tcp = tcp_get_header_size(tcp_segment) + 2, // hardcoded payload size size_psh = size_ip + size_tcp; uint8_t * psh; // TCP checksum computation requires the IPv* header if (!ip_psh) { errno = EINVAL; return false; } // Allocate the buffer which will contains the pseudo header if (!(psh = calloc(1, size_psh))) { return false; } // Put the excerpt of the IP header into the pseudo header memcpy(psh, buffer_get_data(ip_psh), size_ip); // Put the TCP header and its content into the pseudo header memcpy(psh + size_ip, tcp_segment, size_tcp); // Overrides the TCP checksum in psh with zeros memset(psh + size_ip + offsetof(struct tcphdr, check), 0, sizeof(uint16_t)); // Compute the checksum tcp_header->check = csum((const uint16_t *) psh, size_psh); free(psh); return true; }
static bool remove_subj_fwd_hdr(buffer_t *buf, size_t *start_pos, bool *is_reply_or_forward_r) { const char *data; size_t size; /* subj-fwd = subj-fwd-hdr subject subj-fwd-trl subj-fwd-hdr = "[fwd:" subj-fwd-trl = "]" */ data = buffer_get_data(buf, &size); if (strncmp(data + *start_pos, "[FWD:", 5) != 0) return FALSE; if (data[size-2] != ']') return FALSE; *is_reply_or_forward_r = TRUE; buffer_set_used_size(buf, size-2); buffer_append_c(buf, '\0'); *start_pos += 5; return TRUE; }
buffer_t * ipv6_pseudo_header_create(const uint8_t * ipv6_segment) { buffer_t * psh; const struct ip6_hdr * iph = (const struct ip6_hdr *) ipv6_segment; ipv6_pseudo_header_t * data; if (!(psh = buffer_create())) { goto ERR_BUFFER_CREATE; } if (!(buffer_resize(psh, sizeof(ipv6_pseudo_header_t)))) { goto ERR_BUFFER_RESIZE; } data = (ipv6_pseudo_header_t *) buffer_get_data(psh); memcpy((uint8_t *) data + offsetof(ipv6_pseudo_header_t, ip_src), &iph->ip6_src, sizeof(ipv6_t)); memcpy((uint8_t *) data + offsetof(ipv6_pseudo_header_t, ip_dst), &iph->ip6_dst, sizeof(ipv6_t)); // IPv6 stores a uint16 but our pseudo header uses an uint32 ... // So to take care of endianness we cannot directly copy the value. data->size = htonl(ntohs(iph->ip6_ctlun.ip6_un1.ip6_un1_plen)); data->zeros = 0; data->zero = 0; data->protocol = iph->ip6_ctlun.ip6_un1.ip6_un1_nxt; return psh; ERR_BUFFER_RESIZE: buffer_free(psh); ERR_BUFFER_CREATE: return NULL; }
int ssh_get_kex(SSH_SESSION *session,int server_kex ){ STRING *str; char *strings[10]; int i; if(packet_wait(session,SSH2_MSG_KEXINIT,1)) return -1; if(buffer_get_data(session->in_buffer,session->server_kex.cookie,16)!=16){ ssh_set_error(session,SSH_FATAL,"get_kex(): no cookie in packet"); return -1; } hashbufin_add_cookie(session,session->server_kex.cookie); memset(strings,0,sizeof(char *)*10); for(i=0;i<10;++i){ str=buffer_get_ssh_string(session->in_buffer); if(!str) break; if(str){ buffer_add_ssh_string(session->in_hashbuf,str); strings[i]=string_to_char(str); free(str); } else strings[i]=NULL; } /* copy the server kex info into an array of strings */ if(server_kex){ session->client_kex.methods=malloc( 10 * sizeof(char **)); for(i=0;i<10;++i) session->client_kex.methods[i]=strings[i]; } else { // client session->server_kex.methods=malloc( 10 * sizeof(char **)); for(i=0;i<10;++i) session->server_kex.methods[i]=strings[i]; } return 0; }
void str_append_str(string_t *dest, const string_t *src) { const char *cstr; size_t len; cstr = buffer_get_data(src, &len); buffer_append(dest, cstr, len); }
bool unabto_buffer_test(void) { char * raw_test_string = "asjdhc#21?(!?(92814skzjbcasa"; uint8_t data[7 + 2 + strlen(raw_test_string)]; unabto_buffer buf, raw_string_buf; buffer_write_t w_buf; buffer_read_t r_buf; uint32_t t32; uint16_t t16; uint8_t t8; uint8_t raw_string_data[strlen(raw_test_string) + 1]; buffer_init(&raw_string_buf, (uint8_t*)raw_test_string, strlen(raw_test_string)); buffer_init(&buf, data, sizeof(data)); buffer_write_init(&w_buf, &buf); if (! (buffer_write_uint32(&w_buf, 0x12345678) && buffer_write_uint16(&w_buf, 0x1234) && buffer_write_uint8(&w_buf, 0x12) && buffer_write_raw(&w_buf, &raw_string_buf) ) ) { NABTO_LOG_ERROR(("Buffer write test failed")); return false; } buffer_read_init(&r_buf, &buf); memset(raw_string_data, 0, sizeof(raw_string_data) + 1); buffer_init(&raw_string_buf, raw_string_data, sizeof(raw_string_data)); bool t = false; if (! ( buffer_read_uint32(&r_buf, &t32) && t32 == 0x12345678 && buffer_read_uint16(&r_buf, &t16) && t16 == 0x1234 && buffer_read_uint8(&r_buf, &t8) && t8 == 0x12 && (t = buffer_read_raw(&r_buf, &raw_string_buf)) && buffer_get_size(&raw_string_buf) == strlen(raw_test_string) && 0 == strncmp((char*)buffer_get_data(&raw_string_buf), raw_test_string, strlen(raw_test_string)) )) { NABTO_LOG_ERROR(("Failed read test failed")); return false; } if (buffer_read_uint32(&r_buf, &t32) || buffer_read_uint16(&r_buf, &t16) || buffer_read_uint8(&r_buf, &t8) || buffer_read_raw(&w_buf, &raw_string_buf) || buffer_write_uint32(&w_buf, 0x12345678) || buffer_write_uint16(&w_buf, 0x1234) || buffer_write_uint8(&w_buf, 0x12) || buffer_write_raw(&w_buf, &raw_string_buf) ) { NABTO_LOG_ERROR(("Some function should have returned false but returned true")); return false; } return true; }
int dispatch_remreq_buffer_get_data(struct client_list_entry* client, struct remreq_buffer_get_data* message) { struct client_buffer* target = MAP_DEREF(uint32_t, struct client_buffer*, buffermap, &client->screen->buffers, message->buffer); if(target->remote_texture_layout_may_differ) return texture_get_data(client, message, target); else return buffer_get_data(client, message, target); }
static bool remove_subj_leader(buffer_t *buf, size_t *start_pos, bool *is_reply_or_forward_r) { const char *data, *orig_data; bool ret = FALSE; /* subj-leader = (*subj-blob subj-refwd) / WSP subj-blob = "[" *BLOBCHAR "]" *WSP subj-refwd = ("re" / ("fw" ["d"])) *WSP [subj-blob] ":" BLOBCHAR = %x01-5a / %x5c / %x5e-7f ; any CHAR except '[' and ']' */ orig_data = buffer_get_data(buf, NULL); orig_data += *start_pos; data = orig_data; if (*data == ' ') { /* independent from checks below - always removed */ data++; orig_data++; *start_pos += 1; ret = TRUE; } while (*data == '[') { if (!remove_blob(&data)) return ret; } if (strncmp(data, "RE", 2) == 0) data += 2; else if (strncmp(data, "FWD", 3) == 0) data += 3; else if (strncmp(data, "FW", 2) == 0) data += 2; else return ret; if (*data == ' ') data++; if (*data == '[' && !remove_blob(&data)) return ret; if (*data != ':') return ret; data++; *start_pos += (size_t)(data - orig_data); if (is_reply_or_forward_r != NULL) *is_reply_or_forward_r = TRUE; return TRUE; }
END_TEST START_TEST(compress_success) { const unsigned char expected_dest[] = { 0x78, 0x9c, 0x33, 0x34, 0x32, 0x36, 0x31, 0x35, 0x33, 0xb7, 0xb0, 0x34, 0x00, 0x00, 0x0b, 0x2c, 0x02, 0x0e }; fail_unless(buffer_append(source, "1234567890", 10) == 0); fail_unless(buffer_compress(source, dest) == 0); fail_unless(buffer_get_size(dest) == 18); fail_unless(memcmp(buffer_get_data(dest), expected_dest, 8) == 0); }
/* VPN_send */ int32_t VPN_send(int32_t fd, Buffer * buffer, uint32_t size, uint32_t flags) { if(_client_check(NULL, fd) == NULL) return -1; #ifdef DEBUG fprintf(stderr, "DEBUG: %s(%d, buf, %u, %u)\n", __func__, fd, size, flags); #endif if(buffer_get_size(buffer) < size) return -error_set_code(1, "%s", strerror(EINVAL)); /* FIXME implement flags */ return send(fd, buffer_get_data(buffer), size, 0); }
void checkpassword_child_output(struct chkpw_auth_request *request) { /* Send: username \0 password \0 timestamp \0. Must be 512 bytes or less. The "timestamp" parameter is actually useful only for APOP authentication. We don't support it, so keep it empty */ struct auth_request *auth_request = request->request; buffer_t *buf; const unsigned char *data; size_t size; ssize_t ret; buf = buffer_create_dynamic(pool_datastack_create(), 512+1); buffer_append(buf, auth_request->user, strlen(auth_request->user)+1); if (request->password != NULL) buffer_append(buf, request->password, strlen(request->password)+1); else buffer_append_c(buf, '\0'); buffer_append_c(buf, '\0'); data = buffer_get_data(buf, &size); if (size > 512) { auth_request_log_error(request->request, "checkpassword", "output larger than 512 bytes: %"PRIuSIZE_T, size); request->finish_callback(request, request->internal_failure_code); return; } ret = write(request->fd_out, data + request->write_pos, size - request->write_pos); if (ret <= 0) { if (ret < 0) { auth_request_log_error(request->request, "checkpassword", "write() failed: %m"); } request->finish_callback(request, request->internal_failure_code); return; } request->write_pos += ret; if (request->write_pos < size) return; io_remove(&request->io_out); if (close(request->fd_out) < 0) i_error("checkpassword: close() failed: %m"); request->fd_out = -1; }
END_TEST START_TEST(no_objects) { unsigned char expected_out[] = { 0x50, 0x41, 0x43, 0x4b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x9d, 0x08, 0x82, 0x3b, 0xd8, 0xa8, 0xea, 0xb5, 0x10, 0xad, 0x6a, 0xc7, 0x5c, 0x82, 0x3c, 0xfd, 0x3e, 0xd3, 0x1e }; fail_unless(packfile_transfer("xxx", commits, empty_stub, out) == 0); fail_unless(buffer_get_size(out) == 32); fail_unless(memcmp(buffer_get_data(out), expected_out, 32) == 0); }
static uint32_t asn1_get_len(ssh_buffer buffer) { uint32_t len; unsigned char tmp[4]; if (buffer_get_data(buffer,tmp,1) == 0) { return 0; } if (tmp[0] > 127) { len = tmp[0] & 127; if (len > 4) { return 0; /* Length doesn't fit in u32. Can this really happen? */ } if (buffer_get_data(buffer,tmp,len) == 0) { return 0; } len = char_to_u32(tmp, len); } else { len = char_to_u32(tmp, 1); } return len; }
static bool remove_blob_when_nonempty(buffer_t *buf, size_t *start_pos) { const char *data, *orig_data; orig_data = buffer_get_data(buf, NULL); orig_data += *start_pos; data = orig_data; if (*data == '[' && remove_blob(&data) && *data != '\0') { *start_pos += (size_t)(data - orig_data); return TRUE; } return FALSE; }
static void subst_list_eval_funcs____(const subst_list_type * subst_list , const parser_type * parser , buffer_type * buffer) { { int index; for (index = 0; index < vector_get_size( subst_list->func_data); index++) { const subst_list_func_type * subst_func = vector_iget_const( subst_list->func_data , index ); const char * func_name = subst_func->name; bool match; buffer_rewind( buffer ); do { size_t match_pos; match = buffer_strstr( buffer , func_name ); match_pos = buffer_get_offset( buffer ); if (match) { bool update = false; char * arg_start = buffer_get_data( buffer ); arg_start += buffer_get_offset( buffer ) + strlen( func_name ); if (arg_start[0] == '(') { /* We require that an opening paren follows immediately behind the function name. */ char * arg_end = strchr( arg_start , ')'); if (arg_end != NULL) { /* OK - we found an enclosing () pair. */ char * arg_content = util_alloc_substring_copy( arg_start, 1 , arg_end - arg_start - 1); stringlist_type * arg_list = parser_tokenize_buffer( parser , arg_content , true); char * func_eval = subst_list_func_eval( subst_func , arg_list ); int old_len = strlen(func_name) + strlen( arg_content) + 2; if (func_eval != NULL) { buffer_memshift( buffer , match_pos + old_len , strlen( func_eval ) - old_len); buffer_fwrite( buffer , func_eval , strlen( func_eval ) , sizeof * func_eval ); free( func_eval ); update = true; } free( arg_content ); stringlist_free( arg_list ); } } if (!update) buffer_fseek( buffer , match_pos + strlen( func_name ) , SEEK_SET); } } while (match); } } if (subst_list->parent != NULL) subst_list_eval_funcs____( subst_list->parent , parser , buffer ); }
END_TEST START_TEST(one_object) { unsigned char expected_out[] = { 0x50, 0x41, 0x43, 0x4b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x13, 0x78, 0x9c, 0x33, 0x34, 0x32, 0x06, 0x00, 0x01, 0x2d, 0x00, 0x97, 0x07, 0x77, 0x8d, 0x37, 0xa2, 0x12, 0x33, 0xad, 0xe4, 0x78, 0xfb, 0x0e, 0xa1, 0x9e, 0x52, 0x35, 0x10, 0xc3, 0x35, 0x2b }; fail_unless(packfile_transfer("xxx", commits, one_stub, out) == 0); fail_unless(buffer_get_size(out) == 44); fail_unless(memcmp(buffer_get_data(out), expected_out, 44) == 0); }
END_TEST START_TEST(two_objects) { unsigned char expected_out[] = { 0x50, 0x41, 0x43, 0x4b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x13, 0x78, 0x9c, 0x33, 0x34, 0x32, 0x06, 0x00, 0x01, 0x2d, 0x00, 0x97, 0x23, 0x78, 0x9c, 0x33, 0x31, 0x35, 0x03, 0x00, 0x01, 0x3f, 0x00, 0xa0, 0x9b, 0x5b, 0x1b, 0xe5, 0xab, 0x9f, 0x00, 0x63, 0x3b, 0xd5, 0xbe, 0x8b, 0x19, 0xa6, 0x06, 0x28, 0x07, 0xfd, 0x58, 0x0b }; fail_unless(packfile_transfer("xxx", commits, two_stub, out) == 0); fail_unless(buffer_get_size(out) == 56); fail_unless(memcmp(buffer_get_data(out), expected_out, 56) == 0); }
/* ssl_socket_queue */ static int _ssl_socket_queue(SSLSocket * sslsocket, Buffer * buffer) { uint32_t len; char * p; Variable * v; Buffer * b = NULL; #ifdef DEBUG fprintf(stderr, "DEBUG: %s(%d)\n", __func__, sslsocket->fd); #endif /* serialize the buffer */ v = variable_new(VT_BUFFER, buffer); b = buffer_new(0, NULL); if(v == NULL || b == NULL || variable_serialize(v, b, 0) != 0) { if(v != NULL) variable_delete(v); if(b != NULL) buffer_delete(b); return -1; } variable_delete(v); len = buffer_get_size(b); /* FIXME queue the serialized buffer directly as a message instead */ if((p = realloc(sslsocket->bufout, sslsocket->bufout_cnt + len)) == NULL) { buffer_delete(b); return -1; } sslsocket->bufout = p; memcpy(&p[sslsocket->bufout_cnt], buffer_get_data(b), len); /* register the callback if necessary */ if(sslsocket->bufout_cnt == 0) event_register_io_write(sslsocket->transport->helper->event, sslsocket->fd, (EventIOFunc)_ssl_socket_callback_write, sslsocket); sslsocket->bufout_cnt += len; buffer_delete(b); #ifdef DEBUG fprintf(stderr, "DEBUG: %s(%d) => %d\n", __func__, sslsocket->fd, 0); #endif return 0; }
/* video_on_refresh */ static gboolean _video_on_refresh(gpointer data) { VideoPhonePlugin * video = data; /* FIXME no longer block on read() */ if(read(video->fd, buffer_get_data(video->buffer), buffer_get_size(video->buffer)) <= 0) { /* this error can be ignored */ if(errno == EAGAIN) return TRUE; close(video->fd); video->fd = -1; return FALSE; } /* FIXME implement the rest */ return TRUE; }
AppMessage * appmessage_new_deserialize(Buffer * buffer) { AppMessage * message; char const * data = buffer_get_data(buffer); size_t size = buffer_get_size(buffer); size_t pos = 0; size_t s; Variable * v; uint8_t u8; #ifdef DEBUG fprintf(stderr, "DEBUG: %s()\n", __func__); #endif if((message = object_new(sizeof(*message))) == NULL) return NULL; s = size; if((v = variable_new_deserialize_type(VT_UINT8, &s, &data[pos])) == NULL) { object_delete(message); return NULL; } pos += s; size -= s; /* XXX may fail */ variable_get_as(v, VT_UINT8, &u8); variable_delete(v); switch((message->type = u8)) { case AMT_ACKNOWLEDGEMENT: return _new_deserialize_acknowledgement(message, data, size, pos); case AMT_CALL: return _new_deserialize_call(message, data, size, pos); default: error_set_code(1, "%s%u", "Unknown message type ", u8); /* XXX should not happen */ object_delete(message); return NULL; } }
char * subst_list_alloc_string_representation( const subst_list_type * subst_list ) { int size = subst_list_get_size( subst_list ); char * return_string = NULL; if (size > 0) { buffer_type * buffer = buffer_alloc( 512 ); int i; for (i=0; i < size; i++) { buffer_fwrite_char_ptr( buffer , subst_list_iget_key( subst_list , i)); buffer_fwrite_char(buffer , '='); buffer_fwrite_char_ptr( buffer , subst_list_iget_value( subst_list , i)); if (i < (size - 1)) buffer_fwrite_char_ptr( buffer , ", "); } buffer_fwrite_char( buffer , '\0'); buffer_shrink_to_fit( buffer ); return_string = buffer_get_data( buffer ); buffer_free_container( buffer ); } return return_string; }