buffp buff_realloc(buffp b, unsigned size) { void *p; if (!b || !(b->buffer)) return buff_alloc(size); if (!size) { buff_free(b); return NULL; } p = get_mem(size); if (!p) { buff_free(b); return NULL; } if (size > b->alloc) memcpy(p, b->buffer, b->alloc); else memcpy(p, b->buffer, size); free_mem(b->buffer); b->buffer = p; b->alloc = size; return b; }
buffp buff_dup(buffp b1) { buffp b; if (!b1) return NULL; b = buff_alloc(b1->alloc); b->len = b1->len; memcpy(b->buffer, b1->buffer, b1->len); return b; }
buffp buff_append_byte(buffp b, char c) { if (!b) b = buff_alloc(ALLOCSIZE); if (b->len >= b->alloc) buff_realloc(b, b->alloc + ALLOCSIZE); ((char *)(b->buffer))[b->len++] = c; return b; }
static void script_tx_sighash(struct wallet *wallet, uint256 *hash, const struct buff *scriptPubKey, const struct btc_msg_tx *tx, uint32 idx, enum script_hash_type hashType) { struct btc_msg_tx *tx2; struct buff *buf; int i; ASSERT(idx < tx->in_count); memset(hash, 0, sizeof *hash); tx2 = btc_msg_tx_dup(tx); Log(LGPFX " Computing sighash for txi-%u/%llu\n", idx, tx2->in_count); /* * Zero-out all the inputs' signatures. */ for (i = 0; i < tx2->in_count; i++) { tx2->tx_in[i].scriptLength = 0; } size_t len = buff_maxlen(scriptPubKey); ASSERT(len > 0); ASSERT(tx2->tx_in[idx].scriptSig == NULL); ASSERT(tx2->tx_in[idx].scriptLength == 0); tx2->tx_in[idx].scriptLength = len; tx2->tx_in[idx].scriptSig = safe_malloc(len); memcpy(tx2->tx_in[idx].scriptSig, buff_base(scriptPubKey), len); ASSERT((hashType & 0x1f) == SIGHASH_ALL); /* * Final step: * * Serialize tx + hashType (as a uint32) and compute hash. */ buf = buff_alloc(); serialize_tx(buf, tx2); serialize_uint32(buf, hashType); hash256_calc(buff_base(buf), buff_curlen(buf), hash); buff_free(buf); btc_msg_tx_free(tx2); free(tx2); }
static struct buff * txdb_serialize_tx_data(const struct tx_ser_data *tx) { struct buff *buf; ASSERT(tx); buf = buff_alloc(); serialize_uint256(buf, &tx->blkHash); serialize_uint64(buf, tx->timestamp); serialize_varint(buf, tx->len); serialize_bytes(buf, tx->buf, tx->len); return buf; }
buffp buff_cat(buffp b1, buffp b2) { buffp b; if (!b1 || !(b1->buffer)) return buff_dup(b2); if (!b2 || !(b2->buffer)) return buff_dup(b1); b = buff_alloc(b1->alloc + b2->alloc); memcpy(b->buffer, b1->buffer, b1->len); memcpy(((void *)(((char *)b->buffer) + b1->len)), b2->buffer, b2->len); b->len = b1->len + b2->len; return b; }
int script_txo_generate(const uint160 *pubkey, uint8 **script, uint64 *scriptLen) { struct buff *buf = buff_alloc(); serialize_uint8(buf, OP_DUP); serialize_uint8(buf, OP_HASH160); script_push_data(buf, pubkey, sizeof *pubkey); serialize_uint8(buf, OP_EQUALVERIFY); serialize_uint8(buf, OP_CHECKSIG); *script = buff_base(buf); *scriptLen = buff_curlen(buf); free(buf); return 0; }
int buff_fread(int fd,off_t offset,size_t count,\ buff_t* _pb,uint64_t off) { buff_t pb = *_pb; uint64_t size = count + off; int ret; if(pb->size < size) { if(!pb->size) { pb->ptr = calloc(size,sizeof(unsigned char)); if(!pb->ptr) return -1; } else { //check reference if(pb->ref != 1) { if((buff_alloc(&pb)) < 0) return -1; if(!(pb->ptr = calloc(size,sizeof(unsigned char)))) { buff_dec(&pb); return -1; } } else { if(pb->size < size) { if(!(pb->ptr = realloc(pb,size))) return -1; } } } } ret = pread(fd,pb->ptr,count,offset); if((ret < 0) && (pb != *_pb)) { buff_dec(&pb); return ret; } pb->offset = size; //COW,it's written,change the buffer if(pb != *_pb) { buff_dec(_pb); *_pb = pb; } return ret; }
static struct buff * txdb_serialize_tx_key(uint64 tx_seq, const char *hashStr) { struct buff *buf; char str[256]; ASSERT(hashStr); buf = buff_alloc(); snprintf(str, sizeof str, "/tx/%010llu/%s", tx_seq, hashStr); serialize_bytes(buf, str, strlen(str) + 1); /* include terminal '\0' */ Log(LGPFX" adding %s seq=%llu : '%s'\n", hashStr, tx_seq, str); return buf; }
buffp create_menu_popup(strp name, buffp popup, int flags) { MENU_NODE *pNode; buffp b; b = buff_alloc(sizeof(MENU_NODE)); pNode = (MENU_NODE *)b->buffer; b->len = sizeof(MENU_NODE); pNode->data.menuflag = flags | MF_POPUP; pNode->data.menuname = name; pNode->data.menuid = 0; pNode->data.menupopup = NULL; pNode->next = NULL; pNode->child = (MENU_NODE *)buff_ind(popup); return b; }
/** @brief set up an SBD RB (1) build an SBD RB instance in the kernel space\n (2) allocate an SBD array in SHMEM\n (3) allocate a data buffer array in SHMEM if possible\n */ static int setup_sbd_rb(struct sbd_link_device *sl, struct sbd_ring_buffer *rb, enum direction dir, struct sbd_link_attr *link_attr) { unsigned int alloc_size; int i; rb->sl = sl; rb->lnk_hdr = link_attr->lnk_hdr; rb->more = false; rb->total = 0; rb->rcvd = 0; /* Initialize an SBD RB instance in the kernel space. */ rb->id = link_attr->id; rb->ch = link_attr->ch; rb->dir = dir; rb->len = link_attr->rb_len[dir]; rb->buff_size = link_attr->buff_size[dir]; rb->payload_offset = 0; /* Prepare array of pointers to the data buffer for each SBD */ alloc_size = (rb->len * sizeof(u8 *)); rb->buff = kmalloc(alloc_size, GFP_ATOMIC); if (!rb->buff) return -ENOMEM; /* (1) Allocate an array of data buffers in SHMEM. (2) Register the address of each data buffer. */ alloc_size = (rb->len * rb->buff_size); rb->buff_rgn = (u8 *)buff_alloc(sl, alloc_size); if (!rb->buff_rgn) return -ENOMEM; for (i = 0; i < rb->len; i++) rb->buff[i] = rb->buff_rgn + (i * rb->buff_size); #if 0 mif_err("RB[%d:%d][%s] buff_rgn {addr:0x%08X offset:%d size:%d}\n", rb->id, rb->ch, udl_str(dir), (int)rb->buff_rgn, calc_offset(rb->buff_rgn, sl->shmem), alloc_size); #endif /* Prepare SBD array in SHMEM. */ rb->rp = &sl->rp[rb->dir][rb->id]; rb->wp = &sl->wp[rb->dir][rb->id]; alloc_size = (rb->len * sizeof(u32)); rb->addr_v = (u32 *)desc_alloc(sl, alloc_size); if (!rb->addr_v) return -ENOMEM; rb->size_v = (u32 *)desc_alloc(sl, alloc_size); if (!rb->size_v) return -ENOMEM; /* Register each data buffer to the corresponding SBD. */ for (i = 0; i < rb->len; i++) { rb->addr_v[i] = calc_offset(rb->buff[i], sl->shmem); rb->size_v[i] = 0; } rb->iod = link_get_iod_with_channel(sl->ld, rb->ch); rb->ld = sl->ld; return 0; }
int txdb_craft_tx(struct txdb *txdb, const struct btc_tx_desc *tx_desc, btc_msg_tx *tx) { struct buff *buf; char hashStr[80]; uint256 txHash; uint64 change; uint32 numCoins; bool relevant; mtime_t ts; int res; res = 0; relevant = 0; tx->version = 1; txdb_prepare_txout(tx_desc, tx); /* * In order to properly size 'tx->txIn', we need to determine how many coins * we're going to use. Right now, let's just vastly overestimate. */ numCoins = hashtable_getnumentries(txdb->hash_txo); tx->tx_in = safe_calloc(numCoins, sizeof *tx->tx_in); txdb_print_coins(txdb, 1); txdb_select_coins(txdb, tx_desc, tx, &change); /* * Change! XXX: fix me. */ if (change > 0) { const char *btc_change; btc_change = wallet_get_change_addr(btc->wallet); tx->out_count++; txdb_set_txo(tx, tx->out_count - 1, btc_change, change); Warning(LGPFX" change: %llu -- %.8f BTC\n", change, change / ONE_BTC); } txdb_sign_tx_inputs(txdb, tx); /* * Now that the tx is ready, serialize it and check that it's not too big. */ btcmsg_print_tx(tx); buf = buff_alloc(); serialize_tx(buf, tx); if (buff_curlen(buf) > BTC_TX_MAX_SIZE) { Warning(LGPFX" tx too large: %zu\n", buff_curlen(buf)); res = 1; goto exit; } hash256_calc(buff_base(buf), buff_curlen(buf), &txHash); uint256_snprintf_reverse(hashStr, sizeof hashStr, &txHash); Warning(LGPFX" %s (%zu bytes)\n", hashStr, buff_curlen(buf)); Log_Bytes(LGPFX" TX: ", buff_base(buf), buff_curlen(buf)); if (bitc_testing) { Warning("TESTING! Not saving/relaying tx.\n"); goto exit; } ts = time(NULL); res = txdb_remember_tx(txdb, 0 /* save to disk */, ts, buff_base(buf), buff_curlen(buf), &txHash, NULL, &relevant); txdb_save_tx_label(tx_desc, hashStr); txdb_export_tx_info(txdb); res = peergroup_new_tx_broadcast(btc->peerGroup, buf, ts + 2 * 60 * 60, &txHash); if (res) { Warning(LGPFX" failed to transmit tx: %d\n", res); bitcui_set_status("got errors while broadcasting tx"); } exit: buff_free(buf); /* * XXX: We should mark the coins used by this tx as "reserved", so that we * do not attempt to use conflicting coins in subsequent TXs. */ return res; }
int script_sign(struct wallet *wallet, const struct btc_msg_tx_out *txo, struct btc_msg_tx *tx, uint32 idx, enum script_hash_type hashType) { struct btc_msg_tx_in *txi; enum script_txout_type type; struct buff *scriptSig; struct buff scriptPubKey; uint8 *data_addr; size_t data_len; uint256 hash; int res; ASSERT(idx < tx->in_count); scriptSig = buff_alloc(); buff_init(&scriptPubKey, txo->scriptPubKey, txo->scriptLength); Log_Bytes("scriptPubKey:", txo->scriptPubKey, txo->scriptLength); script_tx_sighash(wallet, &hash, &scriptPubKey, tx, idx, hashType); res = script_match_type(&scriptPubKey, &type, &data_addr, &data_len); if (res) { NOT_TESTED(); goto exit; } switch (type) { case TX_PUBKEY: Warning(LGPFX " script TX_PUBKEY\n"); NOT_IMPLEMENTED(); break; case TX_PUBKEYHASH: (void)0; // XXX: clang bug? uint160 *keyHash = (uint160 *)data_addr; ASSERT(data_len == sizeof(uint160)); res = script_sign_hash(wallet, keyHash, &hash, hashType, scriptSig); if (res) { NOT_TESTED(); goto exit; } res = script_push_pubkey(wallet, keyHash, scriptSig); if (res) { NOT_TESTED(); goto exit; } break; default: NOT_IMPLEMENTED(); Warning(LGPFX " script TX_NONSTANDARD\n"); break; } txi = tx->tx_in + idx; txi->scriptLength = buff_curlen(scriptSig); txi->scriptSig = buff_base(scriptSig); exit: free(scriptSig); free(data_addr); return res; }
resp make_icon_resource(buffp b) { BYTE *temp; WORD i, type, count, rgb_count; ICONDIR_NODE *cur_entry, *icon_entry_table; ICON_NODE *cur_image; DWORD image_offset, image_size; BYTE *temp_offset; BITMAPINFOHEADER *bmp_info_header; RGBQUAD *rgb_quad; char *XOR_bits, *AND_bits; WORD mask_bytes; static unsigned IdOrdinal = 1; resp r, rIcon; type = get_word((BYTE *)b->buffer + TYPE_OFFSET); count = get_word((BYTE *)b->buffer + TYPE_OFFSET + 2); if (type != 1) FATAL(("Invalid icon resource, type=%d", type)); r = res_new(); r->type = (char *)RT_GROUP_ICON; r->flags = FLAG_DEFAULT; r->b = buff_alloc(count * sizeof(ICONDIR_NODE)); r->b->len = r->b->alloc; icon_entry_table = (ICONDIR_NODE *)r->b->buffer; cur_entry = icon_entry_table; cur_entry->next = (ICONDIR_NODE *)NULL; i = 0; while (1) { temp = (BYTE *)b->buffer + ICON_DIR_OFFSET + i * DIR_ENTRY_SIZE; cur_entry->data.bWidth = temp[0]; cur_entry->data.bHeight = temp[1]; cur_entry->data.wOrdinalNumber = IdOrdinal; cur_entry->data.bColorCount = temp[2]; cur_entry->data.wPlanes = get_word(&temp[4]); cur_entry->data.wBitsPerPel = 0; /* Unused by library */ cur_entry->data.dwBytesInRes = 0; /* Unused by library */ image_size = get_dword(&temp[8]); image_offset = get_dword(&temp[12]); temp_offset = (BYTE *)b->buffer + image_offset; ALLOC(bmp_info_header, BITMAPINFOHEADER); get_bmp_info_header(bmp_info_header, temp_offset); temp_offset += bmp_info_header->biSize; rgb_count = bit_to_rgb(bmp_info_header->biBitCount); CALLOC(rgb_quad, rgb_count, RGBQUAD); memcpy((char *)rgb_quad, (char *)temp_offset,sizeof(RGBQUAD)*rgb_count); temp_offset += sizeof(RGBQUAD) * rgb_count; mask_bytes = (int)(bmp_info_header->biWidth * bmp_info_header->biHeight * bmp_info_header->biBitCount) / 16; NALLOC(XOR_bits, mask_bytes, char *); memcpy(XOR_bits, (char *)temp_offset, mask_bytes); temp_offset += mask_bytes; mask_bytes /= bmp_info_header->biBitCount; /* AND mask is always MonoChrome */ NALLOC(AND_bits, mask_bytes, char *); memcpy(AND_bits, (char *)temp_offset, mask_bytes); rIcon = res_new(); BUFF_STRUCT(rIcon->b, cur_image, ICON_NODE); cur_image->data.icon_bmp_hdr = bmp_info_header; cur_image->data.icon_rgb_quad = rgb_quad; cur_image->data.icon_xor_mask = (BYTE*)XOR_bits; cur_image->data.icon_and_mask = (BYTE*)AND_bits; rIcon->type = RT_ICON; rIcon->name = (const char *)(IdOrdinal); /* Flags? */ add_common_resource(rIcon); IdOrdinal++; if (count == ++i) break; else { ALLOC(cur_entry->next, ICONDIR_NODE); cur_entry = cur_entry->next; cur_entry->next = (ICONDIR_NODE *)NULL; } } buff_free(b); return r; }