Browse code

add support for command MOVE

git-svn: trunk@2193

Tomasz Kojm authored on 2006/08/14 04:43:01
Showing 2 changed files
... ...
@@ -1,3 +1,7 @@
1
+Sun Aug 13 21:41:59 CEST 2006 (tk)
2
+----------------------------------
3
+  * shared/cdiff.c: add support for command MOVE
4
+
1 5
 Sat Aug 12 23:16:05 CEST 2006 (tk)
2 6
 ----------------------------------
3 7
   * sigtool/sigtool.c: build(): redirect stdout and stderr to /dev/null before
... ...
@@ -62,6 +62,7 @@ static int cdiff_cmd_add(const char *cmdstr, struct cdiff_ctx *ctx);
62 62
 static int cdiff_cmd_del(const char *cmdstr, struct cdiff_ctx *ctx);
63 63
 static int cdiff_cmd_xchg(const char *cmdstr, struct cdiff_ctx *ctx);
64 64
 static int cdiff_cmd_close(const char *cmdstr, struct cdiff_ctx *ctx);
65
+static int cdiff_cmd_move(const char *cmdstr, struct cdiff_ctx *ctx);
65 66
 
66 67
 static struct cdiff_cmd commands[] = {
67 68
     /* OPEN db_name */
... ...
@@ -80,7 +81,7 @@ static struct cdiff_cmd commands[] = {
80 80
     { "CLOSE", 0, &cdiff_cmd_close },
81 81
 
82 82
     /* MOVE src_db dst_db start_line first_16b end_line first_16b */
83
-    /* { "MOVE", 6, &cdiff_cmd_move }, */
83
+    { "MOVE", 6, &cdiff_cmd_move },
84 84
 
85 85
     { NULL, 0, NULL }
86 86
 };
... ...
@@ -363,7 +364,7 @@ static int cdiff_cmd_close(const char *cmdstr, struct cdiff_ctx *ctx)
363 363
 	}
364 364
 
365 365
 	if(!(tmpfh = fopen(tmp, "w"))) {
366
-	    logg("!cdiff_cmd_close: Can't open file %s for reading\n", tmp);
366
+	    logg("!cdiff_cmd_close: Can't open file %s for writing\n", tmp);
367 367
 	    fclose(fh);
368 368
 	    free(tmp);
369 369
 	    return -1;
... ...
@@ -469,6 +470,207 @@ static int cdiff_cmd_close(const char *cmdstr, struct cdiff_ctx *ctx)
469 469
     return 0;
470 470
 }
471 471
 
472
+static int cdiff_cmd_move(const char *cmdstr, struct cdiff_ctx *ctx)
473
+{
474
+	unsigned int lines = 0, start_line, end_line;
475
+	char *arg, *srcdb, *dstdb, *tmpdb, line[1024], *start_str, *end_str;
476
+	FILE *src, *dst, *tmp;
477
+
478
+
479
+    if(ctx->open_db) {
480
+	logg("!cdiff_cmd_move: Database %s is still open\n", ctx->open_db);
481
+	return -1;
482
+    }
483
+
484
+    if(!(arg = cdiff_token(cmdstr, 3, 0))) {
485
+	logg("!cdiff_cmd_move: Can't get third argument\n");
486
+	return -1;
487
+    }
488
+    start_line = atoi(arg);
489
+    free(arg);
490
+
491
+    if(!(arg = cdiff_token(cmdstr, 5, 0))) {
492
+	logg("!cdiff_cmd_move: Can't get fifth argument\n");
493
+	return -1;
494
+    }
495
+    end_line = atoi(arg);
496
+    free(arg);
497
+
498
+    if(end_line < start_line) {
499
+	logg("!cdiff_cmd_move: end_line < start_line\n");
500
+	return -1;
501
+    }
502
+
503
+    if(!(start_str = cdiff_token(cmdstr, 4, 0))) {
504
+	logg("!cdiff_cmd_move: Can't get fourth argument\n");
505
+	return -1;
506
+    }
507
+
508
+    if(!(end_str = cdiff_token(cmdstr, 6, 0))) {
509
+	logg("!cdiff_cmd_move: Can't get sixth argument\n");
510
+	free(start_str);
511
+	return -1;
512
+    }
513
+
514
+    if(!(srcdb = cdiff_token(cmdstr, 1, 0))) {
515
+	logg("!cdiff_cmd_move: Can't get first argument\n");
516
+	free(start_str);
517
+	free(end_str);
518
+	return -1;
519
+    }
520
+
521
+    if(!(src = fopen(srcdb, "r"))) {
522
+	logg("!cdiff_cmd_move: Can't open %s for reading\n", srcdb);
523
+	free(start_str);
524
+	free(end_str);
525
+	free(srcdb);
526
+	return -1;
527
+    }
528
+
529
+    if(!(dstdb = cdiff_token(cmdstr, 2, 0))) {
530
+	logg("!cdiff_cmd_move: Can't get second argument\n");
531
+	free(start_str);
532
+	free(end_str);
533
+	free(srcdb);
534
+	fclose(src);
535
+	return -1;
536
+    }
537
+
538
+    if(!(dst = fopen(dstdb, "a"))) {
539
+	logg("!cdiff_cmd_move: Can't open %s for appending\n", dstdb);
540
+	free(start_str);
541
+	free(end_str);
542
+	free(srcdb);
543
+	fclose(src);
544
+	free(dstdb);
545
+	return -1;
546
+    }
547
+
548
+    if(!(tmpdb = cli_gentemp("."))) {
549
+	logg("!cdiff_cmd_move: Can't generate temporary name\n");
550
+	free(start_str);
551
+	free(end_str);
552
+	free(srcdb);
553
+	fclose(src);
554
+	free(dstdb);
555
+	fclose(dst);
556
+	return -1;
557
+    }
558
+
559
+    if(!(tmp = fopen(tmpdb, "w"))) {
560
+	logg("!cdiff_cmd_move: Can't open file %s for writing\n", tmpdb);
561
+	free(start_str);
562
+	free(end_str);
563
+	free(srcdb);
564
+	fclose(src);
565
+	free(dstdb);
566
+	fclose(dst);
567
+	free(tmpdb);
568
+	return -1;
569
+    }
570
+
571
+    while(fgets(line, sizeof(line), src)) {
572
+	lines++;
573
+
574
+	if(lines == start_line) {
575
+	    if(strncmp(line, start_str, strlen(start_str))) {
576
+		free(start_str);
577
+		free(end_str);
578
+		free(srcdb);
579
+		fclose(src);
580
+		free(dstdb);
581
+		fclose(dst);
582
+		fclose(tmp);
583
+		unlink(tmpdb);
584
+		free(tmpdb);
585
+		logg("!cdiff_cmd_close: Can't apply MOVE due to conflict at line %d\n", lines);
586
+		return -1;
587
+	    }
588
+
589
+	    do {
590
+		if(fputs(line, dst) == EOF) {
591
+		    free(start_str);
592
+		    free(end_str);
593
+		    free(srcdb);
594
+		    fclose(src);
595
+		    fclose(dst);
596
+		    fclose(tmp);
597
+		    unlink(tmpdb);
598
+		    free(tmpdb);
599
+		    logg("!cdiff_cmd_move: Can't write to %s\n", dstdb);
600
+		    free(dstdb);
601
+		    return -1;
602
+		}
603
+	    } while((lines < end_line) && fgets(line, sizeof(line), src) && lines++);
604
+
605
+	    fclose(dst);
606
+	    free(dstdb);
607
+	    dstdb = NULL;
608
+	    free(start_str);
609
+
610
+	    if(strncmp(line, end_str, strlen(end_str))) {
611
+		free(end_str);
612
+		free(srcdb);
613
+		fclose(src);
614
+		fclose(tmp);
615
+		unlink(tmpdb);
616
+		free(tmpdb);
617
+		logg("!cdiff_cmd_close: Can't apply MOVE due to conflict at line %d\n", lines);
618
+		return -1;
619
+	    }
620
+
621
+	    free(end_str);
622
+	    continue;
623
+	}
624
+
625
+	if(fputs(line, tmp) == EOF) {
626
+	    free(srcdb);
627
+	    fclose(src);
628
+	    fclose(tmp);
629
+	    unlink(tmpdb);
630
+	    logg("!cdiff_cmd_move: Can't write to %s\n", tmpdb);
631
+	    free(tmpdb);
632
+	    return -1;
633
+	}
634
+    }
635
+
636
+    fclose(src);
637
+    fclose(tmp);
638
+
639
+    if(dstdb) {
640
+	fclose(dst);
641
+	free(start_str);
642
+	free(end_str);
643
+	unlink(tmpdb);
644
+	free(tmpdb);
645
+	logg("!cdiff_cmd_move: No data was moved from %s to %s\n", srcdb, dstdb);
646
+	free(srcdb);
647
+	free(dstdb);
648
+	return -1;
649
+    }
650
+
651
+    if(unlink(srcdb) == -1) {
652
+	logg("!cdiff_cmd_move: Can't unlink %s\n", srcdb);
653
+	free(srcdb);
654
+	unlink(tmpdb);
655
+	free(tmpdb);
656
+	return -1;
657
+    }
658
+
659
+    if(rename(tmpdb, srcdb) == -1) {
660
+	logg("!cdiff_cmd_move: Can't rename %s to %s\n", tmpdb, srcdb);
661
+	free(srcdb);
662
+	unlink(tmpdb);
663
+	free(tmpdb);
664
+	return -1;
665
+    }
666
+
667
+    free(srcdb);
668
+    free(tmpdb);
669
+
670
+    return 0;
671
+}
672
+
472 673
 int cdiff_apply(int fd)
473 674
 {
474 675
 	struct cdiff_ctx ctx;