static uint64_t parseVersion1( tr_torrent * tor, const uint8_t * buf, const uint8_t * end, uint64_t fieldsToLoad ) { uint64_t ret = 0; while( end - buf >= 5 ) { uint8_t id; uint32_t len; readBytes( &id, &buf, sizeof( id ) ); readBytes( &len, &buf, sizeof( len ) ); if( buf + len > end ) { tr_torerr( tor, "Resume file seems to be corrupt. Skipping." ); } else if( fieldsToLoad & internalIdToPublicBitfield( id ) ) switch( id ) { case FR_ID_DOWNLOADED: ret |= parseDownloaded( tor, buf, len ); break; case FR_ID_UPLOADED: ret |= parseUploaded( tor, buf, len ); break; case FR_ID_PROGRESS: ret |= parseProgress( tor, buf, len ); break; case FR_ID_PRIORITY: ret |= parsePriorities( tor, buf, len ); break; case FR_ID_SPEED: ret |= parseSpeedLimit( tor, buf, len ); break; case FR_ID_RUN: ret |= parseRun( tor, buf, len ); break; case FR_ID_CORRUPT: ret |= parseCorrupt( tor, buf, len ); break; case FR_ID_PEERS: ret |= parsePeers( tor, buf, len ); break; case FR_ID_MAX_PEERS: ret |= parseConnections( tor, buf, len ); break; case FR_ID_DOWNLOAD_DIR: ret |= parseDownloadDir( tor, buf, len ); break; default: tr_tordbg( tor, "Skipping unknown resume code %d", (int)id ); break; } buf += len; } return ret; }
int rdbParse(char *rdbFile, keyValueHandler handler) { int type, loops = 0, dbid, valType; unsigned int rlen; char buf[1024]; time_t expiretime = -1; FILE *fp; sds key, sval; /* sval is simple string value.*/ sds *cval; /*complicatae value*/ /* Double constants initialization */ R_Zero = 0.0; R_PosInf = 1.0/R_Zero; R_NegInf = -1.0/R_Zero; R_Nan = R_Zero/R_Zero; if((fp = fopen(rdbFile, "r")) == NULL) { return PARSE_ERR; } if (freadCheck(buf, 9, 1, fp) == 0) { fclose(fp); fprintf(stderr, "fread err :%s\n", strerror(errno)); return PARSE_ERR; } buf[9] = '\0'; if (memcmp(buf, "REDIS", 5) != 0) { fclose(fp); fprintf(stderr, "Wrong signature trying to load DB from file\n"); return PARSE_ERR; } rdb_version = atoi(buf+5); if (rdb_version > 6) { fclose(fp); fprintf(stderr, "Can't handle RDB format version %d\n", rdb_version); return PARSE_ERR; } startParse(fp); while(1) { if(!(loops++ % 1000)) { /* record parse progress every 1000 loops. */ parseProgress(ftello(fp)); } if((type = rdbLoadType(fp)) == -1) return PARSE_ERR; if(type == REDIS_EXPIRETIME) { if ((expiretime = rdbLoadTime(fp)) == -1) return PARSE_ERR; if((type = rdbLoadType(fp)) == -1) return PARSE_ERR; } /* file end. */ if(type == REDIS_EOF) { break; } /* select db */ if(type == REDIS_SELECTDB) { dbid = rdbLoadLen(fp,NULL); continue; } /* load key. */ if ((key = rdbLoadStringObject(fp)) == NULL) { return PARSE_ERR; } if(type == REDIS_HASH_ZIPMAP) { valType = REDIS_HASH; } else if(type == REDIS_LIST_ZIPLIST) { valType = REDIS_LIST; } else if(type == REDIS_SET_INTSET) { valType = REDIS_SET; } else if(type == REDIS_ZSET_ZIPLIST) { valType = REDIS_ZSET; } else { valType = type; } /* load value. */ if(type == REDIS_STRING) { sval = rdbLoadValueObject(fp, type, &rlen); handler(valType, key, sval, rlen, expiretime); } else { cval = rdbLoadValueObject(fp, type, &rlen); handler(valType, key, cval, rlen, expiretime); } /* clean*/ sdsfree(key); if(valType == REDIS_STRING) { sdsfree(sval); } else { unsigned int k; for(k = 0; k < rlen; k++) { sdsfree(cval[k]); } zfree(cval); } } /* checksum */ uint64_t checksum = 0; int ret; ret = fread(&checksum, sizeof(checksum), 1, fp); if (ret == 1) { if ((long long)checksum != digest) { fprintf(stderr, "DB load failed, checksum does not match: %016llx != %016llx\n", (long long)checksum, digest); exit(1); } fprintf(stderr, "DB loaded, checksum: %016llx\n", digest); } parser_stats.stop_time = time(NULL); fclose(fp); return PARSE_OK; }