int HeaderFieldsSame(GptHeader *h1, GptHeader *h2) { if (Memcmp(h1->signature, h2->signature, sizeof(h1->signature))) return 1; if (h1->revision != h2->revision) return 1; if (h1->size != h2->size) return 1; if (h1->reserved_zero != h2->reserved_zero) return 1; if (h1->first_usable_lba != h2->first_usable_lba) return 1; if (h1->last_usable_lba != h2->last_usable_lba) return 1; if (Memcmp(&h1->disk_uuid, &h2->disk_uuid, sizeof(Guid))) return 1; if (h1->number_of_entries != h2->number_of_entries) return 1; if (h1->size_of_entry != h2->size_of_entry) return 1; if (h1->entries_crc32 != h2->entries_crc32) return 1; return 0; }
static int addaddr(struct in6_addr*list,struct in6_addr itm) { int i; /*do nothing if it is a null addr*/ if(Memcmp(&itm,&NULLADDR,16)==0)return -1; /*go through list...*/ for(i=0;i<MAXITEMS;i++){ /*if the current one is a null addr, insert it here*/ if(Memcmp(&list[i],&NULLADDR,16)==0){ Memcpy(&list[i],&itm,16); return i; } /*otherwise: check whether it is already known*/ if(Memcmp(&list[i],&itm,16)==0) return -1; } /*no free space*/ return -1; }
int CheckEntries(GptEntry *entries, GptHeader *h) { if (!entries) return GPT_ERROR_INVALID_ENTRIES; GptEntry *entry; uint32_t crc32; uint32_t i; /* Check CRC before examining entries. */ crc32 = Crc32((const uint8_t *)entries, h->size_of_entry * h->number_of_entries); if (crc32 != h->entries_crc32) return GPT_ERROR_CRC_CORRUPTED; /* Check all entries. */ for (i = 0, entry = entries; i < h->number_of_entries; i++, entry++) { GptEntry *e2; uint32_t i2; if (IsUnusedEntry(entry)) continue; /* Entry must be in valid region. */ if ((entry->starting_lba < h->first_usable_lba) || (entry->ending_lba > h->last_usable_lba) || (entry->ending_lba < entry->starting_lba)) return GPT_ERROR_OUT_OF_REGION; /* Entry must not overlap other entries. */ for (i2 = 0, e2 = entries; i2 < h->number_of_entries; i2++, e2++) { if (i2 == i || IsUnusedEntry(e2)) continue; if ((entry->starting_lba >= e2->starting_lba) && (entry->starting_lba <= e2->ending_lba)) return GPT_ERROR_START_LBA_OVERLAP; if ((entry->ending_lba >= e2->starting_lba) && (entry->ending_lba <= e2->ending_lba)) return GPT_ERROR_END_LBA_OVERLAP; /* UniqueGuid field must be unique. */ if (0 == Memcmp(&entry->unique, &e2->unique, sizeof(Guid))) return GPT_ERROR_DUP_GUID; } } /* Success */ return 0; }
VbError_t VbCheckDisplayKey(VbCommonParams *cparams, uint32_t key, VbNvContext *vncptr) { int i; /* Update key buffer */ for(i = 1; i < MAGIC_WORD_LEN; i++) MagicBuffer[i - 1] = MagicBuffer[i]; /* Save as lower-case ASCII */ MagicBuffer[MAGIC_WORD_LEN - 1] = (key | 0x20) & 0xFF; if ('\t' == key) { /* Tab = display debug info */ return VbDisplayDebugInfo(cparams, vncptr); } else if (VB_KEY_LEFT == key || VB_KEY_RIGHT == key || VB_KEY_DOWN == key || VB_KEY_UP == key) { /* Arrow keys = change localization */ uint32_t loc = 0; uint32_t count = 0; VbNvGet(vncptr, VBNV_LOCALIZATION_INDEX, &loc); if (VBERROR_SUCCESS != VbGetLocalizationCount(cparams, &count)) loc = 0; /* No localization count (bad GBB?) */ else if (VB_KEY_RIGHT == key || VB_KEY_UP == key) loc = (loc < count - 1 ? loc + 1 : 0); else loc = (loc > 0 ? loc - 1 : count - 1); VBDEBUG(("VbCheckDisplayKey() - change localization to %d\n", (int)loc)); VbNvSet(vncptr, VBNV_LOCALIZATION_INDEX, loc); #ifdef SAVE_LOCALE_IMMEDIATELY VbNvTeardown(vncptr); /* really only computes checksum */ if (vncptr->raw_changed) VbExNvStorageWrite(vncptr->raw); #endif /* Force redraw of current screen */ return VbDisplayScreen(cparams, disp_current_screen, 1, vncptr); } if (0 == Memcmp(MagicBuffer, MAGIC_WORD, MAGIC_WORD_LEN)) { if (VBEASTEREGG) (void)VbDisplayScreen(cparams, disp_current_screen, 1, vncptr); } return VBERROR_SUCCESS; }
void DmaIntModeDemo(void) { UINT8 ch_no; //Dma channel number UINT32 len = 1023; UINT32 tmp_src[1023], tmp_dst[1023]; UINT8 ret; printf("Dma Int Mode Demo.\r\n"); /* enable Dma Clk */ ScuDmaClkEn(); for(ch_no = 0; ch_no < 8; ch_no++) { trans_finish_flag = FALSE; /* initial source data */ GetTrueRand8((UINT8 *)tmp_src, len << 2); /* lock dma channel */ ret = DmaChLock(ch_no); /* setting dma trans interrupt handle */ ret |= DmaSetIntrHandle(ch_no, DmaFinishHdl, NULL, NULL, NULL); /* setting dma trans parameter */ ret |= SetupMode(ch_no, MEM_MEM, DISCRIC, NO_PER, NO_PER, ENINC, ENINC, W_32BIT, len, H_PRI); /* setting dma trans address */ ret |= SetTransAddress(ch_no, (UINT32)tmp_src, (UINT32)tmp_dst); /* start dma trans */ ret |= DmaStart(ch_no); if(ret != DMA_RET_SUCESS) { printf("dma channel %d trans error, error code %d\r\n", ch_no, ret); return; } /* wait trans finish */ while(trans_finish_flag == FALSE); /* disable dma channel trrans finish interrupt */ DisDmaIntr(0x1 << ch_no); if(Memcmp(tmp_src, tmp_dst, len) != 0) { printf("dma channel %d trans error, data error\r\n", ch_no); return; } else { printf("dma channel %d trans sucess\r\n", ch_no); } DmaChUnlock(ch_no); } ScuDmaClkDis(); }
/*execute the script*/ static int execscript() { int i; char tmp[128],buf[4096]; /*check there is anything to do*/ if(Memcmp(addresses,&NULLADDR,16)==0 && Memcmp(prefixes,&NULLADDR,16)==0 && Memcmp(dnsservers,&NULLADDR,16)==0 && *dnsnames==0){ td_log(LOGWARN,"no information has been received from the server, not executing script"); return 1; } /*encode addresses*/ buf[0]=0; for(i=0;i<MAXITEMS;i++){ if(Memcmp(&addresses[i],&NULLADDR,16)==0)break; if(i)strncat(buf," ",sizeof(buf)); strncat(buf,inet_ntop(AF_INET6,&addresses[i],tmp,sizeof(tmp)),sizeof(buf)); } if(buf[0])setenv("IPADDR",buf,1); /*encode prefixes*/ buf[0]=0; for(i=0;i<MAXITEMS;i++){ if(Memcmp(&prefixes[i],&NULLADDR,16)==0)break; if(i)strncat(buf," ",sizeof(buf)); strncat(buf,inet_ntop(AF_INET6,&prefixes[i],tmp,sizeof(tmp)),sizeof(buf)); snprintf(tmp,sizeof(tmp),"/%i",(int)prefixlens[i]); strncat(buf,tmp,sizeof(buf)); } if(buf[0])setenv("PREFIX",buf,1); /*encode DNS servers*/ buf[0]=0; for(i=0;i<MAXITEMS;i++){ if(Memcmp(&dnsservers[i],&NULLADDR,16)==0)break; if(i)strncat(buf," ",sizeof(buf)); strncat(buf,inet_ntop(AF_INET6,&dnsservers[i],tmp,sizeof(tmp)),sizeof(buf)); } if(buf[0])setenv("DNSSRV",buf,1); /*encode DNS search names*/ buf[0]=0; for(i=0;i<MAXITEMS;i++){ if(!dnsnames[i])break; if(i)strncat(buf," ",sizeof(buf)); strncat(buf,dnsnames[i],sizeof(buf)); } if(buf[0])setenv("DNSDOM",buf,1); /*dhcp server addr*/ setenv("DHCPSRV",inet_ntop(AF_INET6,&dhcpserver,tmp,sizeof(tmp)),1); /*call*/ return system(script)!=0; }
void DmaScanModeDemo(void) { UINT8 ch_no; //Dma channel number UINT32 len = 1023; UINT32 tmp_src[1023], tmp_dst[1023]; UINT8 ret; printf("Dma Scan Mode Demo.\r\n"); /* enable Dma Clk */ ScuDmaClkEn(); for(ch_no = 0; ch_no < 8; ch_no++) { /* initial source data */ GetTrueRand8((UINT8 *)tmp_src, len << 2); /* lock dma channel */ ret = DmaChLock(ch_no); /* setting dma trans parameter */ ret |= SetupMode(ch_no, MEM_MEM, DISCRIC, NO_PER, NO_PER, ENINC, ENINC, W_32BIT, len, H_PRI); /* setting dma trans address */ ret |= SetTransAddress(ch_no, (UINT32)tmp_src, (UINT32)tmp_dst); /* start dma trans */ ret |= DmaTrans(ch_no); if(ret != DMA_RET_SUCESS) { printf("dma channel %d trans error, error code %d\r\n", ch_no, ret); return; } /* dma trans finish */ if(Memcmp(tmp_src, tmp_dst, len) != 0) { printf("dma channel %d trans error, data error\r\n", ch_no); return; } else { printf("dma channel %d trans sucess\r\n", ch_no); } DmaChUnlock(ch_no); } ScuDmaClkDis(); }
/* Adjusts KERNEL_VERSIONS space. */ static uint32_t RollbackTest_AdjustKernelVersions(int* wrong_value) { uint8_t kdata[KERNEL_SPACE_SIZE]; int exists; uint32_t result; result = TlclRead(KERNEL_VERSIONS_NV_INDEX, kdata, sizeof(kdata)); if (result != TPM_SUCCESS && result != TPM_E_BADINDEX) { return result; } *wrong_value = Memcmp(kdata + sizeof(uint32_t), KERNEL_SPACE_UID, KERNEL_SPACE_UID_SIZE); /* for later use */ exists = result == TPM_SUCCESS; if (RBTS.KERNEL_VERSIONS_exists && !exists) { RETURN_ON_FAILURE(SafeDefineSpace(KERNEL_VERSIONS_NV_INDEX, TPM_NV_PER_PPWRITE, KERNEL_SPACE_SIZE)); } if (!RBTS.KERNEL_VERSIONS_exists && exists) { RETURN_ON_FAILURE(RollbackTest_RemoveSpace(KERNEL_VERSIONS_NV_INDEX)); } return TPM_SUCCESS; }
int user_addr_store(void * sub_proc,void * message) { int ret; struct user_address * user_addr; MSG_EXPAND * expand; struct expand_flow_trace * flow_trace; struct login_info * login_data; DB_RECORD * db_record; int trace_offset; ret=message_get_record(message,&login_data,0); if(ret<0) return ret; ret=message_get_define_expand(message,&expand,DTYPE_MSG_EXPAND,SUBTYPE_FLOW_TRACE); if(ret<0) return ret; if(expand==NULL) return -EINVAL; flow_trace=expand->expand; if(flow_trace->record_num<=0) return -EINVAL; trace_offset=DIGEST_SIZE*(flow_trace->record_num-1); db_record=memdb_find_byname(login_data->user,DTYPE_CRYPTO_DEMO,SUBTYPE_USER_ADDR); if(db_record!=NULL) { user_addr=(struct user_address *)db_record->record; if(Memcmp(user_addr->addr,flow_trace->trace_record+trace_offset,DIGEST_SIZE)==0) return 0; memdb_remove_record(db_record); } user_addr=Talloc0(sizeof(struct user_address)); if(user_addr==NULL) return -ENOMEM; Strncpy(user_addr->user,login_data->user,DIGEST_SIZE); Memcpy(user_addr->addr,flow_trace->trace_record+trace_offset,DIGEST_SIZE); memdb_store(user_addr,DTYPE_CRYPTO_DEMO,SUBTYPE_USER_ADDR,login_data->user); return 1; }
int IsUnusedEntry(const GptEntry *e) { static Guid zero = {{{0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0}}}}; return !Memcmp(&zero, (const uint8_t*)(&e->type), sizeof(zero)); }
/** * Write any changes for the GPT data back to the drive, then free the buffers. * * Returns 0 if successful, 1 if error. */ int WriteAndFreeGptData(VbExDiskHandle_t disk_handle, GptData *gptdata) { int legacy = 0; GptHeader *header = (GptHeader *)gptdata->primary_header; uint64_t entries_bytes = header->number_of_entries * header->size_of_entry; uint64_t entries_sectors = entries_bytes / gptdata->sector_bytes; int ret = 1; /* * TODO(namnguyen): Preserve padding between primary GPT header and * its entries. */ uint64_t entries_lba = GPT_PMBR_SECTORS + GPT_HEADER_SECTORS; if (gptdata->primary_header) { GptHeader *h = (GptHeader *)(gptdata->primary_header); entries_lba = h->entries_lba; /* * Avoid even looking at this data if we don't need to. We * may in fact not have read it from disk if the read failed, * and this avoids a valgrind complaint. */ if (gptdata->modified) { legacy = !Memcmp(h->signature, GPT_HEADER_SIGNATURE2, GPT_HEADER_SIGNATURE_SIZE); } if (gptdata->modified & GPT_MODIFIED_HEADER1) { if (legacy) { VBDEBUG(("Not updating GPT header 1: " "legacy mode is enabled.\n")); } else { VBDEBUG(("Updating GPT header 1\n")); if (0 != VbExDiskWrite(disk_handle, 1, 1, gptdata->primary_header)) goto fail; } } } if (gptdata->primary_entries) { if (gptdata->modified & GPT_MODIFIED_ENTRIES1) { if (legacy) { VBDEBUG(("Not updating GPT entries 1: " "legacy mode is enabled.\n")); } else { VBDEBUG(("Updating GPT entries 1\n")); if (0 != VbExDiskWrite(disk_handle, entries_lba, entries_sectors, gptdata->primary_entries)) goto fail; } } } entries_lba = (gptdata->gpt_drive_sectors - entries_sectors - GPT_HEADER_SECTORS); if (gptdata->secondary_header) { GptHeader *h = (GptHeader *)(gptdata->secondary_header); entries_lba = h->entries_lba; if (gptdata->modified & GPT_MODIFIED_HEADER2) { VBDEBUG(("Updating GPT entries 2\n")); if (0 != VbExDiskWrite(disk_handle, gptdata->gpt_drive_sectors - 1, 1, gptdata->secondary_header)) goto fail; } } if (gptdata->secondary_entries) { if (gptdata->modified & GPT_MODIFIED_ENTRIES2) { VBDEBUG(("Updating GPT header 2\n")); if (0 != VbExDiskWrite(disk_handle, entries_lba, entries_sectors, gptdata->secondary_entries)) goto fail; } } ret = 0; fail: /* Avoid leaking memory on disk write failure */ if (gptdata->primary_header) VbExFree(gptdata->primary_header); if (gptdata->primary_entries) VbExFree(gptdata->primary_entries); if (gptdata->secondary_entries) VbExFree(gptdata->secondary_entries); if (gptdata->secondary_header) VbExFree(gptdata->secondary_header); /* Success */ return ret; }
int CheckHeader(GptHeader *h, int is_secondary, uint64_t streaming_drive_sectors, uint64_t gpt_drive_sectors, uint32_t flags) { if (!h) return 1; /* * Make sure we're looking at a header of reasonable size before * attempting to calculate CRC. */ if (Memcmp(h->signature, GPT_HEADER_SIGNATURE, GPT_HEADER_SIGNATURE_SIZE) && Memcmp(h->signature, GPT_HEADER_SIGNATURE2, GPT_HEADER_SIGNATURE_SIZE)) return 1; if (h->revision != GPT_HEADER_REVISION) return 1; if (h->size < MIN_SIZE_OF_HEADER || h->size > MAX_SIZE_OF_HEADER) return 1; /* Check CRC before looking at remaining fields */ if (HeaderCrc(h) != h->header_crc32) return 1; /* Reserved fields must be zero. */ if (h->reserved_zero) return 1; /* Could check that padding is zero, but that doesn't matter to us. */ /* * If entry size is different than our struct, we won't be able to * parse it. Technically, any size 2^N where N>=7 is valid. */ if (h->size_of_entry != sizeof(GptEntry)) return 1; if ((h->number_of_entries < MIN_NUMBER_OF_ENTRIES) || (h->number_of_entries > MAX_NUMBER_OF_ENTRIES) || (!(flags & GPT_FLAG_EXTERNAL) && h->number_of_entries != MAX_NUMBER_OF_ENTRIES)) return 1; /* * Check locations for the header and its entries. The primary * immediately follows the PMBR, and is followed by its entries. The * secondary is at the end of the drive, preceded by its entries. */ if (is_secondary) { if (h->my_lba != gpt_drive_sectors - GPT_HEADER_SECTORS) return 1; if (h->entries_lba != h->my_lba - CalculateEntriesSectors(h)) return 1; } else { if (h->my_lba != GPT_PMBR_SECTORS) return 1; if (h->entries_lba < h->my_lba + 1) return 1; } /* FirstUsableLBA <= LastUsableLBA. */ if (h->first_usable_lba > h->last_usable_lba) return 1; if (flags & GPT_FLAG_EXTERNAL) { if (h->last_usable_lba >= streaming_drive_sectors) { return 1; } return 0; } /* * FirstUsableLBA must be after the end of the primary GPT table array. * LastUsableLBA must be before the start of the secondary GPT table * array. */ /* TODO(namnguyen): Also check for padding between header & entries. */ if (h->first_usable_lba < 2 + CalculateEntriesSectors(h)) return 1; if (h->last_usable_lba >= streaming_drive_sectors - 1 - CalculateEntriesSectors(h)) return 1; /* Success */ return 0; }
int IsKernelEntry(const GptEntry *e) { static Guid chromeos_kernel = GPT_ENT_TYPE_CHROMEOS_KERNEL; return !Memcmp(&e->type, &chromeos_kernel, sizeof(Guid)); }
/** * Find and return a valid set of note events. * * We'll use the user's struct if possible, but we will still enforce the * 30-second timeout and require at least a second of audible noise within that * period. We allocate storage for two reasons: the user's struct will be in * flash, which is slow to read, and we may need one extra note at the end to * pad out the user's notes to a full 30 seconds. The caller should free it * when finished. */ static void VbGetDevMusicNotes(VbAudioContext *audio, int use_short) { VbDevMusicNote *notebuf = 0; VbDevMusicNote *builtin = 0; VbDevMusic *hdr = CUSTOM_MUSIC_NOTES; uint32_t maxsize = CUSTOM_MUSIC_MAXSIZE; /* always <= flash size (8M) */ uint32_t maxnotes, mysum, mylen, i; uint32_t this_msecs, on_msecs, total_msecs; uint32_t count; VBDEBUG(("VbGetDevMusicNotes: use_short is %d, hdr is %lx, " "maxsize is %d\n", use_short, hdr, maxsize)); if (use_short) { builtin = short_notes_; count = short_count_; goto nope; } builtin = default_notes_; count = default_count_; /* If we can't beep in the background, don't allow customization. */ if (!audio->background_beep) goto nope; if (!hdr || maxsize < sizeof(VbDevMusic)) goto nope; if (0 != Memcmp(hdr->sig, "$SND", sizeof(hdr->sig))) { VBDEBUG(("VbGetDevMusicNotes: bad sig\n")); goto nope; } /* * How many notes will fit in the flash region? One more than you'd * think, because there's one note in the header itself. */ maxnotes = 1 + (maxsize - sizeof(VbDevMusic)) / sizeof(VbDevMusicNote); if (hdr->count == 0 || hdr->count > maxnotes) { VBDEBUG(("VbGetDevMusicNotes: count=%d maxnotes=%d\n", hdr->count, maxnotes)); goto nope; } /* * CUSTOM_MUSIC_MAXSIZE can't be larger than the size of the flash * (around 8M or so) so this isn't really necessary, but let's be safe * anyway. */ if ((sizeof(VbDevMusicNote) > UINT_MAX / hdr->count) || (sizeof(hdr->count) > UINT_MAX - hdr->count * sizeof(VbDevMusicNote))) { VBDEBUG(("VbGetDevMusicNotes: count=%d, just isn't right\n")); goto nope; } /* Now we know this won't overflow */ mylen = (uint32_t)(sizeof(hdr->count) + hdr->count * sizeof(VbDevMusicNote)); mysum = Crc32(&(hdr->count), mylen); if (mysum != hdr->checksum) { VBDEBUG(("VbGetDevMusicNotes: mysum=%08x, want=%08x\n", mysum, hdr->checksum)); goto nope; } VBDEBUG(("VbGetDevMusicNotes: custom notes struct at %lx\n", hdr)); /* * Measure the audible sound up to the first 22 seconds, being careful * to avoid rollover. The note time is 16 bits, and the note count is * 32 bits. The product should fit in 64 bits. */ total_msecs = 0; on_msecs = 0; for (i=0; i < hdr->count; i++) { this_msecs = hdr->notes[i].msec ; if (this_msecs) { total_msecs += this_msecs; if (total_msecs <= REQUIRED_NOISE_WITHIN && hdr->notes[i].frequency >= 100 && hdr->notes[i].frequency <= 2000) on_msecs += this_msecs; } } /* We require at least one second of noise in the first 22 seconds */ VBDEBUG(("VbGetDevMusicNotes: with %ld msecs of sound to begin\n", on_msecs)); if (on_msecs < REQUIRED_NOISE_TIME) goto nope; /* * We'll also require that the total time be less than a minute. No * real reason, it just gives us less to worry about. */ VBDEBUG(("VbGetDevMusicNotes: lasting %ld msecs\n", total_msecs)); if (total_msecs > MAX_CUSTOM_DELAY) { goto nope; } /* One more check, just to be paranoid. */ if (hdr->count > (UINT_MAX / sizeof(VbDevMusicNote) - 1)) { VBDEBUG(("VbGetDevMusicNotes: they're all out to get me!\n")); goto nope; } /* Looks good. Allocate the space (plus one) and copy it over. */ notebuf = VbExMalloc((hdr->count + 1) * sizeof(VbDevMusicNote)); Memcpy(notebuf, hdr->notes, hdr->count * sizeof(VbDevMusicNote)); count = hdr->count; /* We also require at least 30 seconds of delay. */ if (total_msecs < REQUIRED_TOTAL_DELAY) { /* * If the total time is less than 30 seconds, the needed * difference will fit in 16 bits. */ this_msecs = (REQUIRED_TOTAL_DELAY - total_msecs) & 0xffff; notebuf[hdr->count].msec = this_msecs; notebuf[hdr->count].frequency = 0; count++; VBDEBUG(("VbGetDevMusicNotes: adding %ld msecs of silence\n", this_msecs)); } /* Done */ audio->music_notes = notebuf; audio->note_count = count; audio->free_notes_when_done = 1; return; nope: /* No custom notes, use the default. The count is already set. */ VBDEBUG(("VbGetDevMusicNotes: using %d default notes\n", count)); audio->music_notes = builtin; audio->note_count = count; audio->free_notes_when_done = 0; }
int json_2_message(char * json_str,void ** message) { void * root_node; void * head_node; void * tag_node; void * record_node; void * curr_record; void * expand_node; void * curr_expand; void * record_value; void * expand_value; struct message_box * msg_box; MSG_HEAD * msg_head; MSG_EXPAND * msg_expand; int record_no; int expand_no; void * precord; void * pexpand; int i; int ret; char buffer[DIGEST_SIZE]; int offset; int type; int subtype; offset=json_solve_str(&root_node,json_str); if(offset<0) return offset; // get json node's head head_node=json_find_elem("HEAD",root_node); if(head_node==NULL) head_node=json_find_elem("head",root_node); if(head_node==NULL) return -EINVAL; tag_node=json_find_elem("tag",head_node); if(tag_node!=NULL) // default tag value is "MESG" { ret=json_node_getvalue(tag_node,buffer,10); if(ret!=4) return -EINVAL; if(Memcmp(buffer,"MESG",ret)!=0) return -EINVAL; } msg_box=message_init(); msg_head=message_get_head(msg_box); json_2_struct(head_node,msg_head,msg_box->head_template); // get json node's record // init message box ret=message_record_init(msg_box); if(ret<0) return ret; record_node=json_find_elem("RECORD",root_node); if(record_node==NULL) record_node=json_find_elem("record",root_node); if(record_node==NULL) return -EINVAL; curr_record=json_get_first_child(record_node); if(curr_record==NULL) return -EINVAL; char node_name[DIGEST_SIZE*2]; ret=json_node_getname(curr_record,node_name); if(!strcmp(node_name,"BIN_FORMAT")) { BYTE * radix64_string; radix64_string=malloc(4096); if(radix64_string==NULL) return -ENOMEM; ret=json_node_getvalue(curr_record,radix64_string,4096); if(ret<0) return -EINVAL; int radix64_len=strnlen(radix64_string,4096); msg_head->record_size=radix_to_bin_len(radix64_len); msg_box->blob=malloc(msg_head->record_size); if(msg_box->blob==NULL) return -ENOMEM; ret=radix64_to_bin(msg_box->blob,radix64_len,radix64_string); } else { for(i=0;i<msg_head->record_num;i++) { if(curr_record==NULL) return -EINVAL; ret=Galloc0(&precord,struct_size(msg_box->record_template)); if(ret<=0) return -EINVAL; json_2_struct(curr_record,precord,msg_box->record_template); message_add_record(msg_box,precord); curr_record=json_get_next_child(record_node); } } // get json_node's expand expand_no=msg_head->expand_num; msg_head->expand_num=0; expand_node=json_find_elem("EXPAND",root_node); if(expand_node==NULL) expand_node=json_find_elem("expand",root_node); if(expand_node!=NULL) { char buf[20]; void * curr_expand_template; curr_expand=json_get_first_child(expand_node); for(i=0;i<expand_no;i++) { if(curr_expand==NULL) return -EINVAL; ret=Galloc0(&msg_expand,struct_size(message_get_expand_template())); if(ret<0) return -ENOMEM; ret=json_2_struct(curr_expand,&msg_expand,message_get_expand_template()); if(ret<0) return ret; void * tempnode; if((tempnode=json_find_elem(curr_expand,"BIN_DATA"))==NULL) { curr_expand_template=memdb_get_template(msg_expand->type,msg_expand->subtype); if(curr_expand_template==NULL) return -EINVAL; struct_free(msg_expand,message_get_expand_template()); ret=Galloc(&msg_expand,struct_size(curr_expand_template)); if(ret<0) return -ENOMEM; ret=json_2_struct(curr_expand,msg_expand,curr_expand_template); if(ret<0) return ret; } message_add_expand(msg_box,msg_expand); curr_expand=json_get_next_child(expand_node); } } *message=msg_box; msg_box->box_state = MSG_BOX_RECOVER; return offset; }