Changeset 178 for trunk/lib


Ignore:
Timestamp:
03/13/10 12:56:36 (14 years ago)
Author:
tim
Message:

reworked I/O to use callback functions

fixed a bug in mtime validation and consolidated time formatting code

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/lib/regfi.c

    r173 r178  
    422422
    423423
     424off_t regfi_raw_seek(REGFI_RAW_FILE* self, off_t offset, int whence)
     425{
     426  return lseek(*(int*)self->state, offset, whence);
     427}
     428
     429ssize_t regfi_raw_read(REGFI_RAW_FILE* self, void* buf, size_t count)
     430{
     431  return read(*(int*)self->state, buf, count);
     432}
     433
     434
     435/*****************************************************************************
     436 * Convenience function to wrap up the ugly callback stuff
     437 *****************************************************************************/
     438off_t regfi_seek(REGFI_RAW_FILE* file_cb, off_t offset, int whence)
     439{
     440  return file_cb->seek(file_cb, offset, whence);
     441}
     442
     443
    424444/*****************************************************************************
    425445 * This function is just like read(2), except that it continues to
    426446 * re-try reading from the file descriptor if EINTR or EAGAIN is received. 
    427  * regfi_read will attempt to read length bytes from fd and write them to buf.
     447 * regfi_read will attempt to read length bytes from the file and write them to
     448 * buf.
    428449 *
    429450 * On success, 0 is returned.  Upon failure, an errno code is returned.
     
    433454 * returned as 0, then EOF was encountered immediately
    434455 *****************************************************************************/
    435 uint32_t regfi_read(int fd, uint8_t* buf, uint32_t* length)
     456uint32_t regfi_read(REGFI_RAW_FILE* file_cb, uint8_t* buf, uint32_t* length)
    436457{
    437458  uint32_t rsize = 0;
     
    440461  do
    441462  {
    442     rret = read(fd, buf + rsize, *length - rsize);
     463    rret = file_cb->read(file_cb, buf + rsize, *length - rsize);
    443464    if(rret > 0)
    444465      rsize += rret;
     
    457478 *
    458479 *****************************************************************************/
    459 bool regfi_parse_cell(int fd, uint32_t offset, uint8_t* hdr, uint32_t hdr_len,
    460                       uint32_t* cell_length, bool* unalloc)
     480bool regfi_parse_cell(REGFI_RAW_FILE* file_cb, uint32_t offset, uint8_t* hdr,
     481                      uint32_t hdr_len, uint32_t* cell_length, bool* unalloc)
    461482{
    462483  uint32_t length;
     
    464485  uint8_t tmp[4];
    465486
    466   if(lseek(fd, offset, SEEK_SET) == -1)
     487  if(regfi_seek(file_cb, offset, SEEK_SET) == -1)
    467488    return false;
    468489
    469490  length = 4;
    470   if((regfi_read(fd, tmp, &length) != 0) || length != 4)
     491  if((regfi_read(file_cb, tmp, &length) != 0) || length != 4)
    471492    return false;
    472493  raw_length = IVALS(tmp, 0);
     
    489510  {
    490511    length = hdr_len;
    491     if((regfi_read(fd, hdr, &length) != 0) || length != hdr_len)
     512    if((regfi_read(file_cb, hdr, &length) != 0) || length != hdr_len)
    492513      return false;
    493514  }
     
    634655  bool recursive_type;
    635656
    636   if(!regfi_parse_cell(file->fd, offset, buf, REGFI_SUBKEY_LIST_MIN_LEN,
     657  if(!regfi_parse_cell(file->cb, offset, buf, REGFI_SUBKEY_LIST_MIN_LEN,
    637658                       &cell_length, &unalloc))
    638659  {
     
    704725
    705726  read_len = length;
    706   if(regfi_read(file->fd, elements, &read_len) != 0 || read_len != length)
     727  if(regfi_read(file->cb, elements, &read_len) != 0 || read_len!=length)
    707728    goto fail;
    708729
     
    802823  bool unalloc = false;
    803824
    804   if(!regfi_parse_cell(file->fd, offset, sk_header, REGFI_SK_MIN_LENGTH,
     825  if(!regfi_parse_cell(file->cb, offset, sk_header, REGFI_SK_MIN_LENGTH,
    805826                       &cell_length, &unalloc))
    806827  {
     
    868889
    869890  length = ret_val->desc_size;
    870   if(regfi_read(file->fd, sec_desc_buf, &length) != 0
     891  if(regfi_read(file->cb, sec_desc_buf, &length) != 0
    871892     || length != ret_val->desc_size)
    872893  {
     
    904925  bool unalloc;
    905926
    906   if(!regfi_parse_cell(file->fd, offset, NULL, 0, &cell_length, &unalloc))
     927  if(!regfi_parse_cell(file->cb, offset, NULL, 0, &cell_length, &unalloc))
    907928  {
    908929    regfi_add_message(file, REGFI_MSG_ERROR, "Failed to read cell header"
     
    943964
    944965  length = read_len;
    945   if((regfi_read(file->fd, (uint8_t*)ret_val->elements, &length) != 0)
     966  if((regfi_read(file->cb, (uint8_t*)ret_val->elements, &length) != 0)
    946967     || length != read_len)
    947968  {
     
    12651286  while(cur_offset < hbin_end)
    12661287  {
    1267     if(!regfi_parse_cell(file->fd, cur_offset, NULL, 0, &cell_length, &unalloc))
     1288    if(!regfi_parse_cell(file->cb, cur_offset, NULL, 0, &cell_length, &unalloc))
    12681289    {
    12691290      regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell at offset"
     
    12891310
    12901311
    1291 /******************************************************************************
    1292  ******************************************************************************/
    1293 REGFI_FILE* regfi_open(const char* filename)
    1294 {
    1295   REGFI_FILE* ret_val;
    1296   int fd;
    1297 
    1298   /* open an existing file */
    1299   if ((fd = open(filename, REGFI_OPEN_FLAGS)) == -1)
    1300   {
    1301     /* fprintf(stderr, "regfi_open: failure to open %s (%s)\n", filename, strerror(errno));*/
    1302     return NULL;
    1303   }
    1304 
    1305   ret_val = regfi_alloc(fd);
    1306 
    1307   if(ret_val == NULL)
    1308     close(fd);
    1309 
    1310   return ret_val;
    1311 }
    1312 
    13131312
    13141313/******************************************************************************
     
    13161315REGFI_FILE* regfi_alloc(int fd)
    13171316{
    1318   struct stat sbuf;
     1317  REGFI_FILE* ret_val;
     1318  REGFI_RAW_FILE* file_cb = talloc(NULL, REGFI_RAW_FILE);
     1319  if(file_cb == NULL)
     1320    return NULL;
     1321
     1322  file_cb->state = (void*)talloc(file_cb, int);
     1323  if(file_cb->state == NULL)
     1324    goto fail;
     1325  *(int*)file_cb->state = fd;
     1326 
     1327  file_cb->cur_off = 0;
     1328  file_cb->size = 0;
     1329  file_cb->read = &regfi_raw_read;
     1330  file_cb->seek = &regfi_raw_seek;
     1331 
     1332  ret_val = regfi_alloc_cb(file_cb);
     1333  if(ret_val == NULL)
     1334    goto fail;
     1335
     1336  /* In this case, we want file_cb to be freed when ret_val is */
     1337  talloc_steal(ret_val, file_cb);
     1338  return ret_val;
     1339
     1340 fail:
     1341    talloc_free(file_cb);
     1342    return NULL;
     1343}
     1344
     1345
     1346
     1347REGFI_FILE* regfi_alloc_cb(REGFI_RAW_FILE* file_cb)
     1348{
    13191349  REGFI_FILE* rb;
    13201350  REGFI_HBIN* hbin = NULL;
    1321   uint32_t hbin_off, file_length, cache_secret;
     1351  uint32_t hbin_off, cache_secret;
     1352  int32_t file_length;
    13221353  bool rla;
    13231354
    1324   /* Determine file length.  Must be at least big enough
    1325    * for the header and one hbin.
     1355  /* Determine file length.  Must be at least big enough for the header
     1356   * and one hbin.
    13261357   */
    1327   if (fstat(fd, &sbuf) == -1)
    1328     return NULL;
    1329   file_length = sbuf.st_size;
     1358  file_length = file_cb->seek(file_cb, 0, SEEK_END);
    13301359  if(file_length < REGFI_REGF_SIZE+REGFI_HBIN_ALLOC)
    13311360    return NULL;
     1361  file_cb->seek(file_cb, 0, SEEK_SET);
    13321362
    13331363  /* Read file header */
    1334   if ((rb = regfi_parse_regf(fd, true)) == NULL)
    1335   {
    1336     /* fprintf(stderr, "regfi_alloc: Failed to read initial REGF block\n"); */
     1364  if ((rb = regfi_parse_regf(file_cb, true)) == NULL)
     1365  {
     1366    /* fprintf(stderr, "regfi_alloc_cb: Failed to read initial REGF block\n");*/
    13371367    return NULL;
    13381368  }
    13391369  rb->file_length = file_length; 
     1370  rb->cb = file_cb;
    13401371
    13411372  rb->hbins = range_list_new();
    13421373  if(rb->hbins == NULL)
    13431374  {
    1344     /* fprintf(stderr, "regfi_alloc: Failed to create HBIN list.\n"); */
     1375    /* fprintf(stderr, "regfi_alloc_cb: Failed to create HBIN list.\n"); */
    13451376    talloc_free(rb);
    13461377    return NULL;
     
    13741405  /* success */
    13751406  return rb;
    1376 }
    1377 
    1378 
    1379 /******************************************************************************
    1380  ******************************************************************************/
    1381 int regfi_close(REGFI_FILE* file)
    1382 {
    1383   int fd;
    1384 
    1385   /* nothing to do if there is no open file */
    1386   if ((file == NULL) || (file->fd == -1))
    1387     return 0;
    1388 
    1389   fd = file->fd;
    1390   file->fd = -1;
    1391 
    1392   regfi_free(file);
    1393 
    1394   return close(fd);
    13951407}
    13961408
     
    21832195 * XXX: Add way to return more detailed error information.
    21842196 *******************************************************************/
    2185 REGFI_FILE* regfi_parse_regf(int fd, bool strict)
     2197REGFI_FILE* regfi_parse_regf(REGFI_RAW_FILE* file_cb, bool strict)
    21862198{
    21872199  uint8_t file_header[REGFI_REGF_SIZE];
     
    21932205    return NULL;
    21942206
    2195   ret_val->fd = fd;
    21962207  ret_val->sk_cache = NULL;
    21972208  ret_val->last_message = NULL;
    21982209  ret_val->hbins = NULL;
    2199  
     2210
    22002211  length = REGFI_REGF_SIZE;
    2201   if((regfi_read(fd, file_header, &length)) != 0 || length != REGFI_REGF_SIZE)
     2212  if((regfi_read(file_cb, file_header, &length)) != 0
     2213     || length != REGFI_REGF_SIZE)
    22022214    goto fail;
    22032215 
     
    22172229                      ret_val->magic[2], ret_val->magic[3]);
    22182230  }
     2231
    22192232  ret_val->sequence1 = IVAL(file_header, 0x4);
    22202233  ret_val->sequence2 = IVAL(file_header, 0x8);
     
    22702283    return NULL;
    22712284
    2272   if(lseek(file->fd, offset, SEEK_SET) == -1)
     2285  if(regfi_seek(file->cb, offset, SEEK_SET) == -1)
    22732286  {
    22742287    regfi_add_message(file, REGFI_MSG_ERROR, "Seek failed"
     
    22782291
    22792292  length = REGFI_HBIN_HEADER_SIZE;
    2280   if((regfi_read(file->fd, hbin_header, &length) != 0)
     2293  if((regfi_read(file->cb, hbin_header, &length) != 0)
    22812294     || length != REGFI_HBIN_HEADER_SIZE)
    22822295    return NULL;
    22832296
    2284   if(lseek(file->fd, offset, SEEK_SET) == -1)
     2297  if(regfi_seek(file->cb, offset, SEEK_SET) == -1)
    22852298  {
    22862299    regfi_add_message(file, REGFI_MSG_ERROR, "Seek failed"
     
    23412354  bool unalloc = false;
    23422355
    2343   if(!regfi_parse_cell(file->fd, offset, nk_header, REGFI_NK_MIN_LENGTH,
     2356  if(!regfi_parse_cell(file->cb, offset, nk_header, REGFI_NK_MIN_LENGTH,
    23442357                       &cell_length, &unalloc))
    23452358  {
     
    23992412   */
    24002413  if(unalloc
    2401      && ((ret_val->mtime.high < REGFI_MTIME_MIN_HIGH
    2402           && ret_val->mtime.low < REGFI_MTIME_MIN_LOW)
    2403          || (ret_val->mtime.high > REGFI_MTIME_MAX_HIGH
    2404              && ret_val->mtime.low > REGFI_MTIME_MAX_LOW)))
    2405     return NULL;
     2414     && (ret_val->mtime.high < REGFI_MTIME_MIN_HIGH
     2415         || ret_val->mtime.high > REGFI_MTIME_MAX_HIGH))
     2416  {
     2417    talloc_free(ret_val);
     2418    return NULL;
     2419  }
    24062420
    24072421  ret_val->unknown1 = IVAL(nk_header, 0xC);
     
    24592473  /* Don't need to seek, should be at the right offset */
    24602474  length = ret_val->name_length;
    2461   if((regfi_read(file->fd, (uint8_t*)ret_val->keyname_raw, &length) != 0)
     2475  if((regfi_read(file->cb, (uint8_t*)ret_val->keyname_raw, &length) != 0)
    24622476     || length != ret_val->name_length)
    24632477  {
     
    24832497     && (offset & 0x00000007) == 0)
    24842498  {
    2485     if(!regfi_parse_cell(file->fd, offset, NULL, 0, &cell_length, &unalloc))
     2499    if(!regfi_parse_cell(file->cb, offset, NULL, 0, &cell_length, &unalloc))
    24862500    {
    24872501      regfi_add_message(file, REGFI_MSG_WARN, "Could not parse cell header"
     
    25212535    {
    25222536      length = *name_length;
    2523       if((regfi_read(file->fd, ret_val, &length) != 0)
     2537      if((regfi_read(file->cb, ret_val, &length) != 0)
    25242538         || length != *name_length)
    25252539      {
     
    25462560  bool unalloc = false;
    25472561
    2548   if(!regfi_parse_cell(file->fd, offset, vk_header, REGFI_VK_MIN_LENGTH,
     2562  if(!regfi_parse_cell(file->cb, offset, vk_header, REGFI_VK_MIN_LENGTH,
    25492563                       &cell_length, &unalloc))
    25502564  {
     
    26292643
    26302644    length = ret_val->name_length;
    2631     if((regfi_read(file->fd, (uint8_t*)ret_val->valuename_raw, &length) != 0)
     2645    if((regfi_read(file->cb, (uint8_t*)ret_val->valuename_raw, &length) != 0)
    26322646       || length != ret_val->name_length)
    26332647    {
     
    26972711    }
    26982712   
    2699     if(!regfi_parse_cell(file->fd, offset, NULL, 0,
     2713    if(!regfi_parse_cell(file->cb, offset, NULL, 0,
    27002714                         &cell_length, &unalloc))
    27012715    {
     
    27702784  ret_val.len = 0;
    27712785 
    2772   if(lseek(file->fd, offset+4, SEEK_SET) == -1)
     2786  if(regfi_seek(file->cb, offset+4, SEEK_SET) == -1)
    27732787  {
    27742788    regfi_add_message(file, REGFI_MSG_WARN, "Could not seek while "
     
    27822796 
    27832797  read_length = length;
    2784   if((regfi_read(file->fd, ret_val.buf, &read_length) != 0)
     2798  if((regfi_read(file->cb, ret_val.buf, &read_length) != 0)
    27852799     || read_length != length)
    27862800  {
     
    28482862  }
    28492863
    2850   if(!regfi_parse_cell(file->fd, offset, ret_val.buf, REGFI_BIG_DATA_MIN_LENGTH,
     2864  if(!regfi_parse_cell(file->cb, offset, ret_val.buf, REGFI_BIG_DATA_MIN_LENGTH,
    28512865                       &cell_length, &unalloc))
    28522866  {
     
    29022916    goto fail;
    29032917
    2904   if(!regfi_parse_cell(file->fd, offset, (uint8_t*)ret_val,
     2918  if(!regfi_parse_cell(file->cb, offset, (uint8_t*)ret_val,
    29052919                       num_chunks*sizeof(uint32_t),
    29062920                       &indirect_length, &unalloc))
     
    29572971  {
    29582972    chunk_offset = offsets[i]+REGFI_REGF_SIZE;
    2959     if(!regfi_parse_cell(file->fd, chunk_offset, NULL, 0,
     2973    if(!regfi_parse_cell(file->cb, chunk_offset, NULL, 0,
    29602974                         &cell_length, &unalloc))
    29612975    {
     
    30653079    }
    30663080
    3067     if(lseek(file->fd, cell_info->offset+sizeof(uint32_t), SEEK_SET) == -1)
     3081    if(regfi_seek(file->cb, cell_info->offset+sizeof(uint32_t), SEEK_SET) == -1)
    30683082    {
    30693083      regfi_add_message(file, REGFI_MSG_WARN, "Could not seek to chunk while "
     
    30743088
    30753089    tmp_len = read_length;
    3076     if(regfi_read(file->fd, ret_val.buf+(data_length-data_left),
     3090    if(regfi_read(file->cb, ret_val.buf+(data_length-data_left),
    30773091                  &read_length) != 0 || (read_length != tmp_len))
    30783092    {
     
    31303144    while(curr_off < hbin->block_size)
    31313145    {
    3132       if(!regfi_parse_cell(file->fd, hbin->file_off+curr_off, NULL, 0,
     3146      if(!regfi_parse_cell(file->cb, hbin->file_off+curr_off, NULL, 0,
    31333147                           &cell_len, &is_unalloc))
    31343148        break;
Note: See TracChangeset for help on using the changeset viewer.