Fossil SCM
More sync fixes: The previous version was not pulling new branches off of the server. This should fix that.
Commit
50150adeecefe2019e9a8ef00b136245ac22c4b7
Parent
edbb332d548cc19…
1 file changed
+64
-30
+64
-30
| --- src/xfer.c | ||
| +++ src/xfer.c | ||
| @@ -191,11 +191,11 @@ | ||
| 191 | 191 | */ |
| 192 | 192 | static void send_file(Xfer *pXfer, int rid, Blob *pUuid, int srcId){ |
| 193 | 193 | Blob content, uuid; |
| 194 | 194 | int size = 0; |
| 195 | 195 | |
| 196 | - if( db_exists("SELECT 1 FROM sent WHERE rid=%d", rid) ){ | |
| 196 | + if( db_exists("SELECT 1 FROM onremote WHERE rid=%d", rid) ){ | |
| 197 | 197 | return; |
| 198 | 198 | } |
| 199 | 199 | blob_zero(&uuid); |
| 200 | 200 | if( pUuid==0 ){ |
| 201 | 201 | db_blob(&uuid, "SELECT uuid FROM blob WHERE rid=%d AND size>=0", rid); |
| @@ -221,11 +221,11 @@ | ||
| 221 | 221 | blob_append(pXfer->pOut, blob_buffer(&content), size); |
| 222 | 222 | pXfer->nFileSent++; |
| 223 | 223 | }else{ |
| 224 | 224 | pXfer->nDeltaSent++; |
| 225 | 225 | } |
| 226 | - db_multi_exec("INSERT INTO sent VALUES(%d)", rid); | |
| 226 | + db_multi_exec("INSERT INTO onremote VALUES(%d)", rid); | |
| 227 | 227 | blob_reset(&uuid); |
| 228 | 228 | } |
| 229 | 229 | |
| 230 | 230 | /* |
| 231 | 231 | ** This routine runs when either client or server is notified that |
| @@ -379,11 +379,11 @@ | ||
| 379 | 379 | xfer.pOut = cgi_output_blob(); |
| 380 | 380 | xfer.mxSend = db_get_int("max-download", 1000000); |
| 381 | 381 | |
| 382 | 382 | db_begin_transaction(); |
| 383 | 383 | db_multi_exec( |
| 384 | - "CREATE TEMP TABLE sent(rid INTEGER PRIMARY KEY);" | |
| 384 | + "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);" | |
| 385 | 385 | ); |
| 386 | 386 | while( blob_line(xfer.pIn, &xfer.line) ){ |
| 387 | 387 | xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken)); |
| 388 | 388 | |
| 389 | 389 | /* file UUID SIZE \n CONTENT |
| @@ -390,11 +390,11 @@ | ||
| 390 | 390 | ** file UUID DELTASRC SIZE \n CONTENT |
| 391 | 391 | ** |
| 392 | 392 | ** Accept a file from the client. |
| 393 | 393 | */ |
| 394 | 394 | if( blob_eq(&xfer.aToken[0], "file") ){ |
| 395 | - if( !g.okWrite ){ | |
| 395 | + if( !isPush ){ | |
| 396 | 396 | cgi_reset_content(); |
| 397 | 397 | @ error not\sauthorized\sto\swrite |
| 398 | 398 | nErr++; |
| 399 | 399 | break; |
| 400 | 400 | } |
| @@ -413,11 +413,11 @@ | ||
| 413 | 413 | */ |
| 414 | 414 | if( blob_eq(&xfer.aToken[0], "gimme") |
| 415 | 415 | && xfer.nToken==2 |
| 416 | 416 | && blob_is_uuid(&xfer.aToken[1]) |
| 417 | 417 | ){ |
| 418 | - if( g.okRead ){ | |
| 418 | + if( isPull ){ | |
| 419 | 419 | int rid = rid_from_uuid(&xfer.aToken[1], 0); |
| 420 | 420 | if( rid ){ |
| 421 | 421 | send_file(&xfer, rid, &xfer.aToken[1], 0); |
| 422 | 422 | } |
| 423 | 423 | } |
| @@ -429,28 +429,34 @@ | ||
| 429 | 429 | */ |
| 430 | 430 | if( xfer.nToken==2 |
| 431 | 431 | && blob_eq(&xfer.aToken[0], "igot") |
| 432 | 432 | && blob_is_uuid(&xfer.aToken[1]) |
| 433 | 433 | ){ |
| 434 | - if( g.okWrite ){ | |
| 434 | + if( isPush ){ | |
| 435 | 435 | rid_from_uuid(&xfer.aToken[1], 1); |
| 436 | 436 | } |
| 437 | 437 | }else |
| 438 | 438 | |
| 439 | 439 | |
| 440 | 440 | /* leaf UUID |
| 441 | 441 | ** |
| 442 | - ** Client announces that it has a particular manifest | |
| 442 | + ** Client announces that it has a particular manifest. If | |
| 443 | + ** the server has children of this leaf, then send those | |
| 444 | + ** children back to the client. If the server lacks this | |
| 445 | + ** leaf, request it. | |
| 443 | 446 | */ |
| 444 | 447 | if( xfer.nToken==2 |
| 445 | 448 | && blob_eq(&xfer.aToken[0], "leaf") |
| 446 | 449 | && blob_is_uuid(&xfer.aToken[1]) |
| 447 | 450 | ){ |
| 448 | - if( g.okRead ){ | |
| 449 | - int rid = rid_from_uuid(&xfer.aToken[1], 0); | |
| 451 | + int rid = rid_from_uuid(&xfer.aToken[1], 0); | |
| 452 | + if( isPull && rid ){ | |
| 450 | 453 | leaf_response(&xfer, rid); |
| 451 | 454 | } |
| 455 | + if( isPush && !rid ){ | |
| 456 | + content_put(0, blob_str(&xfer.aToken[1]), 0); | |
| 457 | + } | |
| 452 | 458 | }else |
| 453 | 459 | |
| 454 | 460 | /* pull SERVERCODE PROJECTCODE |
| 455 | 461 | ** push SERVERCODE PROJECTCODE |
| 456 | 462 | ** |
| @@ -619,40 +625,46 @@ | ||
| 619 | 625 | assert( pushFlag || pullFlag || cloneFlag ); |
| 620 | 626 | assert( !g.urlIsFile ); /* This only works for networking */ |
| 621 | 627 | |
| 622 | 628 | db_begin_transaction(); |
| 623 | 629 | db_multi_exec( |
| 624 | - "CREATE TEMP TABLE sent(rid INTEGER PRIMARY KEY);" | |
| 630 | + "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);" | |
| 625 | 631 | ); |
| 626 | 632 | blobarray_zero(xfer.aToken, count(xfer.aToken)); |
| 627 | 633 | blob_zero(&send); |
| 628 | 634 | blob_zero(&recv); |
| 629 | 635 | blob_zero(&xfer.err); |
| 630 | 636 | blob_zero(&xfer.line); |
| 631 | 637 | |
| 638 | + /* | |
| 639 | + ** Always begin with a clone, pull, or push message | |
| 640 | + */ | |
| 641 | + if( cloneFlag ){ | |
| 642 | + blob_appendf(&send, "clone\n"); | |
| 643 | + pushFlag = 0; | |
| 644 | + pullFlag = 0; | |
| 645 | + nMsg++; | |
| 646 | + }else if( pullFlag ){ | |
| 647 | + blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); | |
| 648 | + nMsg++; | |
| 649 | + } | |
| 650 | + if( pushFlag ){ | |
| 651 | + blob_appendf(&send, "push %s %s\n", zSCode, zPCode); | |
| 652 | + nMsg++; | |
| 653 | + } | |
| 654 | + | |
| 632 | 655 | |
| 633 | 656 | while( go ){ |
| 657 | + int newPhantom = 0; | |
| 634 | 658 | |
| 635 | - /* Generate a request to be sent to the server. | |
| 636 | - ** Always begin with a clone, pull, or push message | |
| 659 | + /* Generate gimme messages for phantoms and leaf messages | |
| 660 | + ** for all leaves. | |
| 637 | 661 | */ |
| 638 | - | |
| 639 | - if( cloneFlag ){ | |
| 640 | - blob_appendf(&send, "clone\n"); | |
| 641 | - pushFlag = 0; | |
| 642 | - pullFlag = 0; | |
| 643 | - nMsg++; | |
| 644 | - }else if( pullFlag ){ | |
| 645 | - blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); | |
| 646 | - nMsg++; | |
| 662 | + if( pullFlag ){ | |
| 647 | 663 | request_phantoms(&xfer); |
| 648 | 664 | send_leaves(&xfer); |
| 649 | 665 | } |
| 650 | - if( pushFlag ){ | |
| 651 | - blob_appendf(&send, "push %s %s\n", zSCode, zPCode); | |
| 652 | - nMsg++; | |
| 653 | - } | |
| 654 | 666 | |
| 655 | 667 | /* Exchange messages with the server */ |
| 656 | 668 | nFileSend = xfer.nFileSent + xfer.nDeltaSent; |
| 657 | 669 | printf("Send: %10d bytes, %3d messages, %3d files (%d+%d)\n", |
| 658 | 670 | blob_size(&send), nMsg+xfer.nGimmeSent+xfer.nIGotSent, |
| @@ -661,10 +673,23 @@ | ||
| 661 | 673 | xfer.nFileSent = 0; |
| 662 | 674 | xfer.nDeltaSent = 0; |
| 663 | 675 | xfer.nGimmeSent = 0; |
| 664 | 676 | http_exchange(&send, &recv); |
| 665 | 677 | blob_reset(&send); |
| 678 | + | |
| 679 | + /* Begin constructing the next message (which might never be | |
| 680 | + ** sent) by beginning with the pull or push messages | |
| 681 | + */ | |
| 682 | + if( pullFlag ){ | |
| 683 | + blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); | |
| 684 | + nMsg++; | |
| 685 | + } | |
| 686 | + if( pushFlag ){ | |
| 687 | + blob_appendf(&send, "push %s %s\n", zSCode, zPCode); | |
| 688 | + nMsg++; | |
| 689 | + } | |
| 690 | + | |
| 666 | 691 | |
| 667 | 692 | /* Process the reply that came back from the server */ |
| 668 | 693 | while( blob_line(&recv, &xfer.line) ){ |
| 669 | 694 | if( blob_buffer(&xfer.line)[0]=='#' ){ |
| 670 | 695 | continue; |
| @@ -706,10 +731,11 @@ | ||
| 706 | 731 | nMsg++; |
| 707 | 732 | if( pullFlag ){ |
| 708 | 733 | if( !db_exists("SELECT 1 FROM blob WHERE uuid='%b' AND size>=0", |
| 709 | 734 | &xfer.aToken[1]) ){ |
| 710 | 735 | content_put(0, blob_str(&xfer.aToken[1]), 0); |
| 736 | + newPhantom = 1; | |
| 711 | 737 | } |
| 712 | 738 | } |
| 713 | 739 | }else |
| 714 | 740 | |
| 715 | 741 | |
| @@ -720,13 +746,17 @@ | ||
| 720 | 746 | if( xfer.nToken==2 |
| 721 | 747 | && blob_eq(&xfer.aToken[0], "leaf") |
| 722 | 748 | && blob_is_uuid(&xfer.aToken[1]) |
| 723 | 749 | ){ |
| 724 | 750 | nMsg++; |
| 725 | - if( pushFlag ){ | |
| 726 | - int rid = rid_from_uuid(&xfer.aToken[1], 0); | |
| 751 | + int rid = rid_from_uuid(&xfer.aToken[1], 0); | |
| 752 | + if( pushFlag && rid ){ | |
| 727 | 753 | leaf_response(&xfer, rid); |
| 754 | + } | |
| 755 | + if( pullFlag && rid==0 ){ | |
| 756 | + content_put(0, blob_str(&xfer.aToken[1]), 0); | |
| 757 | + newPhantom = 1; | |
| 728 | 758 | } |
| 729 | 759 | }else |
| 730 | 760 | |
| 731 | 761 | |
| 732 | 762 | /* push SERVERCODE PRODUCTCODE |
| @@ -747,10 +777,12 @@ | ||
| 747 | 777 | zPCode = mprintf("%b", &xfer.aToken[2]); |
| 748 | 778 | db_set("project-code", zPCode); |
| 749 | 779 | } |
| 750 | 780 | cloneFlag = 0; |
| 751 | 781 | pullFlag = 1; |
| 782 | + blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); | |
| 783 | + nMsg++; | |
| 752 | 784 | }else |
| 753 | 785 | |
| 754 | 786 | /* error MESSAGE |
| 755 | 787 | ** |
| 756 | 788 | ** Report an error |
| @@ -783,14 +815,16 @@ | ||
| 783 | 815 | xfer.nDeltaRcvd = 0; |
| 784 | 816 | xfer.nDanglingFile = 0; |
| 785 | 817 | nCycle++; |
| 786 | 818 | go = 0; |
| 787 | 819 | |
| 788 | - /* If we have received one or more files on this cycle and | |
| 789 | - ** we have one or more phantoms, then go for another round | |
| 820 | + /* If we have received one or more files on this cycle or if | |
| 821 | + ** we have received information that has caused us to create | |
| 822 | + ** new phantoms and we have one or more phantoms, then go for | |
| 823 | + ** another round | |
| 790 | 824 | */ |
| 791 | - if(xfer.nFileRcvd+xfer.nDeltaRcvd+xfer.nDanglingFile>0 | |
| 825 | + if( (xfer.nFileRcvd+xfer.nDeltaRcvd+xfer.nDanglingFile>0 || newPhantom) | |
| 792 | 826 | && db_exists("SELECT 1 FROM phantom") |
| 793 | 827 | ){ |
| 794 | 828 | go = 1; |
| 795 | 829 | } |
| 796 | 830 | |
| 797 | 831 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -191,11 +191,11 @@ | |
| 191 | */ |
| 192 | static void send_file(Xfer *pXfer, int rid, Blob *pUuid, int srcId){ |
| 193 | Blob content, uuid; |
| 194 | int size = 0; |
| 195 | |
| 196 | if( db_exists("SELECT 1 FROM sent WHERE rid=%d", rid) ){ |
| 197 | return; |
| 198 | } |
| 199 | blob_zero(&uuid); |
| 200 | if( pUuid==0 ){ |
| 201 | db_blob(&uuid, "SELECT uuid FROM blob WHERE rid=%d AND size>=0", rid); |
| @@ -221,11 +221,11 @@ | |
| 221 | blob_append(pXfer->pOut, blob_buffer(&content), size); |
| 222 | pXfer->nFileSent++; |
| 223 | }else{ |
| 224 | pXfer->nDeltaSent++; |
| 225 | } |
| 226 | db_multi_exec("INSERT INTO sent VALUES(%d)", rid); |
| 227 | blob_reset(&uuid); |
| 228 | } |
| 229 | |
| 230 | /* |
| 231 | ** This routine runs when either client or server is notified that |
| @@ -379,11 +379,11 @@ | |
| 379 | xfer.pOut = cgi_output_blob(); |
| 380 | xfer.mxSend = db_get_int("max-download", 1000000); |
| 381 | |
| 382 | db_begin_transaction(); |
| 383 | db_multi_exec( |
| 384 | "CREATE TEMP TABLE sent(rid INTEGER PRIMARY KEY);" |
| 385 | ); |
| 386 | while( blob_line(xfer.pIn, &xfer.line) ){ |
| 387 | xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken)); |
| 388 | |
| 389 | /* file UUID SIZE \n CONTENT |
| @@ -390,11 +390,11 @@ | |
| 390 | ** file UUID DELTASRC SIZE \n CONTENT |
| 391 | ** |
| 392 | ** Accept a file from the client. |
| 393 | */ |
| 394 | if( blob_eq(&xfer.aToken[0], "file") ){ |
| 395 | if( !g.okWrite ){ |
| 396 | cgi_reset_content(); |
| 397 | @ error not\sauthorized\sto\swrite |
| 398 | nErr++; |
| 399 | break; |
| 400 | } |
| @@ -413,11 +413,11 @@ | |
| 413 | */ |
| 414 | if( blob_eq(&xfer.aToken[0], "gimme") |
| 415 | && xfer.nToken==2 |
| 416 | && blob_is_uuid(&xfer.aToken[1]) |
| 417 | ){ |
| 418 | if( g.okRead ){ |
| 419 | int rid = rid_from_uuid(&xfer.aToken[1], 0); |
| 420 | if( rid ){ |
| 421 | send_file(&xfer, rid, &xfer.aToken[1], 0); |
| 422 | } |
| 423 | } |
| @@ -429,28 +429,34 @@ | |
| 429 | */ |
| 430 | if( xfer.nToken==2 |
| 431 | && blob_eq(&xfer.aToken[0], "igot") |
| 432 | && blob_is_uuid(&xfer.aToken[1]) |
| 433 | ){ |
| 434 | if( g.okWrite ){ |
| 435 | rid_from_uuid(&xfer.aToken[1], 1); |
| 436 | } |
| 437 | }else |
| 438 | |
| 439 | |
| 440 | /* leaf UUID |
| 441 | ** |
| 442 | ** Client announces that it has a particular manifest |
| 443 | */ |
| 444 | if( xfer.nToken==2 |
| 445 | && blob_eq(&xfer.aToken[0], "leaf") |
| 446 | && blob_is_uuid(&xfer.aToken[1]) |
| 447 | ){ |
| 448 | if( g.okRead ){ |
| 449 | int rid = rid_from_uuid(&xfer.aToken[1], 0); |
| 450 | leaf_response(&xfer, rid); |
| 451 | } |
| 452 | }else |
| 453 | |
| 454 | /* pull SERVERCODE PROJECTCODE |
| 455 | ** push SERVERCODE PROJECTCODE |
| 456 | ** |
| @@ -619,40 +625,46 @@ | |
| 619 | assert( pushFlag || pullFlag || cloneFlag ); |
| 620 | assert( !g.urlIsFile ); /* This only works for networking */ |
| 621 | |
| 622 | db_begin_transaction(); |
| 623 | db_multi_exec( |
| 624 | "CREATE TEMP TABLE sent(rid INTEGER PRIMARY KEY);" |
| 625 | ); |
| 626 | blobarray_zero(xfer.aToken, count(xfer.aToken)); |
| 627 | blob_zero(&send); |
| 628 | blob_zero(&recv); |
| 629 | blob_zero(&xfer.err); |
| 630 | blob_zero(&xfer.line); |
| 631 | |
| 632 | |
| 633 | while( go ){ |
| 634 | |
| 635 | /* Generate a request to be sent to the server. |
| 636 | ** Always begin with a clone, pull, or push message |
| 637 | */ |
| 638 | |
| 639 | if( cloneFlag ){ |
| 640 | blob_appendf(&send, "clone\n"); |
| 641 | pushFlag = 0; |
| 642 | pullFlag = 0; |
| 643 | nMsg++; |
| 644 | }else if( pullFlag ){ |
| 645 | blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); |
| 646 | nMsg++; |
| 647 | request_phantoms(&xfer); |
| 648 | send_leaves(&xfer); |
| 649 | } |
| 650 | if( pushFlag ){ |
| 651 | blob_appendf(&send, "push %s %s\n", zSCode, zPCode); |
| 652 | nMsg++; |
| 653 | } |
| 654 | |
| 655 | /* Exchange messages with the server */ |
| 656 | nFileSend = xfer.nFileSent + xfer.nDeltaSent; |
| 657 | printf("Send: %10d bytes, %3d messages, %3d files (%d+%d)\n", |
| 658 | blob_size(&send), nMsg+xfer.nGimmeSent+xfer.nIGotSent, |
| @@ -661,10 +673,23 @@ | |
| 661 | xfer.nFileSent = 0; |
| 662 | xfer.nDeltaSent = 0; |
| 663 | xfer.nGimmeSent = 0; |
| 664 | http_exchange(&send, &recv); |
| 665 | blob_reset(&send); |
| 666 | |
| 667 | /* Process the reply that came back from the server */ |
| 668 | while( blob_line(&recv, &xfer.line) ){ |
| 669 | if( blob_buffer(&xfer.line)[0]=='#' ){ |
| 670 | continue; |
| @@ -706,10 +731,11 @@ | |
| 706 | nMsg++; |
| 707 | if( pullFlag ){ |
| 708 | if( !db_exists("SELECT 1 FROM blob WHERE uuid='%b' AND size>=0", |
| 709 | &xfer.aToken[1]) ){ |
| 710 | content_put(0, blob_str(&xfer.aToken[1]), 0); |
| 711 | } |
| 712 | } |
| 713 | }else |
| 714 | |
| 715 | |
| @@ -720,13 +746,17 @@ | |
| 720 | if( xfer.nToken==2 |
| 721 | && blob_eq(&xfer.aToken[0], "leaf") |
| 722 | && blob_is_uuid(&xfer.aToken[1]) |
| 723 | ){ |
| 724 | nMsg++; |
| 725 | if( pushFlag ){ |
| 726 | int rid = rid_from_uuid(&xfer.aToken[1], 0); |
| 727 | leaf_response(&xfer, rid); |
| 728 | } |
| 729 | }else |
| 730 | |
| 731 | |
| 732 | /* push SERVERCODE PRODUCTCODE |
| @@ -747,10 +777,12 @@ | |
| 747 | zPCode = mprintf("%b", &xfer.aToken[2]); |
| 748 | db_set("project-code", zPCode); |
| 749 | } |
| 750 | cloneFlag = 0; |
| 751 | pullFlag = 1; |
| 752 | }else |
| 753 | |
| 754 | /* error MESSAGE |
| 755 | ** |
| 756 | ** Report an error |
| @@ -783,14 +815,16 @@ | |
| 783 | xfer.nDeltaRcvd = 0; |
| 784 | xfer.nDanglingFile = 0; |
| 785 | nCycle++; |
| 786 | go = 0; |
| 787 | |
| 788 | /* If we have received one or more files on this cycle and |
| 789 | ** we have one or more phantoms, then go for another round |
| 790 | */ |
| 791 | if(xfer.nFileRcvd+xfer.nDeltaRcvd+xfer.nDanglingFile>0 |
| 792 | && db_exists("SELECT 1 FROM phantom") |
| 793 | ){ |
| 794 | go = 1; |
| 795 | } |
| 796 | |
| 797 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -191,11 +191,11 @@ | |
| 191 | */ |
| 192 | static void send_file(Xfer *pXfer, int rid, Blob *pUuid, int srcId){ |
| 193 | Blob content, uuid; |
| 194 | int size = 0; |
| 195 | |
| 196 | if( db_exists("SELECT 1 FROM onremote WHERE rid=%d", rid) ){ |
| 197 | return; |
| 198 | } |
| 199 | blob_zero(&uuid); |
| 200 | if( pUuid==0 ){ |
| 201 | db_blob(&uuid, "SELECT uuid FROM blob WHERE rid=%d AND size>=0", rid); |
| @@ -221,11 +221,11 @@ | |
| 221 | blob_append(pXfer->pOut, blob_buffer(&content), size); |
| 222 | pXfer->nFileSent++; |
| 223 | }else{ |
| 224 | pXfer->nDeltaSent++; |
| 225 | } |
| 226 | db_multi_exec("INSERT INTO onremote VALUES(%d)", rid); |
| 227 | blob_reset(&uuid); |
| 228 | } |
| 229 | |
| 230 | /* |
| 231 | ** This routine runs when either client or server is notified that |
| @@ -379,11 +379,11 @@ | |
| 379 | xfer.pOut = cgi_output_blob(); |
| 380 | xfer.mxSend = db_get_int("max-download", 1000000); |
| 381 | |
| 382 | db_begin_transaction(); |
| 383 | db_multi_exec( |
| 384 | "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);" |
| 385 | ); |
| 386 | while( blob_line(xfer.pIn, &xfer.line) ){ |
| 387 | xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken)); |
| 388 | |
| 389 | /* file UUID SIZE \n CONTENT |
| @@ -390,11 +390,11 @@ | |
| 390 | ** file UUID DELTASRC SIZE \n CONTENT |
| 391 | ** |
| 392 | ** Accept a file from the client. |
| 393 | */ |
| 394 | if( blob_eq(&xfer.aToken[0], "file") ){ |
| 395 | if( !isPush ){ |
| 396 | cgi_reset_content(); |
| 397 | @ error not\sauthorized\sto\swrite |
| 398 | nErr++; |
| 399 | break; |
| 400 | } |
| @@ -413,11 +413,11 @@ | |
| 413 | */ |
| 414 | if( blob_eq(&xfer.aToken[0], "gimme") |
| 415 | && xfer.nToken==2 |
| 416 | && blob_is_uuid(&xfer.aToken[1]) |
| 417 | ){ |
| 418 | if( isPull ){ |
| 419 | int rid = rid_from_uuid(&xfer.aToken[1], 0); |
| 420 | if( rid ){ |
| 421 | send_file(&xfer, rid, &xfer.aToken[1], 0); |
| 422 | } |
| 423 | } |
| @@ -429,28 +429,34 @@ | |
| 429 | */ |
| 430 | if( xfer.nToken==2 |
| 431 | && blob_eq(&xfer.aToken[0], "igot") |
| 432 | && blob_is_uuid(&xfer.aToken[1]) |
| 433 | ){ |
| 434 | if( isPush ){ |
| 435 | rid_from_uuid(&xfer.aToken[1], 1); |
| 436 | } |
| 437 | }else |
| 438 | |
| 439 | |
| 440 | /* leaf UUID |
| 441 | ** |
| 442 | ** Client announces that it has a particular manifest. If |
| 443 | ** the server has children of this leaf, then send those |
| 444 | ** children back to the client. If the server lacks this |
| 445 | ** leaf, request it. |
| 446 | */ |
| 447 | if( xfer.nToken==2 |
| 448 | && blob_eq(&xfer.aToken[0], "leaf") |
| 449 | && blob_is_uuid(&xfer.aToken[1]) |
| 450 | ){ |
| 451 | int rid = rid_from_uuid(&xfer.aToken[1], 0); |
| 452 | if( isPull && rid ){ |
| 453 | leaf_response(&xfer, rid); |
| 454 | } |
| 455 | if( isPush && !rid ){ |
| 456 | content_put(0, blob_str(&xfer.aToken[1]), 0); |
| 457 | } |
| 458 | }else |
| 459 | |
| 460 | /* pull SERVERCODE PROJECTCODE |
| 461 | ** push SERVERCODE PROJECTCODE |
| 462 | ** |
| @@ -619,40 +625,46 @@ | |
| 625 | assert( pushFlag || pullFlag || cloneFlag ); |
| 626 | assert( !g.urlIsFile ); /* This only works for networking */ |
| 627 | |
| 628 | db_begin_transaction(); |
| 629 | db_multi_exec( |
| 630 | "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);" |
| 631 | ); |
| 632 | blobarray_zero(xfer.aToken, count(xfer.aToken)); |
| 633 | blob_zero(&send); |
| 634 | blob_zero(&recv); |
| 635 | blob_zero(&xfer.err); |
| 636 | blob_zero(&xfer.line); |
| 637 | |
| 638 | /* |
| 639 | ** Always begin with a clone, pull, or push message |
| 640 | */ |
| 641 | if( cloneFlag ){ |
| 642 | blob_appendf(&send, "clone\n"); |
| 643 | pushFlag = 0; |
| 644 | pullFlag = 0; |
| 645 | nMsg++; |
| 646 | }else if( pullFlag ){ |
| 647 | blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); |
| 648 | nMsg++; |
| 649 | } |
| 650 | if( pushFlag ){ |
| 651 | blob_appendf(&send, "push %s %s\n", zSCode, zPCode); |
| 652 | nMsg++; |
| 653 | } |
| 654 | |
| 655 | |
| 656 | while( go ){ |
| 657 | int newPhantom = 0; |
| 658 | |
| 659 | /* Generate gimme messages for phantoms and leaf messages |
| 660 | ** for all leaves. |
| 661 | */ |
| 662 | if( pullFlag ){ |
| 663 | request_phantoms(&xfer); |
| 664 | send_leaves(&xfer); |
| 665 | } |
| 666 | |
| 667 | /* Exchange messages with the server */ |
| 668 | nFileSend = xfer.nFileSent + xfer.nDeltaSent; |
| 669 | printf("Send: %10d bytes, %3d messages, %3d files (%d+%d)\n", |
| 670 | blob_size(&send), nMsg+xfer.nGimmeSent+xfer.nIGotSent, |
| @@ -661,10 +673,23 @@ | |
| 673 | xfer.nFileSent = 0; |
| 674 | xfer.nDeltaSent = 0; |
| 675 | xfer.nGimmeSent = 0; |
| 676 | http_exchange(&send, &recv); |
| 677 | blob_reset(&send); |
| 678 | |
| 679 | /* Begin constructing the next message (which might never be |
| 680 | ** sent) by beginning with the pull or push messages |
| 681 | */ |
| 682 | if( pullFlag ){ |
| 683 | blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); |
| 684 | nMsg++; |
| 685 | } |
| 686 | if( pushFlag ){ |
| 687 | blob_appendf(&send, "push %s %s\n", zSCode, zPCode); |
| 688 | nMsg++; |
| 689 | } |
| 690 | |
| 691 | |
| 692 | /* Process the reply that came back from the server */ |
| 693 | while( blob_line(&recv, &xfer.line) ){ |
| 694 | if( blob_buffer(&xfer.line)[0]=='#' ){ |
| 695 | continue; |
| @@ -706,10 +731,11 @@ | |
| 731 | nMsg++; |
| 732 | if( pullFlag ){ |
| 733 | if( !db_exists("SELECT 1 FROM blob WHERE uuid='%b' AND size>=0", |
| 734 | &xfer.aToken[1]) ){ |
| 735 | content_put(0, blob_str(&xfer.aToken[1]), 0); |
| 736 | newPhantom = 1; |
| 737 | } |
| 738 | } |
| 739 | }else |
| 740 | |
| 741 | |
| @@ -720,13 +746,17 @@ | |
| 746 | if( xfer.nToken==2 |
| 747 | && blob_eq(&xfer.aToken[0], "leaf") |
| 748 | && blob_is_uuid(&xfer.aToken[1]) |
| 749 | ){ |
| 750 | nMsg++; |
| 751 | int rid = rid_from_uuid(&xfer.aToken[1], 0); |
| 752 | if( pushFlag && rid ){ |
| 753 | leaf_response(&xfer, rid); |
| 754 | } |
| 755 | if( pullFlag && rid==0 ){ |
| 756 | content_put(0, blob_str(&xfer.aToken[1]), 0); |
| 757 | newPhantom = 1; |
| 758 | } |
| 759 | }else |
| 760 | |
| 761 | |
| 762 | /* push SERVERCODE PRODUCTCODE |
| @@ -747,10 +777,12 @@ | |
| 777 | zPCode = mprintf("%b", &xfer.aToken[2]); |
| 778 | db_set("project-code", zPCode); |
| 779 | } |
| 780 | cloneFlag = 0; |
| 781 | pullFlag = 1; |
| 782 | blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); |
| 783 | nMsg++; |
| 784 | }else |
| 785 | |
| 786 | /* error MESSAGE |
| 787 | ** |
| 788 | ** Report an error |
| @@ -783,14 +815,16 @@ | |
| 815 | xfer.nDeltaRcvd = 0; |
| 816 | xfer.nDanglingFile = 0; |
| 817 | nCycle++; |
| 818 | go = 0; |
| 819 | |
| 820 | /* If we have received one or more files on this cycle or if |
| 821 | ** we have received information that has caused us to create |
| 822 | ** new phantoms and we have one or more phantoms, then go for |
| 823 | ** another round |
| 824 | */ |
| 825 | if( (xfer.nFileRcvd+xfer.nDeltaRcvd+xfer.nDanglingFile>0 || newPhantom) |
| 826 | && db_exists("SELECT 1 FROM phantom") |
| 827 | ){ |
| 828 | go = 1; |
| 829 | } |
| 830 | |
| 831 |