/*---------------------------------------------------------------------------*/ static int32_t find_file(const char *name) { struct file_header hdr; int32_t page; page = dir_cache_find(name); if(page >= 0) { return page; } page = 0; do { READ_HEADER(&hdr, page); if(COFFEE_PAGE_ACTIVE(hdr)) { if(strcmp(name, hdr.name) == 0) { dir_cache_add(name[0], page); return page; } page += hdr.max_pages; } else if(COFFEE_PAGE_ISOLATED(hdr)) { ++page; } else if(COFFEE_PAGE_OBSOLETE(hdr)) { page += hdr.max_pages; } else { /* It follows from the properties of the page allocation algorithm that if a free page is encountered, then the rest of the sector is also free. */ page = (page + COFFEE_PAGES_PER_SECTOR) & ~(COFFEE_PAGES_PER_SECTOR - 1); } watchdog_periodic(); } while(page < COFFEE_PAGE_COUNT); return -1; }
/*---------------------------------------------------------------------------*/ static int find_contiguous_pages(unsigned wanted) { int page, start; struct file_header hdr; start = -1; for(page = 0; page < COFFEE_PAGE_COUNT;) { READ_HEADER(&hdr, page); if(COFFEE_PAGE_FREE(hdr)) { if(start == -1) { start = page; } else { if(start + wanted <= page) { return start; } } /* Jump to the next sector. */ page = (page + COFFEE_PAGES_PER_SECTOR) & ~(COFFEE_PAGES_PER_SECTOR - 1); } else if(COFFEE_PAGE_ISOLATED(hdr)) { ++page; } else { start = -1; page += hdr.max_pages; } } return -1; }
/*! ****************************************************************************** @Function PVRSRVTimeTraceItemSize @Description Calculate the size of a trace item @Input psTraceItem : Trace item @Return size of trace item ******************************************************************************/ static IMG_UINT32 PVRSRVTimeTraceItemSize(IMG_UINT32 *psTraceItem) { IMG_UINT32 ui32Size = PVRSRV_TRACE_ITEM_SIZE; ui32Size += READ_HEADER(SIZE, psTraceItem[PVRSRV_TRACE_DATA_HEADER]); return ui32Size; }
int print_trx(const char* filename){ u_int8_t buf[TRX_HEADER_SIZE]; int fd = open(filename,O_RDONLY); if(fd < 0){ perror("can't open file:"); return -1; } int size; struct trx_header header; READ_HEADER(header.magic); READ_HEADER(header.file_length); READ_HEADER(header.crc32); READ_HEADER(header.flags); READ_HEADER(header.version); for (int i = 0; i < NUM_OFFSETS; i++){ READ_HEADER(header.offsets[i]); } printf("magic = 0x%04x\n",header.magic); printf("length = %d\n", header.file_length); printf("crc32 = %u\n", header.crc32); printf("~crc32 = %u\n", ~header.crc32); printf("flags = 0x%04x\n", header.flags); printf("version = %d\n", header.version); for (int i = 0; i < NUM_OFFSETS; i++){ printf("offset[%d] = %d\n", i, header.offsets[i]); } close(fd); return 0; }
/*---------------------------------------------------------------------------*/ static int32_t find_offset_in_file(int first_page) { struct file_header hdr; unsigned char buf[COFFEE_PAGE_SIZE]; int page; int i; int search_limit; uint32_t range_start, range_end, part_size; READ_HEADER(&hdr, first_page); for(search_limit = i = 0; i < sizeof(hdr.eof_hint) * CHAR_BIT; i++) { if(hdr.eof_hint >> i) { search_limit = i + 1; } } part_size = hdr.max_pages / sizeof(hdr.eof_hint) / CHAR_BIT; if(part_size == 0) { part_size = 1; } range_start = part_size * search_limit; range_end = range_start + part_size; if(range_end > hdr.max_pages) { range_end = hdr.max_pages; } /* * Move from the end of the range towards the beginning and look for * a byte that has been modified. * * An important implication of this is that if the last written bytes * are zeroes, then these are skipped from the calculation. */ for(page = first_page + range_end; page >= first_page + range_start; page--) { watchdog_periodic(); COFFEE_READ(buf, sizeof(buf), page * COFFEE_PAGE_SIZE); for(i = COFFEE_PAGE_SIZE - 1; i >= 0; i--) { if(buf[i] != 0) { if(page == first_page) { return i < sizeof(hdr) ? 0 : 1 + i - sizeof(hdr); } else { return 1 + i + (page - first_page) * COFFEE_PAGE_SIZE - sizeof(hdr); } } } } /* All bytes are writable. */ return 0; }
/*---------------------------------------------------------------------------*/ static int remove_by_page(uint16_t page, int remove_log, int close_fds) { struct file_header hdr; int i; uint16_t log_page; if(page >= COFFEE_PAGE_COUNT) { return -1; } READ_HEADER(&hdr, page); if(!COFFEE_PAGE_ACTIVE(hdr)) { return -1; } dir_cache_del(page); hdr.flags |= COFFEE_FLAG_OBSOLETE; WRITE_HEADER(&hdr, page); if(remove_log && COFFEE_PAGE_MODIFIED(hdr)) { log_page = hdr.log_page; dir_cache_del(log_page); READ_HEADER(&hdr, log_page); hdr.flags |= COFFEE_FLAG_OBSOLETE; WRITE_HEADER(&hdr, log_page); } /* Close all file descriptors that reference the remove file. */ if(close_fds) { for(i = 0; i < COFFEE_FD_SET_SIZE; i++) { if(coffee_fd_set[i].file_page == page) { coffee_fd_set[i].flags = COFFEE_FD_FREE; } } } return 0; }
/*---------------------------------------------------------------------------*/ static int32_t dir_cache_find(const char *name) { int i; struct file_header hdr; for(i = 0; i < COFFEE_DIR_CACHE_ENTRIES; i++) { if(*name == dir_cache[i].filename_start) { READ_HEADER(&hdr, dir_cache[i].page); if(!COFFEE_PAGE_ACTIVE(hdr)) { dir_cache[i].filename_start = '\0'; } else if(strcmp(hdr.name, name) == 0) { return dir_cache[i].page; } } } return -1; }
/*----------------------------------------------------------------------+*/ protocol_request_ptr SPC_Read_Protocol(SPC_Connection_Ptr connection) /*----------------------------------------------------------------------+*/ { int channel_id; protocol_request_ptr prot; buffered_data_ptr dptr; int len; if(!connection->connected) return(SPC_ERROR); if((prot=SPC_New_Protocol_Ptr(NULL, 0, 0))==SPC_ERROR) { SPC_Close_Connection(connection); return(SPC_ERROR); } /* read header */ dptr=prot->dataptr; len=SPC_Read_Chars(connection, REQUEST_HEADER_LENGTH, dptr->data); if(len != REQUEST_HEADER_LENGTH) { SPC_Close_Connection(connection); SPC_Free_Protocol_Ptr(prot); return(SPC_ERROR); } /* we have the header. Parse out the fields */ READ_HEADER(dptr, &channel_id, &prot->request_type, &dptr->len, &prot->seqno); prot->channel=SPC_Lookup_Channel(channel_id, connection); /* JET - 11/12/2001 - correct an exploitable buffer overrun where the user */ /* can supply a data len that is larger than the available buffer */ /* MAXREQLEN */ /* CERT - VU#172583 */ if (dptr->len >= MAXREQLEN) { /* we have a problem. Initiate DefCon 1 */ /* and launch our missiles. */ XeString connection_hostname = CONNECTION_HOSTNAME(connection); SPC_Error(SPC_Buffer_Overflow, connection_hostname); XeFree(connection_hostname); SPC_Close_Connection(connection); SPC_Free_Protocol_Ptr(prot); return(SPC_ERROR); } /* read header */ len=SPC_Read_Chars(connection, dptr->len, dptr->data+REQUEST_HEADER_LENGTH); if(len != dptr->len) { SPC_Close_Connection(connection); SPC_Free_Protocol_Ptr(prot); return(SPC_ERROR); } dptr->offset=REQUEST_HEADER_LENGTH; return(prot); }