gboolean falcon_object_load(falcon_object_t *object, void *userdata) { int fd = GPOINTER_TO_INT(userdata); guint16 len = 0; g_return_val_if_fail(object, FALSE); if (read(fd, &len, 2) == -1) { g_critical(_("Failed to read the length of object: %s"), g_strerror(errno)); return FALSE; } len = GUINT16_FROM_BE(len); object->name = g_new0(gchar, len + 1); if (read(fd, object->name, len) == -1) { g_critical(_("Failed to read object name: %s"), g_strerror(errno)); g_free(object->name); return FALSE; } if (read(fd, &(object->size), 8) == -1) { g_critical(_("Failed to read object size \"%s\": %s"), object->name, g_strerror(errno)); g_free(object->name); return FALSE; } object->size = GUINT64_FROM_BE(object->size); if (read(fd, &(object->time), 8) == -1) { g_critical(_("Failed to read object time \"%s\": %s"), object->name, g_strerror(errno)); g_free(object->name); return FALSE; } object->time = GUINT64_FROM_BE(object->time); if (read(fd, &(object->mode), 4) == -1) { g_critical(_("Failed to read object mode \"%s\": %s"), object->name, g_strerror(errno)); g_free(object->name); return FALSE; } object->mode = GUINT32_FROM_BE(object->mode); if (read(fd, &(object->watch), 1) == -1) { g_critical(_("Failed to read object watch \"%s\": %s"), object->name, g_strerror(errno)); g_free(object->name); return FALSE; } return TRUE; }
static void dump_commit (GVariant *variant, OstreeDumpFlags flags) { const gchar *subject; const gchar *body; guint64 timestamp; gs_free gchar *str; /* See OSTREE_COMMIT_GVARIANT_FORMAT */ g_variant_get (variant, "(a{sv}aya(say)&s&stayay)", NULL, NULL, NULL, &subject, &body, ×tamp, NULL, NULL); timestamp = GUINT64_FROM_BE (timestamp); str = format_timestamp (timestamp); if (str) g_print ("Date: %s\n", str); g_print ("\n"); dump_indented_lines (subject); if (body[0]) { g_print ("\n"); dump_indented_lines (body); } g_print ("\n"); }
gboolean ostree_zlib_file_header_parse (GVariant *metadata, GFileInfo **out_file_info, GVariant **out_xattrs, GError **error) { gboolean ret = FALSE; guint64 size; guint32 uid, gid, mode, rdev; const char *symlink_target; ot_lobj GFileInfo *ret_file_info = NULL; ot_lvariant GVariant *ret_xattrs = NULL; g_variant_get (metadata, "(tuuuu&s@a(ayay))", &size, &uid, &gid, &mode, &rdev, &symlink_target, &ret_xattrs); size = GUINT64_FROM_BE (size); uid = GUINT32_FROM_BE (uid); gid = GUINT32_FROM_BE (gid); mode = GUINT32_FROM_BE (mode); rdev = GUINT32_FROM_BE (rdev); ret_file_info = g_file_info_new (); g_file_info_set_size (ret_file_info, size); g_file_info_set_attribute_uint32 (ret_file_info, "standard::type", ot_gfile_type_for_mode (mode)); g_file_info_set_attribute_boolean (ret_file_info, "standard::is-symlink", S_ISLNK (mode)); g_file_info_set_attribute_uint32 (ret_file_info, "unix::uid", uid); g_file_info_set_attribute_uint32 (ret_file_info, "unix::gid", gid); g_file_info_set_attribute_uint32 (ret_file_info, "unix::mode", mode); if (S_ISREG (mode)) { ; } else if (S_ISLNK (mode)) { g_file_info_set_attribute_byte_string (ret_file_info, "standard::symlink-target", symlink_target); } else if (S_ISCHR (mode) || S_ISBLK (mode)) { g_file_info_set_attribute_uint32 (ret_file_info, "unix::rdev", rdev); } else if (S_ISFIFO (mode)) { ; } else { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Corrupted archive file; invalid mode %u", mode); goto out; } ret = TRUE; ot_transfer_out_value(out_file_info, &ret_file_info); ot_transfer_out_value(out_xattrs, &ret_xattrs); out: return ret; }
guint64 msn_read64be(const char *buf) { guint64 val; memcpy(&val, buf, sizeof(val)); return GUINT64_FROM_BE(val); }
/** * Reads an unsigned 64-bit Big Endian value from the stream into native endian format. * * @param value Pointer to the variable to read the value into. * @param stream A #VFSFile object representing the stream. * @return TRUE if read was succesful, FALSE if there was an error. */ EXPORT bool_t vfs_fget_be64(uint64_t *value, VFSFile *stream) { uint64_t tmp; if (vfs_fread(&tmp, sizeof(tmp), 1, stream) != 1) return FALSE; *value = GUINT64_FROM_BE(tmp); return TRUE; }
/* * Cache file format * * All values are stored in Big Endian order. * 8 bytes unsigned integer: number of objects following. * For each object, * 2 bytes unsigned integer: name length, follow by name string. * 8 bytes signed integer: file size * 8 bytes signed integer: time * 4 bytes unsigned integer: mode * 1 byte unsigned integer: watchability flag. */ gboolean falcon_cache_load(falcon_cache_t *cache, const gchar *name) { int fd = 0; guint64 count = 0; falcon_object_t *object = NULL; guint64 i; gboolean ret = TRUE; g_return_val_if_fail(cache, FALSE); if (!name) return FALSE; fd = g_open(name, O_RDONLY, 0); if (fd == -1) { g_critical(_("Failed to read cache file %s: %s"), name, g_strerror(errno)); return FALSE; } if (read(fd, &(count), 8) == -1) { g_critical(_("Failed to read cache file %s: %s"), name, g_strerror(errno)); close(fd); return FALSE; } count = GUINT64_FROM_BE(count); g_debug(_("Loaded %lu cache keys."), count); for (i = 1; i <= count; i++) { object = falcon_object_new(NULL); if (!falcon_object_load(object, GINT_TO_POINTER(fd))) { g_critical(_("Failed to load object %lu"), i); falcon_object_free(object); ret = FALSE; break; } g_debug(_("Loaded object \"%s\": dir=%s, size=%ld, time=%ld, watch=%s"), falcon_object_get_name(object), falcon_object_isdir(object) ? "yes" : "no", falcon_object_get_size(object), falcon_object_get_time(object), falcon_object_get_watch(object) ? "yes" : "no"); falcon_cache_add(cache, object); falcon_object_free(object); object = NULL; } close(fd); return ret; }
static void dump_summary_ref (const char *ref_name, guint64 commit_size, GVariant *csum_v, GVariantIter *metadata) { const guchar *csum_bytes; GError *csum_error = NULL; g_autofree char *size = NULL; GVariant *value; char *key; g_print ("* %s\n", ref_name); size = g_format_size (commit_size); g_print (" Latest Commit (%s):\n", size); csum_bytes = ostree_checksum_bytes_peek_validate (csum_v, &csum_error); if (csum_error == NULL) { char csum[OSTREE_SHA256_STRING_LEN+1]; ostree_checksum_inplace_from_bytes (csum_bytes, csum); g_print (" %s\n", csum); } else { g_print (" %s\n", csum_error->message); g_clear_error (&csum_error); } while (g_variant_iter_loop (metadata, "{sv}", &key, &value)) { g_autofree gchar *value_str = NULL; const gchar *pretty_key = NULL; if (g_strcmp0 (key, OSTREE_COMMIT_TIMESTAMP) == 0) { pretty_key = "Timestamp"; value_str = uint64_secs_to_iso8601 (GUINT64_FROM_BE (g_variant_get_uint64 (value))); } else { value_str = g_variant_print (value, FALSE); } /* Print out. */ if (pretty_key != NULL) g_print (" %s (%s): %s\n", pretty_key, key, value_str); else g_print (" %s: %s\n", key, value_str); } }
gboolean g_vfs_afp_reply_read_uint64 (GVfsAfpReply *reply, guint64 *val) { if ((reply->len - reply->pos) < 8) return FALSE; if (val) *val = GUINT64_FROM_BE (*((guint64 *)(reply->data + reply->pos))); reply->pos += 8; return TRUE; }
gint32 thrift_binary_protocol_write_double (ThriftProtocol *protocol, const gdouble value, GError **error) { g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); guint64 bits = GUINT64_FROM_BE (thrift_bitwise_cast_guint64 (value)); if (thrift_transport_write (protocol->transport, (const gpointer) &bits, 8, error)) { return 8; } else { return -1; } }
static gboolean input_stream_read_uint64_all(GInputStream *stream, guint64 *data, GCancellable *cancellable, GError **error) { guint64 tmp; gsize bytes_read; gboolean res; res = g_input_stream_read_all(stream, &tmp, sizeof(tmp), &bytes_read, cancellable, error); g_assert(bytes_read == sizeof(tmp)); *data = GUINT64_FROM_BE(tmp); return res; }
gint32 thrift_binary_protocol_read_i64 (ThriftProtocol *protocol, gint64 *value, GError **error) { g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); gint32 ret; gpointer b[8]; if ((ret = thrift_transport_read (protocol->transport, b, 8, error)) < 0) { return -1; } *value = *(gint64 *) b; *value = GUINT64_FROM_BE (*value); return ret; }
gint32 thrift_binary_protocol_read_double (ThriftProtocol *protocol, gdouble *value, GError **error) { g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); gint32 ret; gpointer b[8]; if ((ret = thrift_transport_read (protocol->transport, b, 8, error)) < 0) { return -1; } guint64 bits = *(guint64 *) b; bits = GUINT64_FROM_BE (bits); *value = thrift_bitwise_cast_gdouble (bits); return ret; }
static void dump_commit (GVariant *variant, OstreeDumpFlags flags) { const gchar *subject; const gchar *body; guint64 timestamp; g_autofree char *str = NULL; g_autofree char *version = NULL; g_autoptr(GError) local_error = NULL; /* See OSTREE_COMMIT_GVARIANT_FORMAT */ g_variant_get (variant, "(a{sv}aya(say)&s&stayay)", NULL, NULL, NULL, &subject, &body, ×tamp, NULL, NULL); timestamp = GUINT64_FROM_BE (timestamp); str = format_timestamp (timestamp, &local_error); if (!str) errx (1, "Failed to read commit: %s", local_error->message); g_print ("Date: %s\n", str); if ((version = ot_admin_checksum_version (variant))) { g_print ("Version: %s\n", version); } if (subject[0]) { g_print ("\n"); dump_indented_lines (subject); } else { g_print ("(no subject)\n"); } if (body[0]) { g_print ("\n"); dump_indented_lines (body); } g_print ("\n"); }
static gboolean read_word (EvaDebugLog *log, guint64 *out) { if (log->is_64bit) { guint64 val; if (fread (&val, 8, 1, log->fp) != 1) return FALSE; *out = log->little_endian ? GUINT64_FROM_LE (val) : GUINT64_FROM_BE (val); } else { guint32 val; if (fread (&val, 4, 1, log->fp) != 1) return FALSE; *out = log->little_endian ? GUINT32_FROM_LE (val) : GUINT32_FROM_BE (val); } return TRUE; }
gint32 thrift_binary_protocol_read_double (ThriftProtocol *protocol, gdouble *value, GError **error) { gint32 ret; union { gint8 byte_array[8]; guint64 uint64; } b; g_return_val_if_fail (THRIFT_IS_BINARY_PROTOCOL (protocol), -1); if ((ret = thrift_transport_read_all (protocol->transport, b.byte_array, 8, error)) < 0) { return -1; } *value = thrift_bitwise_cast_gdouble (GUINT64_FROM_BE (b.uint64)); return ret; }
static void *read_tiff_tag_8(FILE *f, int64_t count, int64_t offset, uint16_t endian) { uint64_t *result = g_try_new(uint64_t, count); if (result == NULL) { goto FAIL; } if (!read_tiff_tag(f, count * sizeof *result, result, offset, NULL)) { goto FAIL; } // swap? for (int64_t i = 0; i < count; i++) { if (endian == TIFF_BIGENDIAN) { result[i] = GUINT64_FROM_BE(result[i]); } else { result[i] = GUINT64_FROM_LE(result[i]); } } /* g_debug(" count %" PRId64, count); for (int i = 0; i < count; i++) { if (i > 50) { g_debug(" ..."); break; } g_debug(" %" PRIu64, result[i]); } g_debug(" "); */ return result; FAIL: g_free(result); return NULL; }
/** * qmi_utils_read_guint64_from_buffer: * @buffer: a buffer with raw binary data. * @buffer_size: size of @buffer. * @endian: endianness of firmware value; swapped to host byte order if necessary * @out: return location for the read variable. * * Reads an unsigned 64-bit integer from the buffer. The number in the buffer is * expected to be given in the byte order specified by @endian, and this method * takes care of converting the read value to the proper host endianness. * * The user needs to make sure that at least 8 bytes are available * in the buffer. * * Also note that both @buffer and @buffer_size get updated after the 8 bytes * read. */ void qmi_utils_read_guint64_from_buffer (const guint8 **buffer, guint16 *buffer_size, QmiEndian endian, guint64 *out) { g_assert (out != NULL); g_assert (buffer != NULL); g_assert (buffer_size != NULL); g_assert (*buffer_size >= 8); memcpy (out, &((*buffer)[0]), 8); if (endian == QMI_ENDIAN_BIG) *out = GUINT64_FROM_BE (*out); else *out = GUINT64_FROM_LE (*out); print_read_bytes_trace ("guint64", &(*buffer)[0], out, 8); *buffer = &((*buffer)[8]); *buffer_size = (*buffer_size) - 8; }
/** * qmi_utils_read_sized_guint_from_buffer: * @buffer: a buffer with raw binary data. * @buffer_size: size of @buffer. * @n_bytes: number of bytes to read. * @endian: endianness of firmware value; swapped to host byte order if necessary * @out: return location for the read variable. * * Reads a @n_bytes-sized unsigned integer from the buffer. The number in the * buffer is expected to be given in the byte order specified by @endian, and * this method takes care of converting the read value to the proper host * endianness. * * The user needs to make sure that at least @n_bytes bytes are available * in the buffer. * * Also note that both @buffer and @buffer_size get updated after the @n_bytes * bytes read. */ void qmi_utils_read_sized_guint_from_buffer (const guint8 **buffer, guint16 *buffer_size, guint n_bytes, QmiEndian endian, guint64 *out) { g_assert (out != NULL); g_assert (buffer != NULL); g_assert (buffer_size != NULL); g_assert (*buffer_size >= n_bytes); *out = 0; memcpy (out, *buffer, n_bytes); if (endian == QMI_ENDIAN_BIG) *out = GUINT64_FROM_BE (*out); else *out = GUINT64_FROM_LE (*out); *buffer = &((*buffer)[n_bytes]); *buffer_size = (*buffer_size) - n_bytes; }
gboolean _ostree_repo_static_delta_dump (OstreeRepo *self, const char *delta_id, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; g_autofree char *from = NULL; g_autofree char *to = NULL; g_autofree char *superblock_path = NULL; g_autoptr(GVariant) delta_superblock = NULL; guint64 total_size = 0, total_usize = 0; guint64 total_fallback_size = 0, total_fallback_usize = 0; guint i; OstreeDeltaEndianness endianness; gboolean swap_endian = FALSE; if (!_ostree_parse_delta_name (delta_id, &from, &to, error)) goto out; superblock_path = _ostree_get_relative_static_delta_superblock_path (from, to); if (!ot_util_variant_map_at (self->repo_dir_fd, superblock_path, (GVariantType*)OSTREE_STATIC_DELTA_SUPERBLOCK_FORMAT, OT_VARIANT_MAP_TRUSTED, &delta_superblock, error)) goto out; g_print ("Delta: %s\n", delta_id); { const char *endianness_description; gboolean was_heuristic; endianness = _ostree_delta_get_endianness (delta_superblock, &was_heuristic); switch (endianness) { case OSTREE_DELTA_ENDIAN_BIG: if (was_heuristic) endianness_description = "big (heuristic)"; else endianness_description = "big"; if (G_BYTE_ORDER == G_LITTLE_ENDIAN) swap_endian = TRUE; break; case OSTREE_DELTA_ENDIAN_LITTLE: if (was_heuristic) endianness_description = "little (heuristic)"; else endianness_description = "little"; if (G_BYTE_ORDER == G_BIG_ENDIAN) swap_endian = TRUE; break; case OSTREE_DELTA_ENDIAN_INVALID: endianness_description = "invalid"; break; default: g_assert_not_reached (); } g_print ("Endianness: %s\n", endianness_description); } { guint64 ts; g_variant_get_child (delta_superblock, 1, "t", &ts); g_print ("Timestamp: %" G_GUINT64_FORMAT "\n", GUINT64_FROM_BE (ts)); } { g_autoptr(GVariant) recurse = NULL; g_variant_get_child (delta_superblock, 5, "@ay", &recurse); g_print ("Number of parents: %u\n", (guint)(g_variant_get_size (recurse) / (OSTREE_SHA256_DIGEST_LEN * 2))); } { g_autoptr(GVariant) fallback = NULL; guint n_fallback; g_variant_get_child (delta_superblock, 7, "@a" OSTREE_STATIC_DELTA_FALLBACK_FORMAT, &fallback); n_fallback = g_variant_n_children (fallback); g_print ("Number of fallback entries: %u\n", n_fallback); for (i = 0; i < n_fallback; i++) { guint64 size, usize; g_autoptr(GVariant) checksum_v = NULL; char checksum[OSTREE_SHA256_STRING_LEN+1]; g_variant_get_child (fallback, i, "(y@aytt)", NULL, &checksum_v, &size, &usize); ostree_checksum_inplace_from_bytes (ostree_checksum_bytes_peek (checksum_v), checksum); size = maybe_swap_endian_u64 (swap_endian, size); usize = maybe_swap_endian_u64 (swap_endian, usize); g_print (" %s\n", checksum); total_fallback_size += size; total_fallback_usize += usize; } { g_autofree char *sizestr = g_format_size (total_fallback_size); g_autofree char *usizestr = g_format_size (total_fallback_usize); g_print ("Total Fallback Size: %" G_GUINT64_FORMAT " (%s)\n", total_fallback_size, sizestr); g_print ("Total Fallback Uncompressed Size: %" G_GUINT64_FORMAT " (%s)\n", total_fallback_usize, usizestr); } } { g_autoptr(GVariant) meta_entries = NULL; guint n_parts; g_variant_get_child (delta_superblock, 6, "@a" OSTREE_STATIC_DELTA_META_ENTRY_FORMAT, &meta_entries); n_parts = g_variant_n_children (meta_entries); g_print ("Number of parts: %u\n", n_parts); for (i = 0; i < n_parts; i++) { if (!show_one_part (self, swap_endian, from, to, meta_entries, i, &total_size, &total_usize, cancellable, error)) goto out; } } { g_autofree char *sizestr = g_format_size (total_size); g_autofree char *usizestr = g_format_size (total_usize); g_print ("Total Part Size: %" G_GUINT64_FORMAT " (%s)\n", total_size, sizestr); g_print ("Total Part Uncompressed Size: %" G_GUINT64_FORMAT " (%s)\n", total_usize, usizestr); } { guint64 overall_size = total_size + total_fallback_size; guint64 overall_usize = total_usize + total_fallback_usize; g_autofree char *sizestr = g_format_size (overall_size); g_autofree char *usizestr = g_format_size (overall_usize); g_print ("Total Size: %" G_GUINT64_FORMAT " (%s)\n", overall_size, sizestr); g_print ("Total Uncompressed Size: %" G_GUINT64_FORMAT " (%s)\n", overall_usize, usizestr); } ret = TRUE; out: return ret; }
void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length) { GPtrArray *objects = NULL; GHashTable *ref_table = NULL; struct serialize_s ser_s; uint8_t offset_size = 0; uint8_t dict_param_size = 0; uint64_t num_objects = 0; uint64_t root_object = 0; uint64_t offset_table_index = 0; GByteArray *bplist_buff = NULL; uint64_t i = 0; uint8_t *buff = NULL; uint64_t *offsets = NULL; uint8_t pad[6] = { 0, 0, 0, 0, 0, 0 }; uint8_t trailer[BPLIST_TRL_SIZE]; //for string glong len = 0; int type = 0; glong items_read = 0; glong items_written = 0; GError *error = NULL; gunichar2 *unicodestr = NULL; //check for valid input if (!plist || !plist_bin || *plist_bin || !length) return; //list of objects objects = g_ptr_array_new(); //hashtable to write only once same nodes ref_table = g_hash_table_new(plist_data_hash, plist_data_compare); //serialize plist ser_s.objects = objects; ser_s.ref_table = ref_table; serialize_plist(plist, &ser_s); //now stream to output buffer offset_size = 0; //unknown yet dict_param_size = get_needed_bytes(objects->len); num_objects = objects->len; root_object = 0; //root is first in list offset_table_index = 0; //unknown yet //setup a dynamic bytes array to store bplist in bplist_buff = g_byte_array_new(); //set magic number and version g_byte_array_append(bplist_buff, BPLIST_MAGIC, BPLIST_MAGIC_SIZE); g_byte_array_append(bplist_buff, BPLIST_VERSION, BPLIST_VERSION_SIZE); //write objects and table offsets = (uint64_t *) malloc(num_objects * sizeof(uint64_t)); for (i = 0; i < num_objects; i++) { plist_data_t data = plist_get_data(g_ptr_array_index(objects, i)); offsets[i] = bplist_buff->len; switch (data->type) { case PLIST_BOOLEAN: buff = (uint8_t *) malloc(sizeof(uint8_t)); buff[0] = data->boolval ? BPLIST_TRUE : BPLIST_FALSE; g_byte_array_append(bplist_buff, buff, sizeof(uint8_t)); free(buff); break; case PLIST_UINT: write_int(bplist_buff, data->intval); break; case PLIST_REAL: write_real(bplist_buff, data->realval); break; case PLIST_KEY: case PLIST_STRING: len = strlen(data->strval); if ( is_ascii_string(data->strval, len) ) { write_string(bplist_buff, data->strval); } else { unicodestr = g_utf8_to_utf16(data->strval, len, &items_read, &items_written, &error); write_unicode(bplist_buff, unicodestr, items_written); g_free(unicodestr); } break; case PLIST_DATA: write_data(bplist_buff, data->buff, data->length); case PLIST_ARRAY: write_array(bplist_buff, g_ptr_array_index(objects, i), ref_table, dict_param_size); break; case PLIST_DICT: write_dict(bplist_buff, g_ptr_array_index(objects, i), ref_table, dict_param_size); break; case PLIST_DATE: write_date(bplist_buff, data->timeval.tv_sec + (double) data->timeval.tv_usec / G_USEC_PER_SEC); break; default: break; } } //free intermediate objects g_hash_table_foreach_remove(ref_table, free_index, NULL); g_ptr_array_free(objects, TRUE); g_hash_table_destroy(ref_table); //write offsets offset_size = get_needed_bytes(bplist_buff->len); offset_table_index = bplist_buff->len; for (i = 0; i < num_objects; i++) { uint8_t *offsetbuff = (uint8_t *) malloc(offset_size); #if G_BYTE_ORDER == G_BIG_ENDIAN offsets[i] = offsets[i] << ((sizeof(uint64_t) - offset_size) * 8); #endif memcpy(offsetbuff, &offsets[i], offset_size); byte_convert(offsetbuff, offset_size); g_byte_array_append(bplist_buff, offsetbuff, offset_size); free(offsetbuff); } //experimental pad to reflect apple's files g_byte_array_append(bplist_buff, pad, 6); //setup trailer num_objects = GUINT64_FROM_BE(num_objects); root_object = GUINT64_FROM_BE(root_object); offset_table_index = GUINT64_FROM_BE(offset_table_index); memcpy(trailer + BPLIST_TRL_OFFSIZE_IDX, &offset_size, sizeof(uint8_t)); memcpy(trailer + BPLIST_TRL_PARMSIZE_IDX, &dict_param_size, sizeof(uint8_t)); memcpy(trailer + BPLIST_TRL_NUMOBJ_IDX, &num_objects, sizeof(uint64_t)); memcpy(trailer + BPLIST_TRL_ROOTOBJ_IDX, &root_object, sizeof(uint64_t)); memcpy(trailer + BPLIST_TRL_OFFTAB_IDX, &offset_table_index, sizeof(uint64_t)); g_byte_array_append(bplist_buff, trailer, BPLIST_TRL_SIZE); //duplicate buffer *plist_bin = (char *) malloc(bplist_buff->len); memcpy(*plist_bin, bplist_buff->data, bplist_buff->len); *length = bplist_buff->len; g_byte_array_free(bplist_buff, TRUE); free(offsets); }
static void pb_socket_got_data(gpointer userdata, PurpleSslConnection *conn, PurpleInputCondition cond) { PushBulletAccount *pba = userdata; gchar *frame; guchar packet_code, length_code; guint64 frame_len; int read_len = 0; gboolean done_some_reads = FALSE; if (G_UNLIKELY(!pba->websocket_header_received)) { // HTTP/1.1 101 Switching Protocols // Server: nginx // Date: Sun, 19 Jul 2015 23:44:27 GMT // Connection: upgrade // Upgrade: websocket // Sec-WebSocket-Accept: pUDN5Js0uDN5KhEWoPJGLyTqwME= // Expires: 0 // Cache-Control: no-cache gint nlbr_count = 0; gchar nextchar; while(nlbr_count < 4 && purple_ssl_read(conn, &nextchar, 1)) { if (nextchar == '\r' || nextchar == '\n') { nlbr_count++; } else { nlbr_count = 0; } } pba->websocket_header_received = TRUE; done_some_reads = TRUE; } packet_code = 0; while((read_len = purple_ssl_read(conn, &packet_code, 1)) == 1) { done_some_reads = TRUE; if (packet_code != 129) { if (packet_code == 136) { purple_debug_error("pushbullet", "websocket closed\n"); purple_ssl_close(conn); pba->websocket = NULL; pba->websocket_header_received = FALSE; // revert to polling pb_start_polling(pba); return; } purple_debug_error("pushbullet", "unknown websocket error %d\n", packet_code); return; } length_code = 0; purple_ssl_read(conn, &length_code, 1); if (length_code <= 125) { frame_len = length_code; } else if (length_code == 126) { guchar len_buf[2]; purple_ssl_read(conn, len_buf, 2); frame_len = (len_buf[1] << 8) + len_buf[0]; } else if (length_code == 127) { purple_ssl_read(conn, &frame_len, 8); frame_len = GUINT64_FROM_BE(frame_len); } purple_debug_info("pushbullet", "frame_len: %d\n", frame_len); frame = g_new0(gchar, frame_len + 1); purple_ssl_read(conn, frame, frame_len); pb_process_frame(pba, frame); g_free(frame); packet_code = 0; } if (done_some_reads == FALSE && read_len == 0) { purple_connection_error_reason(pba->pc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, "Lost connection to server"); } }
static struct apparam_field *parse_aparam(const uint8_t *buffer, uint32_t hlen) { struct apparam_field *param; struct aparam_header *hdr; uint64_t val64; uint32_t len = 0; uint16_t val16; param = g_new0(struct apparam_field, 1); while (len < hlen) { hdr = (void *) buffer + len; switch (hdr->tag) { case ORDER_TAG: if (hdr->len != ORDER_LEN) goto failed; param->order = hdr->val[0]; break; case SEARCHATTRIB_TAG: if (hdr->len != SEARCHATTRIB_LEN) goto failed; param->searchattrib = hdr->val[0]; break; case SEARCHVALUE_TAG: if (hdr->len == 0) goto failed; param->searchval = g_try_malloc0(hdr->len + 1); if (param->searchval) memcpy(param->searchval, hdr->val, hdr->len); break; case FILTER_TAG: if (hdr->len != FILTER_LEN) goto failed; memcpy(&val64, hdr->val, sizeof(val64)); param->filter = GUINT64_FROM_BE(val64); break; case FORMAT_TAG: if (hdr->len != FORMAT_LEN) goto failed; param->format = hdr->val[0]; break; case MAXLISTCOUNT_TAG: if (hdr->len != MAXLISTCOUNT_LEN) goto failed; memcpy(&val16, hdr->val, sizeof(val16)); param->maxlistcount = GUINT16_FROM_BE(val16); break; case LISTSTARTOFFSET_TAG: if (hdr->len != LISTSTARTOFFSET_LEN) goto failed; memcpy(&val16, hdr->val, sizeof(val16)); param->liststartoffset = GUINT16_FROM_BE(val16); break; default: goto failed; } len += hdr->len + sizeof(struct aparam_header); } DBG("o %x sa %x sv %s fil %" G_GINT64_MODIFIER "x for %x max %x off %x", param->order, param->searchattrib, param->searchval, param->filter, param->format, param->maxlistcount, param->liststartoffset); return param; failed: g_free(param); return NULL; }
guint64 msn_read64be(const char *buf) { return GUINT64_FROM_BE(*(guint64 *)buf); }
static enum protocol_status _decode( struct client *client, const guint64 offset, guint64 *len_, guint64 *frame_len) { /* * See http://tools.ietf.org/html/rfc6455#section-5.2 for more on what's * going on here */ guint64 i; guint64 len; guint64 max; guint64 total_len; union { guint32 i; gchar c[4]; } mask; union { guint32 is[4]; __uint128_t i; } mask128; GString *rbuff = client->qev_client.rbuff; gchar *str = rbuff->str + offset; gchar *msg = rbuff->str + offset; guint64 rbuff_len = rbuff->len - offset; guint16 header_len = 0; if ((str[0] & OPCODE) == OPCODE_CLOSE) { qev_close(client, QEV_CLOSE_HUP); return PROT_FATAL; } if (rbuff_len < 6) { return PROT_AGAIN; } if ((str[0] & OPCODE) != OPCODE_TEXT) { qev_close(client, RFC6455_UNSUPPORTED_OPCODE); return PROT_FATAL; } if (!(str[1] & MASKED_BIT)) { qev_close(client, RFC6455_NO_MASK); return PROT_FATAL; } len = str[1] & MASK_LEN; if (len <= PAYLOAD_SHORT) { header_len = 6; memcpy(mask.c, str + 2, 4); } else if (len == PAYLOAD_MEDIUM) { header_len = 8; if (rbuff_len < header_len) { return PROT_AGAIN; } len = GUINT16_FROM_BE(*((guint16*)(str + 2))); memcpy(mask.c, str + 4, 4); } else { header_len = 14; if (rbuff_len < header_len) { return PROT_AGAIN; } len = GUINT64_FROM_BE(*((guint64*)(str + 2))); memcpy(mask.c, str + 10, 4); } if (!qev_safe_uadd(header_len, len, &total_len)) { return PROT_FATAL; } if (rbuff_len < total_len) { return PROT_AGAIN; } *len_ = len; *frame_len = total_len; str += header_len; /* * The following mess warrants an explanation: it's quite a bit * faster than the naive decode. * * Take a look at bench/bench_ws_decode.c for how much faster it is. * * The following steps are taken: * 0) Create a 128 bit masking key from 4 32bit ones. * 1) Gob through 128 bits at a time, until the next XOR would go past * the end of the buffer. * 2) Gob through 64 bits at a time, until the next XOR would overflow * 3) Finish off going through any last characters. */ for (i = 0; i < sizeof(mask128) / sizeof(mask); i++) { mask128.is[i] = mask.i; } max = len - (len & (sizeof(__uint128_t) - 1)); for (i = 0; i < max; i += sizeof(__uint128_t)) { __uint128_t from = *((__uint128_t*)(str + i)); *((__uint128_t*)(msg + i)) = from ^ mask128.i; } max = len - (len & (sizeof(guint64) - 1)); for (; i < max; i += sizeof(guint64)) { guint64 from = *((guint64*)(str + i)); *((guint64*)(msg + i)) = from ^ mask128.i; } for (; i < len; i++) { msg[i] = str[i] ^ mask.c[i & 3]; } *(msg + len) = '\0'; if (!g_utf8_validate(msg, len, NULL)) { qev_close(client, RFC6455_NOT_UTF8); return PROT_FATAL; } return PROT_OK; }
void ot_dump_summary_bytes (GBytes *summary_bytes, OstreeDumpFlags flags) { g_autoptr(GVariant) summary = NULL; g_autoptr(GVariant) refs = NULL; g_autoptr(GVariant) exts = NULL; GVariantIter iter; GVariant *value; char *key; g_return_if_fail (summary_bytes != NULL); summary = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, summary_bytes, FALSE); if (flags & OSTREE_DUMP_RAW) { ot_dump_variant (summary); return; } refs = g_variant_get_child_value (summary, 0); exts = g_variant_get_child_value (summary, 1); g_variant_iter_init (&iter, refs); while ((value = g_variant_iter_next_value (&iter)) != NULL) { const char *ref_name = NULL; g_variant_get_child (value, 0, "&s", &ref_name); if (ref_name != NULL) { g_autoptr(GVariant) csum_v = NULL; g_autoptr(GVariantIter) metadata = NULL; guint64 commit_size; g_variant_get_child (value, 1, "(t@aya{sv})", &commit_size, &csum_v, &metadata); dump_summary_ref (ref_name, commit_size, csum_v, metadata); g_print ("\n"); } g_variant_unref (value); } g_variant_iter_init (&iter, exts); while (g_variant_iter_loop (&iter, "{sv}", &key, &value)) { g_autofree gchar *value_str = NULL; const gchar *pretty_key = NULL; if (g_strcmp0 (key, OSTREE_SUMMARY_STATIC_DELTAS) == 0) { pretty_key = "Static Deltas"; value_str = g_variant_print (value, FALSE); } else if (g_strcmp0 (key, OSTREE_SUMMARY_LAST_MODIFIED) == 0) { pretty_key = "Last-Modified"; value_str = uint64_secs_to_iso8601 (GUINT64_FROM_BE (g_variant_get_uint64 (value))); } else if (g_strcmp0 (key, OSTREE_SUMMARY_EXPIRES) == 0) { pretty_key = "Expires"; value_str = uint64_secs_to_iso8601 (GUINT64_FROM_BE (g_variant_get_uint64 (value))); } else { value_str = g_variant_print (value, FALSE); } /* Print out. */ if (pretty_key != NULL) g_print ("%s (%s): %s\n", pretty_key, key, value_str); else g_print ("%s: %s\n", key, value_str); } }