185
static int cli_tgzload(int fd, struct cl_engine *engine, unsigned int *signo, unsigned int options)
183
static int cli_tgzload(int fd, struct cl_engine *engine, unsigned int *signo, unsigned int options, struct cli_dbio *dbio, struct cli_dbinfo *dbinfo)
187
185
char osize[13], name[101];
188
186
char block[TAR_BLOCKSIZE];
189
187
int nread, fdd, ret;
190
188
unsigned int type, size, pad, compr = 1;
192
struct cli_dbio dbio;
190
struct cli_dbinfo *db;
191
unsigned char hash[32];
194
193
#define CLOSE_DBIO \
195
gzclose(dbio->gzs); \
200
199
cli_dbgmsg("in cli_tgzload()\n");
217
if((dbio.gzs = gzdopen(fdd, "rb")) == NULL) {
216
if((dbio->gzs = gzdopen(fdd, "rb")) == NULL) {
218
217
cli_errmsg("cli_tgzload: Can't gzdopen() descriptor %d, errno = %d\n", fdd, errno);
223
if((dbio.fs = fdopen(fdd, "rb")) == NULL) {
222
if((dbio->fs = fdopen(fdd, "rb")) == NULL) {
224
223
cli_errmsg("cli_tgzload: Can't fdopen() descriptor %d, errno = %d\n", fdd, errno);
229
dbio->bufsize = CLI_DEFAULT_DBIO_BUFSIZE;
230
dbio->buf = cli_malloc(dbio->bufsize);
232
cli_errmsg("cli_tgzload: Can't allocate memory for dbio->buf\n");
238
dbio->readpt = dbio->buf;
233
nread = gzread(dbio.gzs, block, TAR_BLOCKSIZE);
243
nread = gzread(dbio->gzs, block, TAR_BLOCKSIZE);
235
nread = fread(block, 1, TAR_BLOCKSIZE, dbio.fs);
245
nread = fread(block, 1, TAR_BLOCKSIZE, dbio->fs);
240
250
if(nread != TAR_BLOCKSIZE) {
241
251
cli_errmsg("cli_tgzload: Incomplete block read\n");
243
254
return CL_EMALFDB;
277
291
if((sscanf(osize, "%o", &size)) == 0) {
278
292
cli_errmsg("cli_tgzload: Invalid size in header\n");
280
295
return CL_EMALFDB;
298
dbio->readsize = dbio->size < dbio->bufsize ? dbio->size : dbio->bufsize - 1;
300
dbio->readpt = dbio->buf;
301
sha256_init(&dbio->sha256ctx);
284
304
/* cli_dbgmsg("cli_tgzload: Loading %s, size: %u\n", name, size); */
286
off = (off_t) gzseek(dbio.gzs, 0, SEEK_CUR);
306
off = (off_t) gzseek(dbio->gzs, 0, SEEK_CUR);
288
off = ftell(dbio.fs);
308
off = ftell(dbio->fs);
290
if(CLI_DBEXT(name)) {
291
ret = cli_load(name, engine, signo, options, &dbio);
310
if((!dbinfo && cli_strbcasestr(name, ".info")) || (dbinfo && CLI_DBEXT(name))) {
311
ret = cli_load(name, engine, signo, options, dbio);
293
313
cli_errmsg("cli_tgzload: Can't load %s\n", name);
295
316
return CL_EMALFDB;
324
while(db && strcmp(db->name, name))
327
cli_errmsg("cli_tgzload: File %s not found in .info\n", name);
333
if(db->size != dbio->bread) {
334
cli_errmsg("cli_tgzload: File %s not correctly loaded\n", name);
339
sha256_final(&dbio->sha256ctx, hash);
340
if(memcmp(db->hash, hash, 32)) {
341
cli_errmsg("cli_tgzload: Invalid checksum for file %s\n", name);
298
349
pad = size % TAR_BLOCKSIZE ? (TAR_BLOCKSIZE - (size % TAR_BLOCKSIZE)) : 0;
300
if(off == gzseek(dbio.gzs, 0, SEEK_CUR))
301
gzseek(dbio.gzs, size + pad, SEEK_CUR);
351
if(off == gzseek(dbio->gzs, 0, SEEK_CUR))
352
gzseek(dbio->gzs, size + pad, SEEK_CUR);
303
gzseek(dbio.gzs, pad, SEEK_CUR);
354
gzseek(dbio->gzs, pad, SEEK_CUR);
305
if(off == ftell(dbio.fs))
306
fseek(dbio.fs, size + pad, SEEK_CUR);
356
if(off == ftell(dbio->fs))
357
fseek(dbio->fs, size + pad, SEEK_CUR);
308
fseek(dbio.fs, pad, SEEK_CUR);
359
fseek(dbio->fs, pad, SEEK_CUR);
313
365
return CL_SUCCESS;
505
int cli_cvdload(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int daily, unsigned int options, unsigned int cld)
557
int cli_cvdload(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int options, unsigned int cld, const char *dbname)
508
559
struct cl_cvd cvd;
563
struct cli_dbio dbio;
564
struct cli_dbinfo *dbinfo = NULL;
513
566
cli_dbgmsg("in cli_cvdload()\n");
517
569
if((ret = cli_cvdverify(fs, &cvd, cld)))
520
if(cvd.stime && daily) {
572
if(strstr(dbname, "daily.")) {
522
574
if(cvd.stime > s_time) {
523
575
if(cvd.stime - (unsigned int ) s_time > 3600) {
544
598
cfd = fileno(fs);
545
/* use only operations on file descriptors, and not on the FILE* from here on
546
* if we seek the FILE*, the underlying descriptor may not seek as expected
547
* (for example on OpenBSD, cygwin, etc.).
548
* So seek the descriptor directly.
550
if(lseek(cfd, 512, SEEK_SET) == -1) {
551
cli_errmsg("cli_cvdload(): lseek(fs, 512, SEEK_SET) failed\n");
556
engine->dbversion[0] = cvd.version;
557
engine->dbversion[1] = cvd.stime;
560
if(options & CL_DB_CVDNOTMP) {
562
return cli_tgzload(cfd, engine, signo, options | CL_DB_OFFICIAL);
566
if(!(dir = cli_gentemp(engine->tmpdir)))
569
if(mkdir(dir, 0700)) {
570
cli_errmsg("cli_cvdload(): Can't create temporary directory %s\n", dir);
575
if(cli_untgz(cfd, dir)) {
576
cli_errmsg("cli_cvdload(): Can't unpack CVD file.\n");
581
/* load extracted directory */
582
ret = cl_load(dir, engine, signo, options | CL_DB_OFFICIAL);
599
ret = cli_tgzload(cfd, engine, signo, options | CL_DB_OFFICIAL, &dbio, NULL);
600
if(ret != CL_SUCCESS)
603
dbinfo = engine->dbinfo;
604
if(!dbinfo || !dbinfo->cvd || (dbinfo->cvd->version != cvd.version) || (dbinfo->cvd->sigs != cvd.sigs) || (dbinfo->cvd->fl != cvd.fl) || (dbinfo->cvd->stime != cvd.stime)) {
605
cli_errmsg("cli_cvdload: Corrupted CVD header\n");
608
dbinfo = engine->dbinfo ? engine->dbinfo->next : NULL;
612
options |= CL_DB_SIGNED;
613
ret = cli_tgzload(cfd, engine, signo, options | CL_DB_OFFICIAL, &dbio, dbinfo);
615
while(engine->dbinfo) {
616
dbinfo = engine->dbinfo;
617
engine->dbinfo = dbinfo->next;
618
mpool_free(engine->mempool, dbinfo->name);
619
mpool_free(engine->mempool, dbinfo->hash);
621
cl_cvdfree(dbinfo->cvd);
622
mpool_free(engine->mempool, dbinfo);
591
628
int cli_cvdunpack(const char *file, const char *dir)