~ubuntu-branches/ubuntu/feisty/clamav/feisty

« back to all changes in this revision

Viewing changes to shared/cdiff.c

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook
  • Date: 2007-02-20 10:33:44 UTC
  • mto: This revision was merged to the branch mainline in revision 16.
  • Revision ID: james.westby@ubuntu.com-20070220103344-zgcu2psnx9d98fpa
Tags: upstream-0.90
ImportĀ upstreamĀ versionĀ 0.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 *  Copyright (C) 2006 Sensory Networks, Inc.
3
 
 *            (C) 2007 Tomasz Kojm <tkojm@clamav.net>
4
 
 *            Written by Tomasz Kojm
 
2
 *  Copyright (C) 2006 Tomasz Kojm <tkojm@clamav.net>
5
3
 *
6
4
 *  This program is free software; you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License version 2 as
8
 
 *  published by the Free Software Foundation.
 
5
 *  it under the terms of the GNU General Public License as published by
 
6
 *  the Free Software Foundation; either version 2 of the License, or
 
7
 *  (at your option) any later version.
9
8
 *
10
9
 *  This program is distributed in the hope that it will be useful,
11
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
28
27
#include <ctype.h>
29
28
#include <sys/types.h>
30
29
#include <sys/stat.h>
31
 
#ifdef HAVE_UNISTD_H
32
30
#include <unistd.h>
33
 
#endif
34
31
 
 
32
#include "shared/memory.h"
35
33
#include "shared/misc.h"
36
34
#include "shared/output.h"
37
35
#include "shared/cdiff.h"
38
 
#include "libclamav/sha256.h"
39
36
 
40
37
#include "libclamav/str.h"
41
38
#include "libclamav/others.h"
42
39
#include "libclamav/cvd.h"
43
 
#include "libclamav/default.h"
 
40
#include "libclamav/sha256.h"
 
41
 
 
42
#ifdef HAVE_GMP
 
43
#include "libclamav/dsig.h"
 
44
#endif
44
45
 
45
46
#include "zlib.h"
46
47
 
47
 
#include "libclamav/dsig.h"
48
 
 
49
 
#define PSS_NSTR "14783905874077467090262228516557917570254599638376203532031989214105552847269687489771975792123442185817287694951949800908791527542017115600501303394778618535864845235700041590056318230102449612217458549016089313306591388590790796515819654102320725712300822356348724011232654837503241736177907784198700834440681124727060540035754699658105895050096576226753008596881698828185652424901921668758326578462003247906470982092298106789657211905488986281078346361469524484829559560886227198091995498440676639639830463593211386055065360288422394053998134458623712540683294034953818412458362198117811990006021989844180721010947"
50
 
#define PSS_ESTR "100002053"
51
 
#define PSS_NBITS 2048
52
 
#define PSS_DIGEST_LENGTH 32
53
 
 
54
 
/* the line size can be changed from within .cdiff */
55
 
#define CDIFF_LINE_SIZE CLI_DEFAULT_LSIG_BUFSIZE + 32
56
 
 
57
48
struct cdiff_node {
58
49
    unsigned int lineno;
59
50
    char *str, *str2;
64
55
    char *open_db;
65
56
    struct cdiff_node *add_start, *add_last;
66
57
    struct cdiff_node *del_start;
67
 
    struct cdiff_node *xchg_start, *xchg_last;
 
58
    struct cdiff_node *xchg_start;
68
59
};
69
60
 
70
61
struct cdiff_cmd {
71
62
    const char *name;
72
63
    unsigned short argc;
73
 
    int (*handler)(const char *, struct cdiff_ctx *, char *, unsigned int);
 
64
    int (*handler)(const char *, struct cdiff_ctx *);
74
65
};
75
66
 
76
 
static int cdiff_cmd_open(const char *cmdstr, struct cdiff_ctx *ctx, char *lbuf, unsigned int lbuflen);
77
 
static int cdiff_cmd_add(const char *cmdstr, struct cdiff_ctx *ctx, char *lbuf, unsigned int lbuflen);
78
 
static int cdiff_cmd_del(const char *cmdstr, struct cdiff_ctx *ctx, char *lbuf, unsigned int lbuflen);
79
 
static int cdiff_cmd_xchg(const char *cmdstr, struct cdiff_ctx *ctx, char *lbuf, unsigned int lbuflen);
80
 
static int cdiff_cmd_close(const char *cmdstr, struct cdiff_ctx *ctx, char *lbuf, unsigned int lbuflen);
81
 
static int cdiff_cmd_move(const char *cmdstr, struct cdiff_ctx *ctx, char *lbuf, unsigned int lbuflen);
82
 
static int cdiff_cmd_unlink(const char *cmdstr, struct cdiff_ctx *ctx, char *lbuf, unsigned int lbuflen);
 
67
static int cdiff_cmd_open(const char *cmdstr, struct cdiff_ctx *ctx);
 
68
static int cdiff_cmd_add(const char *cmdstr, struct cdiff_ctx *ctx);
 
69
static int cdiff_cmd_del(const char *cmdstr, struct cdiff_ctx *ctx);
 
70
static int cdiff_cmd_xchg(const char *cmdstr, struct cdiff_ctx *ctx);
 
71
static int cdiff_cmd_close(const char *cmdstr, struct cdiff_ctx *ctx);
 
72
static int cdiff_cmd_move(const char *cmdstr, struct cdiff_ctx *ctx);
 
73
static int cdiff_cmd_unlink(const char *cmdstr, struct cdiff_ctx *ctx);
83
74
 
84
75
static struct cdiff_cmd commands[] = {
85
76
    /* OPEN db_name */
163
154
    if(i == j)
164
155
        return NULL;
165
156
 
166
 
    buffer = malloc(j - i + 1);
 
157
    buffer = mmalloc(j - i + 1);
167
158
    if(!buffer)
168
159
        return NULL;
169
160
 
173
164
    return buffer;
174
165
}
175
166
 
176
 
static int cdiff_cmd_open(const char *cmdstr, struct cdiff_ctx *ctx, char *lbuf, unsigned int lbuflen)
 
167
static int cdiff_cmd_open(const char *cmdstr, struct cdiff_ctx *ctx)
177
168
{
178
169
        char *db;
179
170
        unsigned int i;
202
193
    return 0;
203
194
}
204
195
 
205
 
static int cdiff_cmd_add(const char *cmdstr, struct cdiff_ctx *ctx, char *lbuf, unsigned int lbuflen)
 
196
static int cdiff_cmd_add(const char *cmdstr, struct cdiff_ctx *ctx)
206
197
{
207
198
        char *sig;
208
199
        struct cdiff_node *new;
213
204
        return -1;
214
205
    }
215
206
 
216
 
    new = (struct cdiff_node *) calloc(1, sizeof(struct cdiff_node));
 
207
    new = mcalloc(1, sizeof(struct cdiff_node));
217
208
    if(!new) {
218
209
        logg("!cdiff_cmd_add: Can't allocate memory for cdiff_node\n");
219
210
        free(sig);
231
222
    return 0;
232
223
}
233
224
 
234
 
static int cdiff_cmd_del(const char *cmdstr, struct cdiff_ctx *ctx, char *lbuf, unsigned int lbuflen)
 
225
static int cdiff_cmd_del(const char *cmdstr, struct cdiff_ctx *ctx)
235
226
{
236
227
        char *arg;
237
228
        struct cdiff_node *pt, *last, *new;
250
241
        return -1;
251
242
    }
252
243
 
253
 
    new = (struct cdiff_node *) calloc(1, sizeof(struct cdiff_node));
 
244
    new = mcalloc(1, sizeof(struct cdiff_node));
254
245
    if(!new) {
255
246
        logg("!cdiff_cmd_del: Can't allocate memory for cdiff_node\n");
256
247
        free(arg);
288
279
    return 0;
289
280
}
290
281
 
291
 
static int cdiff_cmd_xchg(const char *cmdstr, struct cdiff_ctx *ctx, char *lbuf, unsigned int lbuflen)
 
282
static int cdiff_cmd_xchg(const char *cmdstr, struct cdiff_ctx *ctx)
292
283
{
293
284
        char *arg, *arg2;
294
285
        struct cdiff_node *pt, *last, *new;
313
304
        return -1;
314
305
    }
315
306
 
316
 
    new = (struct cdiff_node *) calloc(1, sizeof(struct cdiff_node));
 
307
    new = mcalloc(1, sizeof(struct cdiff_node));
317
308
    if(!new) {
318
309
        logg("!cdiff_cmd_xchg: Can't allocate memory for cdiff_node\n");
319
310
        free(arg);
324
315
    new->str2 = arg2;
325
316
    new->lineno = lineno;
326
317
 
327
 
    if(!ctx->xchg_start)
 
318
    if(!ctx->xchg_start) {
 
319
 
328
320
        ctx->xchg_start = new;
329
 
    else
330
 
        ctx->xchg_last->next = new;
331
 
 
332
 
    ctx->xchg_last = new;
 
321
 
 
322
    } else { 
 
323
 
 
324
        if(lineno < ctx->xchg_start->lineno) {
 
325
            new->next = ctx->xchg_start;
 
326
            ctx->xchg_start = new;
 
327
 
 
328
        } else {
 
329
            pt = ctx->xchg_start;
 
330
 
 
331
            while(pt) {
 
332
                last = pt;
 
333
                if((pt->lineno < lineno) && (!pt->next || lineno < pt->next->lineno))
 
334
                    break;
 
335
 
 
336
                pt = pt->next;
 
337
            }
 
338
 
 
339
            new->next = last->next;
 
340
            last->next = new;
 
341
        }
 
342
    }
 
343
 
333
344
    return 0;
334
345
}
335
346
 
336
 
static int cdiff_cmd_close(const char *cmdstr, struct cdiff_ctx *ctx, char *lbuf, unsigned int lbuflen)
 
347
static int cdiff_cmd_close(const char *cmdstr, struct cdiff_ctx *ctx)
337
348
{
338
349
        struct cdiff_node *add, *del, *xchg;
339
350
        unsigned int lines = 0;
340
 
        char *tmp;
 
351
        char *tmp, line[1024];
341
352
        FILE *fh, *tmpfh;
342
353
 
343
354
 
352
363
 
353
364
    if(del || xchg) {
354
365
 
355
 
        if(!(fh = fopen(ctx->open_db, "rb"))) {
 
366
        if(!(fh = fopen(ctx->open_db, "r"))) {
356
367
            logg("!cdiff_cmd_close: Can't open file %s for reading\n", ctx->open_db);
357
368
            return -1;
358
369
        }
363
374
            return -1;
364
375
        }
365
376
 
366
 
        if(!(tmpfh = fopen(tmp, "wb"))) {
 
377
        if(!(tmpfh = fopen(tmp, "w"))) {
367
378
            logg("!cdiff_cmd_close: Can't open file %s for writing\n", tmp);
368
379
            fclose(fh);
369
380
            free(tmp);
370
381
            return -1;
371
382
        }
372
383
 
373
 
        while(fgets(lbuf, lbuflen, fh)) {
 
384
        while(fgets(line, sizeof(line), fh)) {
374
385
            lines++;
375
386
 
376
387
            if(del && del->lineno == lines) {
377
 
                if(strncmp(lbuf, del->str, strlen(del->str))) {
 
388
                if(strncmp(line, del->str, strlen(del->str))) {
378
389
                    fclose(fh);
379
390
                    fclose(tmpfh);
380
391
                    unlink(tmp);
382
393
                    logg("!cdiff_cmd_close: Can't apply DEL at line %d of %s\n", lines, ctx->open_db);
383
394
                    return -1;
384
395
                }
 
396
 
385
397
                del = del->next;
386
398
                continue;
387
399
            }
388
400
 
389
401
            if(xchg && xchg->lineno == lines) {
390
 
                if(strncmp(lbuf, xchg->str, strlen(xchg->str))) {
 
402
                if(strncmp(line, xchg->str, strlen(xchg->str))) {
391
403
                    fclose(fh);
392
404
                    fclose(tmpfh);
393
405
                    unlink(tmp);
408
420
                continue;
409
421
            }
410
422
 
411
 
            if(fputs(lbuf, tmpfh) == EOF) {
 
423
            if(fputs(line, tmpfh) == EOF) {
412
424
                fclose(fh);
413
425
                fclose(tmpfh);
414
426
                unlink(tmp);
447
459
 
448
460
    if(add) {
449
461
 
450
 
        if(!(fh = fopen(ctx->open_db, "ab"))) {
 
462
        if(!(fh = fopen(ctx->open_db, "a"))) {
451
463
            logg("!cdiff_cmd_close: Can't open file %s for appending\n", ctx->open_db);
452
464
            return -1;
453
465
        }
469
481
    return 0;
470
482
}
471
483
 
472
 
static int cdiff_cmd_move(const char *cmdstr, struct cdiff_ctx *ctx, char *lbuf, unsigned int lbuflen)
 
484
static int cdiff_cmd_move(const char *cmdstr, struct cdiff_ctx *ctx)
473
485
{
474
486
        unsigned int lines = 0, start_line, end_line;
475
 
        char *arg, *srcdb, *dstdb, *tmpdb, *start_str, *end_str;
 
487
        char *arg, *srcdb, *dstdb, *tmpdb, line[1024], *start_str, *end_str;
476
488
        FILE *src, *dst, *tmp;
477
489
 
478
490
 
518
530
        return -1;
519
531
    }
520
532
 
521
 
    if(!(src = fopen(srcdb, "rb"))) {
 
533
    if(!(src = fopen(srcdb, "r"))) {
522
534
        logg("!cdiff_cmd_move: Can't open %s for reading\n", srcdb);
523
535
        free(start_str);
524
536
        free(end_str);
535
547
        return -1;
536
548
    }
537
549
 
538
 
    if(!(dst = fopen(dstdb, "ab"))) {
 
550
    if(!(dst = fopen(dstdb, "a"))) {
539
551
        logg("!cdiff_cmd_move: Can't open %s for appending\n", dstdb);
540
552
        free(start_str);
541
553
        free(end_str);
556
568
        return -1;
557
569
    }
558
570
 
559
 
    if(!(tmp = fopen(tmpdb, "wb"))) {
 
571
    if(!(tmp = fopen(tmpdb, "w"))) {
560
572
        logg("!cdiff_cmd_move: Can't open file %s for writing\n", tmpdb);
561
573
        free(start_str);
562
574
        free(end_str);
568
580
        return -1;
569
581
    }
570
582
 
571
 
    while(fgets(lbuf, lbuflen, src)) {
 
583
    while(fgets(line, sizeof(line), src)) {
572
584
        lines++;
573
585
 
574
586
        if(lines == start_line) {
575
 
            if(strncmp(lbuf, start_str, strlen(start_str))) {
 
587
            if(strncmp(line, start_str, strlen(start_str))) {
576
588
                free(start_str);
577
589
                free(end_str);
578
590
                free(srcdb);
587
599
            }
588
600
 
589
601
            do {
590
 
                if(fputs(lbuf, dst) == EOF) {
 
602
                if(fputs(line, dst) == EOF) {
591
603
                    free(start_str);
592
604
                    free(end_str);
593
605
                    free(srcdb);
600
612
                    free(dstdb);
601
613
                    return -1;
602
614
                }
603
 
            } while((lines < end_line) && fgets(lbuf, lbuflen, src) && lines++);
 
615
            } while((lines < end_line) && fgets(line, sizeof(line), src) && lines++);
604
616
 
605
617
            fclose(dst);
606
 
            dst = NULL;
607
618
            free(dstdb);
 
619
            dstdb = NULL;
608
620
            free(start_str);
609
621
 
610
 
            if(strncmp(lbuf, end_str, strlen(end_str))) {
 
622
            if(strncmp(line, end_str, strlen(end_str))) {
611
623
                free(end_str);
612
624
                free(srcdb);
613
625
                fclose(src);
622
634
            continue;
623
635
        }
624
636
 
625
 
        if(fputs(lbuf, tmp) == EOF) {
626
 
            if(dst) {
627
 
                fclose(dst);
628
 
                free(dstdb);
629
 
                free(start_str);
630
 
                free(end_str);
631
 
            }
 
637
        if(fputs(line, tmp) == EOF) {
632
638
            free(srcdb);
633
639
            fclose(src);
634
640
            fclose(tmp);
642
648
    fclose(src);
643
649
    fclose(tmp);
644
650
 
645
 
    if(dst) {
 
651
    if(dstdb) {
646
652
        fclose(dst);
647
653
        free(start_str);
648
654
        free(end_str);
676
682
    return 0;
677
683
}
678
684
 
679
 
static int cdiff_cmd_unlink(const char *cmdstr, struct cdiff_ctx *ctx, char *lbuf, unsigned int lbuflen)
 
685
static int cdiff_cmd_unlink(const char *cmdstr, struct cdiff_ctx *ctx)
680
686
{
681
687
        char *db;
682
688
        unsigned int i;
710
716
    return 0;
711
717
}
712
718
 
713
 
static int cdiff_execute(const char *cmdstr, struct cdiff_ctx *ctx, char *lbuf, unsigned int lbuflen)
 
719
static int cdiff_execute(const char *cmdstr, struct cdiff_ctx *ctx)
714
720
{
715
721
        char *cmd_name, *tmp;
716
 
        int (*cmd_handler)(const char *, struct cdiff_ctx *, char *, unsigned int) = NULL;
 
722
        int (*cmd_handler)(const char *, struct cdiff_ctx *) = NULL;
717
723
        unsigned int i;
718
724
 
719
725
 
743
749
    }
744
750
    free(tmp);
745
751
 
746
 
    if(cmd_handler(cmdstr, ctx, lbuf, lbuflen)) {
 
752
    if(cmd_handler(cmdstr, ctx)) {
747
753
        logg("!cdiff_apply: Can't execute command %s\n", cmd_name);
748
754
        free(cmd_name);
749
755
        return -1;
758
764
        struct cdiff_ctx ctx;
759
765
        FILE *fh;
760
766
        gzFile *gzh;
761
 
        char *line, *lbuf, buff[FILEBUFF], *dsig = NULL;
 
767
        char line[1024], buff[FILEBUFF], *dsig = NULL;
762
768
        unsigned int lines = 0, cmds = 0;
763
 
        unsigned int difflen, diffremain, line_size = CDIFF_LINE_SIZE;
 
769
        unsigned int difflen, diffremain;
764
770
        int end, i, n;
765
771
        struct stat sb;
766
772
        int desc;
 
773
#ifdef HAVE_GMP
767
774
        SHA256_CTX sha256ctx;
768
775
        unsigned char digest[32];
769
776
        int sum, bread;
 
777
#endif
770
778
#define DSIGBUFF 350
771
779
 
772
780
    memset(&ctx, 0, sizeof(ctx));
776
784
        return -1;
777
785
    }
778
786
 
779
 
    if(!(line = malloc(line_size))) {
780
 
        logg("!cdiff_apply: Can't allocate memory for 'line'\n");
781
 
        close(desc);
782
 
        return -1;
783
 
    }
784
 
 
785
 
    if(!(lbuf = malloc(line_size))) {
786
 
        logg("!cdiff_apply: Can't allocate memory for 'lbuf'\n");
787
 
        close(desc);
788
 
        free(line);
789
 
        return -1;
790
 
    }
791
 
 
792
787
    if(mode == 1) { /* .cdiff */
793
788
 
794
789
        if(lseek(desc, -DSIGBUFF, SEEK_END) == -1) {
795
790
            logg("!cdiff_apply: lseek(desc, %d, SEEK_END) failed\n", -DSIGBUFF);
796
791
            close(desc);
797
 
            free(line);
798
 
            free(lbuf);
799
792
            return -1;
800
793
        }
801
794
 
802
 
        memset(line, 0, line_size);
 
795
        memset(line, 0, sizeof(line));
803
796
        if(read(desc, line, DSIGBUFF) != DSIGBUFF) {
804
797
            logg("!cdiff_apply: Can't read %d bytes\n", DSIGBUFF);
805
798
            close(desc);
806
 
            free(line);
807
 
            free(lbuf);
808
799
            return -1;
809
800
        }
810
801
 
818
809
        if(!dsig) {
819
810
            logg("!cdiff_apply: No digital signature in cdiff file\n");
820
811
            close(desc);
821
 
            free(line);
822
 
            free(lbuf);
823
812
            return -1;
824
813
        }
825
814
 
826
815
        if(fstat(desc, &sb) == -1) {
827
816
            logg("!cdiff_apply: Can't fstat file\n");
828
817
            close(desc);
829
 
            free(line);
830
 
            free(lbuf);
831
818
            return -1;
832
819
        }
833
820
 
835
822
        if(end < 0) {
836
823
            logg("!cdiff_apply: compressed data end offset < 0\n");
837
824
            close(desc);
838
 
            free(line);
839
 
            free(lbuf);
840
825
            return -1;
841
826
        }
842
827
 
843
828
        if(lseek(desc, 0, SEEK_SET) == -1) {
844
829
            logg("!cdiff_apply: lseek(desc, 0, SEEK_SET) failed\n");
845
830
            close(desc);
846
 
            free(line);
847
 
            free(lbuf);
848
831
            return -1;
849
832
        }
850
833
 
 
834
#ifdef HAVE_GMP
851
835
        sha256_init(&sha256ctx);
852
836
        sum = 0;
853
837
        while((bread = read(desc, buff, FILEBUFF)) > 0) {
859
843
            }
860
844
            sum += bread;
861
845
        }
862
 
        sha256_final(&sha256ctx, digest);
 
846
        sha256_final(&sha256ctx);
 
847
        sha256_digest(&sha256ctx, digest);
863
848
 
864
 
        if(cli_versig2(digest, dsig, PSS_NSTR, PSS_ESTR) != CL_SUCCESS) {
 
849
        if(cli_versigpss(digest, dsig)) {
865
850
            logg("!cdiff_apply: Incorrect digital signature\n");
866
851
            close(desc);
867
 
            free(line);
868
 
            free(lbuf);
869
852
            return -1;
870
853
        }
 
854
#endif
871
855
 
872
856
        if(lseek(desc, 0, SEEK_SET) == -1) {
873
857
            logg("!cdiff_apply: lseek(desc, 0, SEEK_SET) failed\n");
874
858
            close(desc);
875
 
            free(line);
876
 
            free(lbuf);
877
859
            return -1;
878
860
        }
879
861
 
889
871
        if(sscanf(buff, "ClamAV-Diff:%*u:%u:", &difflen) != 1) {
890
872
            logg("!cdiff_apply: Incorrect file format\n");
891
873
            close(desc);
892
 
            free(line);
893
 
            free(lbuf);
894
874
            return -1;
895
875
        }
896
876
 
897
877
        if(!(gzh = gzdopen(desc, "rb"))) {
898
878
            logg("!cdiff_apply: Can't gzdopen descriptor %d\n", desc);
899
879
            close(desc);
900
 
            free(line);
901
 
            free(lbuf);
902
880
            return -1;
903
881
        }
904
882
 
905
883
        diffremain = difflen;
906
884
        while(diffremain) {
907
 
            unsigned int bufsize = diffremain < line_size ? diffremain + 1 : line_size;
 
885
            unsigned int bufsize = diffremain < sizeof(line) ? diffremain + 1 : sizeof(line);
908
886
 
909
887
            if(!gzgets(gzh, line, bufsize)) {
910
888
                logg("!cdiff_apply: Premature EOF at line %d\n", lines + 1);
911
889
                cdiff_ctx_free(&ctx);
912
890
                gzclose(gzh);
913
 
                free(line);
914
 
                free(lbuf);
915
891
                return -1;
916
892
            }
917
893
            diffremain -= strlen(line);
918
894
            lines++;
919
895
            cli_chomp(line);
920
896
 
921
 
            if(!strlen(line))
922
 
                continue;
923
 
            if(line[0] == '#') {
924
 
                if(!strncmp(line, "#LSIZE", 6) && sscanf(line, "#LSIZE %u", &line_size) == 1) {
925
 
                        char *r1, *r2;
926
 
                    if(line_size < CDIFF_LINE_SIZE || line_size > 10485760) {
927
 
                        logg("^cdiff_apply: Ignoring new buffer size request - invalid size %d\n", line_size);
928
 
                        line_size = CDIFF_LINE_SIZE;
929
 
                        continue;
930
 
                    }
931
 
                    r1 = realloc(line, line_size);
932
 
                    r2 = realloc(lbuf, line_size);
933
 
                    if(!r1 || !r2) {
934
 
                        logg("!cdiff_apply: Can't resize line buffer to %d bytes\n", line_size);
935
 
                        cdiff_ctx_free(&ctx);
936
 
                        gzclose(gzh);
937
 
                        if(!r1 && !r2) {
938
 
                            free(line);
939
 
                            free(lbuf);
940
 
                        } else if(!r1) {
941
 
                            free(line);
942
 
                            free(r2);
943
 
                        } else {
944
 
                            free(r1);
945
 
                            free(lbuf);
946
 
                        }
947
 
                        return -1;
948
 
                    }
949
 
                    line = r1;
950
 
                    lbuf = r2;
951
 
                }
952
 
                continue;
953
 
            }
 
897
            if(line[0] == '#' || !strlen(line))
 
898
                continue;
954
899
 
955
 
            if(cdiff_execute(line, &ctx, lbuf, line_size) == -1) {
 
900
            if(cdiff_execute(line, &ctx) == -1) {
956
901
                logg("!cdiff_apply: Error executing command at line %d\n", lines);
957
902
                cdiff_ctx_free(&ctx);
958
903
                gzclose(gzh);
959
 
                free(line);
960
 
                free(lbuf);
961
904
                return -1;
962
905
            } else {
963
906
                cmds++;
967
910
 
968
911
    } else { /* .script */
969
912
 
970
 
        if(!(fh = fdopen(desc, "rb"))) {
 
913
        if(!(fh = fdopen(desc, "r"))) {
971
914
            logg("!cdiff_apply: fdopen() failed for descriptor %d\n", desc);
972
915
            close(desc);
973
 
            free(line);
974
 
            free(lbuf);
975
916
            return -1;
976
917
        }
977
918
 
978
 
        while(fgets(line, line_size, fh)) {
 
919
        while(fgets(line, sizeof(line), fh)) {
979
920
            lines++;
980
921
            cli_chomp(line);
981
922
 
982
 
            if(!strlen(line))
983
 
                continue;
984
 
            if(line[0] == '#') {
985
 
                if(!strncmp(line, "#LSIZE", 6) && sscanf(line, "#LSIZE %u", &line_size) == 1) {
986
 
                        char *r1, *r2;
987
 
                    if(line_size < CDIFF_LINE_SIZE || line_size > 10485760) {
988
 
                        logg("^cdiff_apply: Ignoring new buffer size request - invalid size %d\n", line_size);
989
 
                        line_size = CDIFF_LINE_SIZE;
990
 
                        continue;
991
 
                    }
992
 
                    r1 = realloc(line, line_size);
993
 
                    r2 = realloc(lbuf, line_size);
994
 
                    if(!r1 || !r2) {
995
 
                        logg("!cdiff_apply: Can't resize line buffer to %d bytes\n", line_size);
996
 
                        cdiff_ctx_free(&ctx);
997
 
                        fclose(fh);
998
 
                        if(!r1 && !r2) {
999
 
                            free(line);
1000
 
                            free(lbuf);
1001
 
                        } else if(!r1) {
1002
 
                            free(line);
1003
 
                            free(r2);
1004
 
                        } else {
1005
 
                            free(r1);
1006
 
                            free(lbuf);
1007
 
                        }
1008
 
                        return -1;
1009
 
                    }
1010
 
                    line = r1;
1011
 
                    lbuf = r2;
1012
 
                }
1013
 
                continue;
1014
 
            }
 
923
            if(line[0] == '#' || !strlen(line))
 
924
                continue;
1015
925
 
1016
 
            if(cdiff_execute(line, &ctx, lbuf, line_size) == -1) {
 
926
            if(cdiff_execute(line, &ctx) == -1) {
1017
927
                logg("!cdiff_apply: Error executing command at line %d\n", lines);
1018
928
                cdiff_ctx_free(&ctx);
1019
929
                fclose(fh);
1020
 
                free(line);
1021
 
                free(lbuf);
1022
930
                return -1;
1023
931
            } else {
1024
932
                cmds++;
1028
936
        fclose(fh);
1029
937
    }
1030
938
 
1031
 
    free(line);
1032
 
    free(lbuf);
1033
 
 
1034
939
    if(ctx.open_db) {
1035
940
        logg("*cdiff_apply: File %s was not properly closed\n", ctx.open_db);
1036
941
        cdiff_ctx_free(&ctx);