Fossil SCM
Prevent blank user names from being displayed for items awaiting moderation. Also, Show much less output on a sync operation, unless the --verbose flag is given.
Commit
15708574fe27eb0500ade91c21c5c29d86034c2f
Parent
26ac392308a1273…
25 files changed
+4
-2
+4
-2
+1
-1
+1
-1
+2
-2
+2
-2
+4
-4
+4
-4
+3
-3
+3
-3
+3
-3
+1
-1
+1
-1
+34
-32
+34
-32
+34
-32
+6
-4
+6
-4
+6
-4
+3
-1
+3
-1
+3
-1
+80
-43
+80
-43
+80
-43
~
src/attach.c
~
src/attach.c
~
src/branch.c
~
src/branch.c
~
src/checkin.c
~
src/checkin.c
~
src/clone.c
~
src/clone.c
~
src/configure.c
~
src/configure.c
~
src/configure.c
~
src/json_branch.c
~
src/json_branch.c
~
src/sync.c
~
src/sync.c
~
src/sync.c
~
src/timeline.c
~
src/timeline.c
~
src/timeline.c
~
src/update.c
~
src/update.c
~
src/update.c
~
src/xfer.c
~
src/xfer.c
~
src/xfer.c
+4
-2
| --- src/attach.c | ||
| +++ src/attach.c | ||
| @@ -71,10 +71,11 @@ | ||
| 71 | 71 | const char *zFilename = db_column_text(&q, 3); |
| 72 | 72 | const char *zComment = db_column_text(&q, 4); |
| 73 | 73 | const char *zUser = db_column_text(&q, 5); |
| 74 | 74 | const char *zUuid = db_column_text(&q, 6); |
| 75 | 75 | int attachid = db_column_int(&q, 7); |
| 76 | + const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous"; | |
| 76 | 77 | int i; |
| 77 | 78 | char *zUrlTail; |
| 78 | 79 | for(i=0; zFilename[i]; i++){ |
| 79 | 80 | if( zFilename[i]=='/' && zFilename[i+1]!=0 ){ |
| 80 | 81 | zFilename = &zFilename[i+1]; |
| @@ -115,11 +116,11 @@ | ||
| 115 | 116 | @ Deleted |
| 116 | 117 | }else { |
| 117 | 118 | @ Added |
| 118 | 119 | } |
| 119 | 120 | } |
| 120 | - @ by %h(zUser) on | |
| 121 | + @ by %h(zDispUser) on | |
| 121 | 122 | hyperlink_to_date(zDate, "."); |
| 122 | 123 | free(zUrlTail); |
| 123 | 124 | } |
| 124 | 125 | db_finalize(&q); |
| 125 | 126 | @ </ol> |
| @@ -557,17 +558,18 @@ | ||
| 557 | 558 | const char *zDate = db_column_text(&q, 0); |
| 558 | 559 | const char *zFile = db_column_text(&q, 1); |
| 559 | 560 | const char *zUser = db_column_text(&q, 2); |
| 560 | 561 | const char *zUuid = db_column_text(&q, 3); |
| 561 | 562 | const char *zSrc = db_column_text(&q, 4); |
| 563 | + const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous"; | |
| 562 | 564 | if( cnt==0 ){ |
| 563 | 565 | @ %s(zHeader) |
| 564 | 566 | } |
| 565 | 567 | cnt++; |
| 566 | 568 | @ <li> |
| 567 | 569 | @ %z(href("%R/artifact/%s",zSrc))%h(zFile)</a> |
| 568 | - @ added by %h(zUser) on | |
| 570 | + @ added by %h(zDispUser) on | |
| 569 | 571 | hyperlink_to_date(zDate, "."); |
| 570 | 572 | @ [%z(href("%R/ainfo/%s",zUuid))details</a>] |
| 571 | 573 | @ </li> |
| 572 | 574 | } |
| 573 | 575 | if( cnt ){ |
| 574 | 576 |
| --- src/attach.c | |
| +++ src/attach.c | |
| @@ -71,10 +71,11 @@ | |
| 71 | const char *zFilename = db_column_text(&q, 3); |
| 72 | const char *zComment = db_column_text(&q, 4); |
| 73 | const char *zUser = db_column_text(&q, 5); |
| 74 | const char *zUuid = db_column_text(&q, 6); |
| 75 | int attachid = db_column_int(&q, 7); |
| 76 | int i; |
| 77 | char *zUrlTail; |
| 78 | for(i=0; zFilename[i]; i++){ |
| 79 | if( zFilename[i]=='/' && zFilename[i+1]!=0 ){ |
| 80 | zFilename = &zFilename[i+1]; |
| @@ -115,11 +116,11 @@ | |
| 115 | @ Deleted |
| 116 | }else { |
| 117 | @ Added |
| 118 | } |
| 119 | } |
| 120 | @ by %h(zUser) on |
| 121 | hyperlink_to_date(zDate, "."); |
| 122 | free(zUrlTail); |
| 123 | } |
| 124 | db_finalize(&q); |
| 125 | @ </ol> |
| @@ -557,17 +558,18 @@ | |
| 557 | const char *zDate = db_column_text(&q, 0); |
| 558 | const char *zFile = db_column_text(&q, 1); |
| 559 | const char *zUser = db_column_text(&q, 2); |
| 560 | const char *zUuid = db_column_text(&q, 3); |
| 561 | const char *zSrc = db_column_text(&q, 4); |
| 562 | if( cnt==0 ){ |
| 563 | @ %s(zHeader) |
| 564 | } |
| 565 | cnt++; |
| 566 | @ <li> |
| 567 | @ %z(href("%R/artifact/%s",zSrc))%h(zFile)</a> |
| 568 | @ added by %h(zUser) on |
| 569 | hyperlink_to_date(zDate, "."); |
| 570 | @ [%z(href("%R/ainfo/%s",zUuid))details</a>] |
| 571 | @ </li> |
| 572 | } |
| 573 | if( cnt ){ |
| 574 |
| --- src/attach.c | |
| +++ src/attach.c | |
| @@ -71,10 +71,11 @@ | |
| 71 | const char *zFilename = db_column_text(&q, 3); |
| 72 | const char *zComment = db_column_text(&q, 4); |
| 73 | const char *zUser = db_column_text(&q, 5); |
| 74 | const char *zUuid = db_column_text(&q, 6); |
| 75 | int attachid = db_column_int(&q, 7); |
| 76 | const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous"; |
| 77 | int i; |
| 78 | char *zUrlTail; |
| 79 | for(i=0; zFilename[i]; i++){ |
| 80 | if( zFilename[i]=='/' && zFilename[i+1]!=0 ){ |
| 81 | zFilename = &zFilename[i+1]; |
| @@ -115,11 +116,11 @@ | |
| 116 | @ Deleted |
| 117 | }else { |
| 118 | @ Added |
| 119 | } |
| 120 | } |
| 121 | @ by %h(zDispUser) on |
| 122 | hyperlink_to_date(zDate, "."); |
| 123 | free(zUrlTail); |
| 124 | } |
| 125 | db_finalize(&q); |
| 126 | @ </ol> |
| @@ -557,17 +558,18 @@ | |
| 558 | const char *zDate = db_column_text(&q, 0); |
| 559 | const char *zFile = db_column_text(&q, 1); |
| 560 | const char *zUser = db_column_text(&q, 2); |
| 561 | const char *zUuid = db_column_text(&q, 3); |
| 562 | const char *zSrc = db_column_text(&q, 4); |
| 563 | const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous"; |
| 564 | if( cnt==0 ){ |
| 565 | @ %s(zHeader) |
| 566 | } |
| 567 | cnt++; |
| 568 | @ <li> |
| 569 | @ %z(href("%R/artifact/%s",zSrc))%h(zFile)</a> |
| 570 | @ added by %h(zDispUser) on |
| 571 | hyperlink_to_date(zDate, "."); |
| 572 | @ [%z(href("%R/ainfo/%s",zUuid))details</a>] |
| 573 | @ </li> |
| 574 | } |
| 575 | if( cnt ){ |
| 576 |
+4
-2
| --- src/attach.c | ||
| +++ src/attach.c | ||
| @@ -71,10 +71,11 @@ | ||
| 71 | 71 | const char *zFilename = db_column_text(&q, 3); |
| 72 | 72 | const char *zComment = db_column_text(&q, 4); |
| 73 | 73 | const char *zUser = db_column_text(&q, 5); |
| 74 | 74 | const char *zUuid = db_column_text(&q, 6); |
| 75 | 75 | int attachid = db_column_int(&q, 7); |
| 76 | + const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous"; | |
| 76 | 77 | int i; |
| 77 | 78 | char *zUrlTail; |
| 78 | 79 | for(i=0; zFilename[i]; i++){ |
| 79 | 80 | if( zFilename[i]=='/' && zFilename[i+1]!=0 ){ |
| 80 | 81 | zFilename = &zFilename[i+1]; |
| @@ -115,11 +116,11 @@ | ||
| 115 | 116 | @ Deleted |
| 116 | 117 | }else { |
| 117 | 118 | @ Added |
| 118 | 119 | } |
| 119 | 120 | } |
| 120 | - @ by %h(zUser) on | |
| 121 | + @ by %h(zDispUser) on | |
| 121 | 122 | hyperlink_to_date(zDate, "."); |
| 122 | 123 | free(zUrlTail); |
| 123 | 124 | } |
| 124 | 125 | db_finalize(&q); |
| 125 | 126 | @ </ol> |
| @@ -557,17 +558,18 @@ | ||
| 557 | 558 | const char *zDate = db_column_text(&q, 0); |
| 558 | 559 | const char *zFile = db_column_text(&q, 1); |
| 559 | 560 | const char *zUser = db_column_text(&q, 2); |
| 560 | 561 | const char *zUuid = db_column_text(&q, 3); |
| 561 | 562 | const char *zSrc = db_column_text(&q, 4); |
| 563 | + const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous"; | |
| 562 | 564 | if( cnt==0 ){ |
| 563 | 565 | @ %s(zHeader) |
| 564 | 566 | } |
| 565 | 567 | cnt++; |
| 566 | 568 | @ <li> |
| 567 | 569 | @ %z(href("%R/artifact/%s",zSrc))%h(zFile)</a> |
| 568 | - @ added by %h(zUser) on | |
| 570 | + @ added by %h(zDispUser) on | |
| 569 | 571 | hyperlink_to_date(zDate, "."); |
| 570 | 572 | @ [%z(href("%R/ainfo/%s",zUuid))details</a>] |
| 571 | 573 | @ </li> |
| 572 | 574 | } |
| 573 | 575 | if( cnt ){ |
| 574 | 576 |
| --- src/attach.c | |
| +++ src/attach.c | |
| @@ -71,10 +71,11 @@ | |
| 71 | const char *zFilename = db_column_text(&q, 3); |
| 72 | const char *zComment = db_column_text(&q, 4); |
| 73 | const char *zUser = db_column_text(&q, 5); |
| 74 | const char *zUuid = db_column_text(&q, 6); |
| 75 | int attachid = db_column_int(&q, 7); |
| 76 | int i; |
| 77 | char *zUrlTail; |
| 78 | for(i=0; zFilename[i]; i++){ |
| 79 | if( zFilename[i]=='/' && zFilename[i+1]!=0 ){ |
| 80 | zFilename = &zFilename[i+1]; |
| @@ -115,11 +116,11 @@ | |
| 115 | @ Deleted |
| 116 | }else { |
| 117 | @ Added |
| 118 | } |
| 119 | } |
| 120 | @ by %h(zUser) on |
| 121 | hyperlink_to_date(zDate, "."); |
| 122 | free(zUrlTail); |
| 123 | } |
| 124 | db_finalize(&q); |
| 125 | @ </ol> |
| @@ -557,17 +558,18 @@ | |
| 557 | const char *zDate = db_column_text(&q, 0); |
| 558 | const char *zFile = db_column_text(&q, 1); |
| 559 | const char *zUser = db_column_text(&q, 2); |
| 560 | const char *zUuid = db_column_text(&q, 3); |
| 561 | const char *zSrc = db_column_text(&q, 4); |
| 562 | if( cnt==0 ){ |
| 563 | @ %s(zHeader) |
| 564 | } |
| 565 | cnt++; |
| 566 | @ <li> |
| 567 | @ %z(href("%R/artifact/%s",zSrc))%h(zFile)</a> |
| 568 | @ added by %h(zUser) on |
| 569 | hyperlink_to_date(zDate, "."); |
| 570 | @ [%z(href("%R/ainfo/%s",zUuid))details</a>] |
| 571 | @ </li> |
| 572 | } |
| 573 | if( cnt ){ |
| 574 |
| --- src/attach.c | |
| +++ src/attach.c | |
| @@ -71,10 +71,11 @@ | |
| 71 | const char *zFilename = db_column_text(&q, 3); |
| 72 | const char *zComment = db_column_text(&q, 4); |
| 73 | const char *zUser = db_column_text(&q, 5); |
| 74 | const char *zUuid = db_column_text(&q, 6); |
| 75 | int attachid = db_column_int(&q, 7); |
| 76 | const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous"; |
| 77 | int i; |
| 78 | char *zUrlTail; |
| 79 | for(i=0; zFilename[i]; i++){ |
| 80 | if( zFilename[i]=='/' && zFilename[i+1]!=0 ){ |
| 81 | zFilename = &zFilename[i+1]; |
| @@ -115,11 +116,11 @@ | |
| 116 | @ Deleted |
| 117 | }else { |
| 118 | @ Added |
| 119 | } |
| 120 | } |
| 121 | @ by %h(zDispUser) on |
| 122 | hyperlink_to_date(zDate, "."); |
| 123 | free(zUrlTail); |
| 124 | } |
| 125 | db_finalize(&q); |
| 126 | @ </ol> |
| @@ -557,17 +558,18 @@ | |
| 558 | const char *zDate = db_column_text(&q, 0); |
| 559 | const char *zFile = db_column_text(&q, 1); |
| 560 | const char *zUser = db_column_text(&q, 2); |
| 561 | const char *zUuid = db_column_text(&q, 3); |
| 562 | const char *zSrc = db_column_text(&q, 4); |
| 563 | const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous"; |
| 564 | if( cnt==0 ){ |
| 565 | @ %s(zHeader) |
| 566 | } |
| 567 | cnt++; |
| 568 | @ <li> |
| 569 | @ %z(href("%R/artifact/%s",zSrc))%h(zFile)</a> |
| 570 | @ added by %h(zDispUser) on |
| 571 | hyperlink_to_date(zDate, "."); |
| 572 | @ [%z(href("%R/ainfo/%s",zUuid))details</a>] |
| 573 | @ </li> |
| 574 | } |
| 575 | if( cnt ){ |
| 576 |
+1
-1
| --- src/branch.c | ||
| +++ src/branch.c | ||
| @@ -176,11 +176,11 @@ | ||
| 176 | 176 | |
| 177 | 177 | /* Commit */ |
| 178 | 178 | db_end_transaction(0); |
| 179 | 179 | |
| 180 | 180 | /* Do an autosync push, if requested */ |
| 181 | - if( !isPrivate ) autosync(AUTOSYNC_PUSH); | |
| 181 | + if( !isPrivate ) autosync(SYNC_PUSH); | |
| 182 | 182 | } |
| 183 | 183 | |
| 184 | 184 | /* |
| 185 | 185 | ** Prepare a query that will list branches. |
| 186 | 186 | ** |
| 187 | 187 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -176,11 +176,11 @@ | |
| 176 | |
| 177 | /* Commit */ |
| 178 | db_end_transaction(0); |
| 179 | |
| 180 | /* Do an autosync push, if requested */ |
| 181 | if( !isPrivate ) autosync(AUTOSYNC_PUSH); |
| 182 | } |
| 183 | |
| 184 | /* |
| 185 | ** Prepare a query that will list branches. |
| 186 | ** |
| 187 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -176,11 +176,11 @@ | |
| 176 | |
| 177 | /* Commit */ |
| 178 | db_end_transaction(0); |
| 179 | |
| 180 | /* Do an autosync push, if requested */ |
| 181 | if( !isPrivate ) autosync(SYNC_PUSH); |
| 182 | } |
| 183 | |
| 184 | /* |
| 185 | ** Prepare a query that will list branches. |
| 186 | ** |
| 187 |
+1
-1
| --- src/branch.c | ||
| +++ src/branch.c | ||
| @@ -176,11 +176,11 @@ | ||
| 176 | 176 | |
| 177 | 177 | /* Commit */ |
| 178 | 178 | db_end_transaction(0); |
| 179 | 179 | |
| 180 | 180 | /* Do an autosync push, if requested */ |
| 181 | - if( !isPrivate ) autosync(AUTOSYNC_PUSH); | |
| 181 | + if( !isPrivate ) autosync(SYNC_PUSH); | |
| 182 | 182 | } |
| 183 | 183 | |
| 184 | 184 | /* |
| 185 | 185 | ** Prepare a query that will list branches. |
| 186 | 186 | ** |
| 187 | 187 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -176,11 +176,11 @@ | |
| 176 | |
| 177 | /* Commit */ |
| 178 | db_end_transaction(0); |
| 179 | |
| 180 | /* Do an autosync push, if requested */ |
| 181 | if( !isPrivate ) autosync(AUTOSYNC_PUSH); |
| 182 | } |
| 183 | |
| 184 | /* |
| 185 | ** Prepare a query that will list branches. |
| 186 | ** |
| 187 |
| --- src/branch.c | |
| +++ src/branch.c | |
| @@ -176,11 +176,11 @@ | |
| 176 | |
| 177 | /* Commit */ |
| 178 | db_end_transaction(0); |
| 179 | |
| 180 | /* Do an autosync push, if requested */ |
| 181 | if( !isPrivate ) autosync(SYNC_PUSH); |
| 182 | } |
| 183 | |
| 184 | /* |
| 185 | ** Prepare a query that will list branches. |
| 186 | ** |
| 187 |
+2
-2
| --- src/checkin.c | ||
| +++ src/checkin.c | ||
| @@ -1108,11 +1108,11 @@ | ||
| 1108 | 1108 | |
| 1109 | 1109 | /* |
| 1110 | 1110 | ** Autosync if autosync is enabled and this is not a private check-in. |
| 1111 | 1111 | */ |
| 1112 | 1112 | if( !g.markPrivate ){ |
| 1113 | - if( autosync(AUTOSYNC_PULL) ){ | |
| 1113 | + if( autosync(SYNC_PULL) ){ | |
| 1114 | 1114 | blob_zero(&ans); |
| 1115 | 1115 | prompt_user("continue in spite of sync failure (y/N)? ", &ans); |
| 1116 | 1116 | cReply = blob_str(&ans)[0]; |
| 1117 | 1117 | if( cReply!='y' && cReply!='Y' ){ |
| 1118 | 1118 | fossil_exit(1); |
| @@ -1459,11 +1459,11 @@ | ||
| 1459 | 1459 | exit(1); |
| 1460 | 1460 | } |
| 1461 | 1461 | db_end_transaction(0); |
| 1462 | 1462 | |
| 1463 | 1463 | if( !g.markPrivate ){ |
| 1464 | - autosync(AUTOSYNC_PUSH); | |
| 1464 | + autosync(SYNC_PUSH); | |
| 1465 | 1465 | } |
| 1466 | 1466 | if( count_nonbranch_children(vid)>1 ){ |
| 1467 | 1467 | fossil_print("**** warning: a fork has occurred *****\n"); |
| 1468 | 1468 | } |
| 1469 | 1469 | } |
| 1470 | 1470 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -1108,11 +1108,11 @@ | |
| 1108 | |
| 1109 | /* |
| 1110 | ** Autosync if autosync is enabled and this is not a private check-in. |
| 1111 | */ |
| 1112 | if( !g.markPrivate ){ |
| 1113 | if( autosync(AUTOSYNC_PULL) ){ |
| 1114 | blob_zero(&ans); |
| 1115 | prompt_user("continue in spite of sync failure (y/N)? ", &ans); |
| 1116 | cReply = blob_str(&ans)[0]; |
| 1117 | if( cReply!='y' && cReply!='Y' ){ |
| 1118 | fossil_exit(1); |
| @@ -1459,11 +1459,11 @@ | |
| 1459 | exit(1); |
| 1460 | } |
| 1461 | db_end_transaction(0); |
| 1462 | |
| 1463 | if( !g.markPrivate ){ |
| 1464 | autosync(AUTOSYNC_PUSH); |
| 1465 | } |
| 1466 | if( count_nonbranch_children(vid)>1 ){ |
| 1467 | fossil_print("**** warning: a fork has occurred *****\n"); |
| 1468 | } |
| 1469 | } |
| 1470 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -1108,11 +1108,11 @@ | |
| 1108 | |
| 1109 | /* |
| 1110 | ** Autosync if autosync is enabled and this is not a private check-in. |
| 1111 | */ |
| 1112 | if( !g.markPrivate ){ |
| 1113 | if( autosync(SYNC_PULL) ){ |
| 1114 | blob_zero(&ans); |
| 1115 | prompt_user("continue in spite of sync failure (y/N)? ", &ans); |
| 1116 | cReply = blob_str(&ans)[0]; |
| 1117 | if( cReply!='y' && cReply!='Y' ){ |
| 1118 | fossil_exit(1); |
| @@ -1459,11 +1459,11 @@ | |
| 1459 | exit(1); |
| 1460 | } |
| 1461 | db_end_transaction(0); |
| 1462 | |
| 1463 | if( !g.markPrivate ){ |
| 1464 | autosync(SYNC_PUSH); |
| 1465 | } |
| 1466 | if( count_nonbranch_children(vid)>1 ){ |
| 1467 | fossil_print("**** warning: a fork has occurred *****\n"); |
| 1468 | } |
| 1469 | } |
| 1470 |
+2
-2
| --- src/checkin.c | ||
| +++ src/checkin.c | ||
| @@ -1108,11 +1108,11 @@ | ||
| 1108 | 1108 | |
| 1109 | 1109 | /* |
| 1110 | 1110 | ** Autosync if autosync is enabled and this is not a private check-in. |
| 1111 | 1111 | */ |
| 1112 | 1112 | if( !g.markPrivate ){ |
| 1113 | - if( autosync(AUTOSYNC_PULL) ){ | |
| 1113 | + if( autosync(SYNC_PULL) ){ | |
| 1114 | 1114 | blob_zero(&ans); |
| 1115 | 1115 | prompt_user("continue in spite of sync failure (y/N)? ", &ans); |
| 1116 | 1116 | cReply = blob_str(&ans)[0]; |
| 1117 | 1117 | if( cReply!='y' && cReply!='Y' ){ |
| 1118 | 1118 | fossil_exit(1); |
| @@ -1459,11 +1459,11 @@ | ||
| 1459 | 1459 | exit(1); |
| 1460 | 1460 | } |
| 1461 | 1461 | db_end_transaction(0); |
| 1462 | 1462 | |
| 1463 | 1463 | if( !g.markPrivate ){ |
| 1464 | - autosync(AUTOSYNC_PUSH); | |
| 1464 | + autosync(SYNC_PUSH); | |
| 1465 | 1465 | } |
| 1466 | 1466 | if( count_nonbranch_children(vid)>1 ){ |
| 1467 | 1467 | fossil_print("**** warning: a fork has occurred *****\n"); |
| 1468 | 1468 | } |
| 1469 | 1469 | } |
| 1470 | 1470 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -1108,11 +1108,11 @@ | |
| 1108 | |
| 1109 | /* |
| 1110 | ** Autosync if autosync is enabled and this is not a private check-in. |
| 1111 | */ |
| 1112 | if( !g.markPrivate ){ |
| 1113 | if( autosync(AUTOSYNC_PULL) ){ |
| 1114 | blob_zero(&ans); |
| 1115 | prompt_user("continue in spite of sync failure (y/N)? ", &ans); |
| 1116 | cReply = blob_str(&ans)[0]; |
| 1117 | if( cReply!='y' && cReply!='Y' ){ |
| 1118 | fossil_exit(1); |
| @@ -1459,11 +1459,11 @@ | |
| 1459 | exit(1); |
| 1460 | } |
| 1461 | db_end_transaction(0); |
| 1462 | |
| 1463 | if( !g.markPrivate ){ |
| 1464 | autosync(AUTOSYNC_PUSH); |
| 1465 | } |
| 1466 | if( count_nonbranch_children(vid)>1 ){ |
| 1467 | fossil_print("**** warning: a fork has occurred *****\n"); |
| 1468 | } |
| 1469 | } |
| 1470 |
| --- src/checkin.c | |
| +++ src/checkin.c | |
| @@ -1108,11 +1108,11 @@ | |
| 1108 | |
| 1109 | /* |
| 1110 | ** Autosync if autosync is enabled and this is not a private check-in. |
| 1111 | */ |
| 1112 | if( !g.markPrivate ){ |
| 1113 | if( autosync(SYNC_PULL) ){ |
| 1114 | blob_zero(&ans); |
| 1115 | prompt_user("continue in spite of sync failure (y/N)? ", &ans); |
| 1116 | cReply = blob_str(&ans)[0]; |
| 1117 | if( cReply!='y' && cReply!='Y' ){ |
| 1118 | fossil_exit(1); |
| @@ -1459,11 +1459,11 @@ | |
| 1459 | exit(1); |
| 1460 | } |
| 1461 | db_end_transaction(0); |
| 1462 | |
| 1463 | if( !g.markPrivate ){ |
| 1464 | autosync(SYNC_PUSH); |
| 1465 | } |
| 1466 | if( count_nonbranch_children(vid)>1 ){ |
| 1467 | fossil_print("**** warning: a fork has occurred *****\n"); |
| 1468 | } |
| 1469 | } |
| 1470 |
+4
-4
| --- src/clone.c | ||
| +++ src/clone.c | ||
| @@ -99,15 +99,15 @@ | ||
| 99 | 99 | ** See also: init |
| 100 | 100 | */ |
| 101 | 101 | void clone_cmd(void){ |
| 102 | 102 | char *zPassword; |
| 103 | 103 | const char *zDefaultUser; /* Optional name of the default user */ |
| 104 | - const char *zPw; /* The user clone password */ | |
| 104 | + const char *zPw; /* The user clone password */ | |
| 105 | 105 | int nErr = 0; |
| 106 | - int bPrivate; /* Also clone private branches */ | |
| 106 | + int bPrivate = 0; /* Also clone private branches */ | |
| 107 | 107 | |
| 108 | - bPrivate = find_option("private",0,0)!=0; | |
| 108 | + if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE; | |
| 109 | 109 | url_proxy_options(); |
| 110 | 110 | if( g.argc < 4 ){ |
| 111 | 111 | usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY"); |
| 112 | 112 | } |
| 113 | 113 | db_open_config(0); |
| @@ -162,11 +162,11 @@ | ||
| 162 | 162 | " VALUES('server-code', lower(hex(randomblob(20))), now());" |
| 163 | 163 | ); |
| 164 | 164 | url_enable_proxy(0); |
| 165 | 165 | url_get_password_if_needed(); |
| 166 | 166 | g.xlinkClusterOnly = 1; |
| 167 | - nErr = client_sync(0,0,1,bPrivate,CONFIGSET_ALL,0); | |
| 167 | + nErr = client_sync(SYNC_CLONE | bPrivate,CONFIGSET_ALL,0); | |
| 168 | 168 | g.xlinkClusterOnly = 0; |
| 169 | 169 | verify_cancel(); |
| 170 | 170 | db_end_transaction(0); |
| 171 | 171 | db_close(1); |
| 172 | 172 | if( nErr ){ |
| 173 | 173 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -99,15 +99,15 @@ | |
| 99 | ** See also: init |
| 100 | */ |
| 101 | void clone_cmd(void){ |
| 102 | char *zPassword; |
| 103 | const char *zDefaultUser; /* Optional name of the default user */ |
| 104 | const char *zPw; /* The user clone password */ |
| 105 | int nErr = 0; |
| 106 | int bPrivate; /* Also clone private branches */ |
| 107 | |
| 108 | bPrivate = find_option("private",0,0)!=0; |
| 109 | url_proxy_options(); |
| 110 | if( g.argc < 4 ){ |
| 111 | usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY"); |
| 112 | } |
| 113 | db_open_config(0); |
| @@ -162,11 +162,11 @@ | |
| 162 | " VALUES('server-code', lower(hex(randomblob(20))), now());" |
| 163 | ); |
| 164 | url_enable_proxy(0); |
| 165 | url_get_password_if_needed(); |
| 166 | g.xlinkClusterOnly = 1; |
| 167 | nErr = client_sync(0,0,1,bPrivate,CONFIGSET_ALL,0); |
| 168 | g.xlinkClusterOnly = 0; |
| 169 | verify_cancel(); |
| 170 | db_end_transaction(0); |
| 171 | db_close(1); |
| 172 | if( nErr ){ |
| 173 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -99,15 +99,15 @@ | |
| 99 | ** See also: init |
| 100 | */ |
| 101 | void clone_cmd(void){ |
| 102 | char *zPassword; |
| 103 | const char *zDefaultUser; /* Optional name of the default user */ |
| 104 | const char *zPw; /* The user clone password */ |
| 105 | int nErr = 0; |
| 106 | int bPrivate = 0; /* Also clone private branches */ |
| 107 | |
| 108 | if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE; |
| 109 | url_proxy_options(); |
| 110 | if( g.argc < 4 ){ |
| 111 | usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY"); |
| 112 | } |
| 113 | db_open_config(0); |
| @@ -162,11 +162,11 @@ | |
| 162 | " VALUES('server-code', lower(hex(randomblob(20))), now());" |
| 163 | ); |
| 164 | url_enable_proxy(0); |
| 165 | url_get_password_if_needed(); |
| 166 | g.xlinkClusterOnly = 1; |
| 167 | nErr = client_sync(SYNC_CLONE | bPrivate,CONFIGSET_ALL,0); |
| 168 | g.xlinkClusterOnly = 0; |
| 169 | verify_cancel(); |
| 170 | db_end_transaction(0); |
| 171 | db_close(1); |
| 172 | if( nErr ){ |
| 173 |
+4
-4
| --- src/clone.c | ||
| +++ src/clone.c | ||
| @@ -99,15 +99,15 @@ | ||
| 99 | 99 | ** See also: init |
| 100 | 100 | */ |
| 101 | 101 | void clone_cmd(void){ |
| 102 | 102 | char *zPassword; |
| 103 | 103 | const char *zDefaultUser; /* Optional name of the default user */ |
| 104 | - const char *zPw; /* The user clone password */ | |
| 104 | + const char *zPw; /* The user clone password */ | |
| 105 | 105 | int nErr = 0; |
| 106 | - int bPrivate; /* Also clone private branches */ | |
| 106 | + int bPrivate = 0; /* Also clone private branches */ | |
| 107 | 107 | |
| 108 | - bPrivate = find_option("private",0,0)!=0; | |
| 108 | + if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE; | |
| 109 | 109 | url_proxy_options(); |
| 110 | 110 | if( g.argc < 4 ){ |
| 111 | 111 | usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY"); |
| 112 | 112 | } |
| 113 | 113 | db_open_config(0); |
| @@ -162,11 +162,11 @@ | ||
| 162 | 162 | " VALUES('server-code', lower(hex(randomblob(20))), now());" |
| 163 | 163 | ); |
| 164 | 164 | url_enable_proxy(0); |
| 165 | 165 | url_get_password_if_needed(); |
| 166 | 166 | g.xlinkClusterOnly = 1; |
| 167 | - nErr = client_sync(0,0,1,bPrivate,CONFIGSET_ALL,0); | |
| 167 | + nErr = client_sync(SYNC_CLONE | bPrivate,CONFIGSET_ALL,0); | |
| 168 | 168 | g.xlinkClusterOnly = 0; |
| 169 | 169 | verify_cancel(); |
| 170 | 170 | db_end_transaction(0); |
| 171 | 171 | db_close(1); |
| 172 | 172 | if( nErr ){ |
| 173 | 173 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -99,15 +99,15 @@ | |
| 99 | ** See also: init |
| 100 | */ |
| 101 | void clone_cmd(void){ |
| 102 | char *zPassword; |
| 103 | const char *zDefaultUser; /* Optional name of the default user */ |
| 104 | const char *zPw; /* The user clone password */ |
| 105 | int nErr = 0; |
| 106 | int bPrivate; /* Also clone private branches */ |
| 107 | |
| 108 | bPrivate = find_option("private",0,0)!=0; |
| 109 | url_proxy_options(); |
| 110 | if( g.argc < 4 ){ |
| 111 | usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY"); |
| 112 | } |
| 113 | db_open_config(0); |
| @@ -162,11 +162,11 @@ | |
| 162 | " VALUES('server-code', lower(hex(randomblob(20))), now());" |
| 163 | ); |
| 164 | url_enable_proxy(0); |
| 165 | url_get_password_if_needed(); |
| 166 | g.xlinkClusterOnly = 1; |
| 167 | nErr = client_sync(0,0,1,bPrivate,CONFIGSET_ALL,0); |
| 168 | g.xlinkClusterOnly = 0; |
| 169 | verify_cancel(); |
| 170 | db_end_transaction(0); |
| 171 | db_close(1); |
| 172 | if( nErr ){ |
| 173 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -99,15 +99,15 @@ | |
| 99 | ** See also: init |
| 100 | */ |
| 101 | void clone_cmd(void){ |
| 102 | char *zPassword; |
| 103 | const char *zDefaultUser; /* Optional name of the default user */ |
| 104 | const char *zPw; /* The user clone password */ |
| 105 | int nErr = 0; |
| 106 | int bPrivate = 0; /* Also clone private branches */ |
| 107 | |
| 108 | if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE; |
| 109 | url_proxy_options(); |
| 110 | if( g.argc < 4 ){ |
| 111 | usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY"); |
| 112 | } |
| 113 | db_open_config(0); |
| @@ -162,11 +162,11 @@ | |
| 162 | " VALUES('server-code', lower(hex(randomblob(20))), now());" |
| 163 | ); |
| 164 | url_enable_proxy(0); |
| 165 | url_get_password_if_needed(); |
| 166 | g.xlinkClusterOnly = 1; |
| 167 | nErr = client_sync(SYNC_CLONE | bPrivate,CONFIGSET_ALL,0); |
| 168 | g.xlinkClusterOnly = 0; |
| 169 | verify_cancel(); |
| 170 | db_end_transaction(0); |
| 171 | db_close(1); |
| 172 | if( nErr ){ |
| 173 |
+3
-3
| --- src/configure.c | ||
| +++ src/configure.c | ||
| @@ -907,15 +907,15 @@ | ||
| 907 | 907 | user_select(); |
| 908 | 908 | url_enable_proxy("via proxy: "); |
| 909 | 909 | if( legacyFlag ) mask |= CONFIGSET_OLDFORMAT; |
| 910 | 910 | if( overwriteFlag ) mask |= CONFIGSET_OVERWRITE; |
| 911 | 911 | if( strncmp(zMethod, "push", n)==0 ){ |
| 912 | - client_sync(0,0,0,0,0,mask); | |
| 912 | + client_sync(0,0,(unsigned)mask); | |
| 913 | 913 | }else if( strncmp(zMethod, "pull", n)==0 ){ |
| 914 | - client_sync(0,0,0,0,mask,0); | |
| 914 | + client_sync(0,(unsigned)mask,0); | |
| 915 | 915 | }else{ |
| 916 | - client_sync(0,0,0,0,mask,mask); | |
| 916 | + client_sync(0,(unsigned)mask,(unsigned)mask); | |
| 917 | 917 | } |
| 918 | 918 | }else |
| 919 | 919 | if( strncmp(zMethod, "reset", n)==0 ){ |
| 920 | 920 | int mask, i; |
| 921 | 921 | char *zBackup; |
| 922 | 922 |
| --- src/configure.c | |
| +++ src/configure.c | |
| @@ -907,15 +907,15 @@ | |
| 907 | user_select(); |
| 908 | url_enable_proxy("via proxy: "); |
| 909 | if( legacyFlag ) mask |= CONFIGSET_OLDFORMAT; |
| 910 | if( overwriteFlag ) mask |= CONFIGSET_OVERWRITE; |
| 911 | if( strncmp(zMethod, "push", n)==0 ){ |
| 912 | client_sync(0,0,0,0,0,mask); |
| 913 | }else if( strncmp(zMethod, "pull", n)==0 ){ |
| 914 | client_sync(0,0,0,0,mask,0); |
| 915 | }else{ |
| 916 | client_sync(0,0,0,0,mask,mask); |
| 917 | } |
| 918 | }else |
| 919 | if( strncmp(zMethod, "reset", n)==0 ){ |
| 920 | int mask, i; |
| 921 | char *zBackup; |
| 922 |
| --- src/configure.c | |
| +++ src/configure.c | |
| @@ -907,15 +907,15 @@ | |
| 907 | user_select(); |
| 908 | url_enable_proxy("via proxy: "); |
| 909 | if( legacyFlag ) mask |= CONFIGSET_OLDFORMAT; |
| 910 | if( overwriteFlag ) mask |= CONFIGSET_OVERWRITE; |
| 911 | if( strncmp(zMethod, "push", n)==0 ){ |
| 912 | client_sync(0,0,(unsigned)mask); |
| 913 | }else if( strncmp(zMethod, "pull", n)==0 ){ |
| 914 | client_sync(0,(unsigned)mask,0); |
| 915 | }else{ |
| 916 | client_sync(0,(unsigned)mask,(unsigned)mask); |
| 917 | } |
| 918 | }else |
| 919 | if( strncmp(zMethod, "reset", n)==0 ){ |
| 920 | int mask, i; |
| 921 | char *zBackup; |
| 922 |
+3
-3
| --- src/configure.c | ||
| +++ src/configure.c | ||
| @@ -907,15 +907,15 @@ | ||
| 907 | 907 | user_select(); |
| 908 | 908 | url_enable_proxy("via proxy: "); |
| 909 | 909 | if( legacyFlag ) mask |= CONFIGSET_OLDFORMAT; |
| 910 | 910 | if( overwriteFlag ) mask |= CONFIGSET_OVERWRITE; |
| 911 | 911 | if( strncmp(zMethod, "push", n)==0 ){ |
| 912 | - client_sync(0,0,0,0,0,mask); | |
| 912 | + client_sync(0,0,(unsigned)mask); | |
| 913 | 913 | }else if( strncmp(zMethod, "pull", n)==0 ){ |
| 914 | - client_sync(0,0,0,0,mask,0); | |
| 914 | + client_sync(0,(unsigned)mask,0); | |
| 915 | 915 | }else{ |
| 916 | - client_sync(0,0,0,0,mask,mask); | |
| 916 | + client_sync(0,(unsigned)mask,(unsigned)mask); | |
| 917 | 917 | } |
| 918 | 918 | }else |
| 919 | 919 | if( strncmp(zMethod, "reset", n)==0 ){ |
| 920 | 920 | int mask, i; |
| 921 | 921 | char *zBackup; |
| 922 | 922 |
| --- src/configure.c | |
| +++ src/configure.c | |
| @@ -907,15 +907,15 @@ | |
| 907 | user_select(); |
| 908 | url_enable_proxy("via proxy: "); |
| 909 | if( legacyFlag ) mask |= CONFIGSET_OLDFORMAT; |
| 910 | if( overwriteFlag ) mask |= CONFIGSET_OVERWRITE; |
| 911 | if( strncmp(zMethod, "push", n)==0 ){ |
| 912 | client_sync(0,0,0,0,0,mask); |
| 913 | }else if( strncmp(zMethod, "pull", n)==0 ){ |
| 914 | client_sync(0,0,0,0,mask,0); |
| 915 | }else{ |
| 916 | client_sync(0,0,0,0,mask,mask); |
| 917 | } |
| 918 | }else |
| 919 | if( strncmp(zMethod, "reset", n)==0 ){ |
| 920 | int mask, i; |
| 921 | char *zBackup; |
| 922 |
| --- src/configure.c | |
| +++ src/configure.c | |
| @@ -907,15 +907,15 @@ | |
| 907 | user_select(); |
| 908 | url_enable_proxy("via proxy: "); |
| 909 | if( legacyFlag ) mask |= CONFIGSET_OLDFORMAT; |
| 910 | if( overwriteFlag ) mask |= CONFIGSET_OVERWRITE; |
| 911 | if( strncmp(zMethod, "push", n)==0 ){ |
| 912 | client_sync(0,0,(unsigned)mask); |
| 913 | }else if( strncmp(zMethod, "pull", n)==0 ){ |
| 914 | client_sync(0,(unsigned)mask,0); |
| 915 | }else{ |
| 916 | client_sync(0,(unsigned)mask,(unsigned)mask); |
| 917 | } |
| 918 | }else |
| 919 | if( strncmp(zMethod, "reset", n)==0 ){ |
| 920 | int mask, i; |
| 921 | char *zBackup; |
| 922 |
+3
-3
| --- src/configure.c | ||
| +++ src/configure.c | ||
| @@ -907,15 +907,15 @@ | ||
| 907 | 907 | user_select(); |
| 908 | 908 | url_enable_proxy("via proxy: "); |
| 909 | 909 | if( legacyFlag ) mask |= CONFIGSET_OLDFORMAT; |
| 910 | 910 | if( overwriteFlag ) mask |= CONFIGSET_OVERWRITE; |
| 911 | 911 | if( strncmp(zMethod, "push", n)==0 ){ |
| 912 | - client_sync(0,0,0,0,0,mask); | |
| 912 | + client_sync(0,0,(unsigned)mask); | |
| 913 | 913 | }else if( strncmp(zMethod, "pull", n)==0 ){ |
| 914 | - client_sync(0,0,0,0,mask,0); | |
| 914 | + client_sync(0,(unsigned)mask,0); | |
| 915 | 915 | }else{ |
| 916 | - client_sync(0,0,0,0,mask,mask); | |
| 916 | + client_sync(0,(unsigned)mask,(unsigned)mask); | |
| 917 | 917 | } |
| 918 | 918 | }else |
| 919 | 919 | if( strncmp(zMethod, "reset", n)==0 ){ |
| 920 | 920 | int mask, i; |
| 921 | 921 | char *zBackup; |
| 922 | 922 |
| --- src/configure.c | |
| +++ src/configure.c | |
| @@ -907,15 +907,15 @@ | |
| 907 | user_select(); |
| 908 | url_enable_proxy("via proxy: "); |
| 909 | if( legacyFlag ) mask |= CONFIGSET_OLDFORMAT; |
| 910 | if( overwriteFlag ) mask |= CONFIGSET_OVERWRITE; |
| 911 | if( strncmp(zMethod, "push", n)==0 ){ |
| 912 | client_sync(0,0,0,0,0,mask); |
| 913 | }else if( strncmp(zMethod, "pull", n)==0 ){ |
| 914 | client_sync(0,0,0,0,mask,0); |
| 915 | }else{ |
| 916 | client_sync(0,0,0,0,mask,mask); |
| 917 | } |
| 918 | }else |
| 919 | if( strncmp(zMethod, "reset", n)==0 ){ |
| 920 | int mask, i; |
| 921 | char *zBackup; |
| 922 |
| --- src/configure.c | |
| +++ src/configure.c | |
| @@ -907,15 +907,15 @@ | |
| 907 | user_select(); |
| 908 | url_enable_proxy("via proxy: "); |
| 909 | if( legacyFlag ) mask |= CONFIGSET_OLDFORMAT; |
| 910 | if( overwriteFlag ) mask |= CONFIGSET_OVERWRITE; |
| 911 | if( strncmp(zMethod, "push", n)==0 ){ |
| 912 | client_sync(0,0,(unsigned)mask); |
| 913 | }else if( strncmp(zMethod, "pull", n)==0 ){ |
| 914 | client_sync(0,(unsigned)mask,0); |
| 915 | }else{ |
| 916 | client_sync(0,(unsigned)mask,(unsigned)mask); |
| 917 | } |
| 918 | }else |
| 919 | if( strncmp(zMethod, "reset", n)==0 ){ |
| 920 | int mask, i; |
| 921 | char *zBackup; |
| 922 |
+1
-1
| --- src/json_branch.c | ||
| +++ src/json_branch.c | ||
| @@ -305,11 +305,11 @@ | ||
| 305 | 305 | /* Commit */ |
| 306 | 306 | db_end_transaction(0); |
| 307 | 307 | |
| 308 | 308 | #if 0 /* Do an autosync push, if requested */ |
| 309 | 309 | /* arugable for JSON mode? */ |
| 310 | - if( !g.isHTTP && !isPrivate ) autosync(AUTOSYNC_PUSH); | |
| 310 | + if( !g.isHTTP && !isPrivate ) autosync(SYNC_PUSH); | |
| 311 | 311 | #endif |
| 312 | 312 | return 0; |
| 313 | 313 | } |
| 314 | 314 | |
| 315 | 315 | |
| 316 | 316 |
| --- src/json_branch.c | |
| +++ src/json_branch.c | |
| @@ -305,11 +305,11 @@ | |
| 305 | /* Commit */ |
| 306 | db_end_transaction(0); |
| 307 | |
| 308 | #if 0 /* Do an autosync push, if requested */ |
| 309 | /* arugable for JSON mode? */ |
| 310 | if( !g.isHTTP && !isPrivate ) autosync(AUTOSYNC_PUSH); |
| 311 | #endif |
| 312 | return 0; |
| 313 | } |
| 314 | |
| 315 | |
| 316 |
| --- src/json_branch.c | |
| +++ src/json_branch.c | |
| @@ -305,11 +305,11 @@ | |
| 305 | /* Commit */ |
| 306 | db_end_transaction(0); |
| 307 | |
| 308 | #if 0 /* Do an autosync push, if requested */ |
| 309 | /* arugable for JSON mode? */ |
| 310 | if( !g.isHTTP && !isPrivate ) autosync(SYNC_PUSH); |
| 311 | #endif |
| 312 | return 0; |
| 313 | } |
| 314 | |
| 315 | |
| 316 |
+1
-1
| --- src/json_branch.c | ||
| +++ src/json_branch.c | ||
| @@ -305,11 +305,11 @@ | ||
| 305 | 305 | /* Commit */ |
| 306 | 306 | db_end_transaction(0); |
| 307 | 307 | |
| 308 | 308 | #if 0 /* Do an autosync push, if requested */ |
| 309 | 309 | /* arugable for JSON mode? */ |
| 310 | - if( !g.isHTTP && !isPrivate ) autosync(AUTOSYNC_PUSH); | |
| 310 | + if( !g.isHTTP && !isPrivate ) autosync(SYNC_PUSH); | |
| 311 | 311 | #endif |
| 312 | 312 | return 0; |
| 313 | 313 | } |
| 314 | 314 | |
| 315 | 315 | |
| 316 | 316 |
| --- src/json_branch.c | |
| +++ src/json_branch.c | |
| @@ -305,11 +305,11 @@ | |
| 305 | /* Commit */ |
| 306 | db_end_transaction(0); |
| 307 | |
| 308 | #if 0 /* Do an autosync push, if requested */ |
| 309 | /* arugable for JSON mode? */ |
| 310 | if( !g.isHTTP && !isPrivate ) autosync(AUTOSYNC_PUSH); |
| 311 | #endif |
| 312 | return 0; |
| 313 | } |
| 314 | |
| 315 | |
| 316 |
| --- src/json_branch.c | |
| +++ src/json_branch.c | |
| @@ -305,11 +305,11 @@ | |
| 305 | /* Commit */ |
| 306 | db_end_transaction(0); |
| 307 | |
| 308 | #if 0 /* Do an autosync push, if requested */ |
| 309 | /* arugable for JSON mode? */ |
| 310 | if( !g.isHTTP && !isPrivate ) autosync(SYNC_PUSH); |
| 311 | #endif |
| 312 | return 0; |
| 313 | } |
| 314 | |
| 315 | |
| 316 |
+34
-32
| --- src/sync.c | ||
| +++ src/sync.c | ||
| @@ -19,19 +19,10 @@ | ||
| 19 | 19 | */ |
| 20 | 20 | #include "config.h" |
| 21 | 21 | #include "sync.h" |
| 22 | 22 | #include <assert.h> |
| 23 | 23 | |
| 24 | -#if INTERFACE | |
| 25 | -/* | |
| 26 | -** Flags used to determine which direction(s) an autosync goes in. | |
| 27 | -*/ | |
| 28 | -#define AUTOSYNC_PUSH 1 | |
| 29 | -#define AUTOSYNC_PULL 2 | |
| 30 | - | |
| 31 | -#endif /* INTERFACE */ | |
| 32 | - | |
| 33 | 24 | /* |
| 34 | 25 | ** If the repository is configured for autosyncing, then do an |
| 35 | 26 | ** autosync. This will be a pull if the argument is true or a push |
| 36 | 27 | ** if the argument is false. |
| 37 | 28 | ** |
| @@ -44,16 +35,16 @@ | ||
| 44 | 35 | int rc; |
| 45 | 36 | int configSync = 0; /* configuration changes transferred */ |
| 46 | 37 | if( g.fNoSync ){ |
| 47 | 38 | return 0; |
| 48 | 39 | } |
| 49 | - if( flags==AUTOSYNC_PUSH && db_get_boolean("dont-push",0) ){ | |
| 40 | + if( flags==SYNC_PUSH && db_get_boolean("dont-push",0) ){ | |
| 50 | 41 | return 0; |
| 51 | 42 | } |
| 52 | 43 | zAutosync = db_get("autosync", 0); |
| 53 | 44 | if( zAutosync ){ |
| 54 | - if( (flags & AUTOSYNC_PUSH)!=0 && memcmp(zAutosync,"pull",4)==0 ){ | |
| 45 | + if( (flags & SYNC_PUSH)!=0 && memcmp(zAutosync,"pull",4)==0 ){ | |
| 55 | 46 | return 0; /* Do not auto-push when autosync=pullonly */ |
| 56 | 47 | } |
| 57 | 48 | if( is_false(zAutosync) ){ |
| 58 | 49 | return 0; /* Autosync is completely off */ |
| 59 | 50 | } |
| @@ -79,13 +70,14 @@ | ||
| 79 | 70 | ** autosync, or something? |
| 80 | 71 | */ |
| 81 | 72 | configSync = CONFIGSET_SHUN; |
| 82 | 73 | } |
| 83 | 74 | #endif |
| 75 | + if( find_option("verbose","v",0)!=0 ) flags |= SYNC_VERBOSE; | |
| 84 | 76 | fossil_print("Autosync: %s\n", g.urlCanonical); |
| 85 | 77 | url_enable_proxy("via proxy: "); |
| 86 | - rc = client_sync((flags & AUTOSYNC_PUSH)!=0, 1, 0, 0, configSync, 0); | |
| 78 | + rc = client_sync(flags, configSync, 0); | |
| 87 | 79 | if( rc ) fossil_warning("Autosync failed"); |
| 88 | 80 | return rc; |
| 89 | 81 | } |
| 90 | 82 | |
| 91 | 83 | /* |
| @@ -92,17 +84,22 @@ | ||
| 92 | 84 | ** This routine processes the command-line argument for push, pull, |
| 93 | 85 | ** and sync. If a command-line argument is given, that is the URL |
| 94 | 86 | ** of a server to sync against. If no argument is given, use the |
| 95 | 87 | ** most recently synced URL. Remember the current URL for next time. |
| 96 | 88 | */ |
| 97 | -static void process_sync_args(int *pConfigSync, int *pPrivate){ | |
| 89 | +static void process_sync_args(unsigned *pConfigFlags, unsigned *pSyncFlags){ | |
| 98 | 90 | const char *zUrl = 0; |
| 99 | 91 | const char *zPw = 0; |
| 100 | - int configSync = 0; | |
| 92 | + unsigned configSync = 0; | |
| 101 | 93 | int urlOptional = find_option("autourl",0,0)!=0; |
| 102 | 94 | g.dontKeepUrl = find_option("once",0,0)!=0; |
| 103 | - *pPrivate = find_option("private",0,0)!=0; | |
| 95 | + if( find_option("private",0,0)!=0 ){ | |
| 96 | + *pSyncFlags |= SYNC_PRIVATE; | |
| 97 | + } | |
| 98 | + if( find_option("verbose","v",0)!=0 ){ | |
| 99 | + *pSyncFlags |= SYNC_VERBOSE; | |
| 100 | + } | |
| 104 | 101 | url_proxy_options(); |
| 105 | 102 | db_find_and_open_repository(0, 0); |
| 106 | 103 | db_open_config(0); |
| 107 | 104 | if( g.argc==2 ){ |
| 108 | 105 | zUrl = db_get("last-sync-url", 0); |
| @@ -127,14 +124,20 @@ | ||
| 127 | 124 | db_set("last-sync-url", g.urlCanonical, 0); |
| 128 | 125 | if( g.urlPasswd ) db_set("last-sync-pw", obscure(g.urlPasswd), 0); |
| 129 | 126 | } |
| 130 | 127 | user_select(); |
| 131 | 128 | if( g.argc==2 ){ |
| 132 | - fossil_print("Server: %s\n", g.urlCanonical); | |
| 129 | + if( ((*pSyncFlags) & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL) ){ | |
| 130 | + fossil_print("Sync with %s\n", g.urlCanonical); | |
| 131 | + }else if( (*pSyncFlags) & SYNC_PUSH ){ | |
| 132 | + fossil_print("Push to %s\n", g.urlCanonical); | |
| 133 | + }else if( (*pSyncFlags) & SYNC_PULL ){ | |
| 134 | + fossil_print("Pull from %s\n", g.urlCanonical); | |
| 135 | + } | |
| 133 | 136 | } |
| 134 | 137 | url_enable_proxy("via proxy: "); |
| 135 | - *pConfigSync = configSync; | |
| 138 | + *pConfigFlags |= configSync; | |
| 136 | 139 | } |
| 137 | 140 | |
| 138 | 141 | /* |
| 139 | 142 | ** COMMAND: pull |
| 140 | 143 | ** |
| @@ -156,14 +159,14 @@ | ||
| 156 | 159 | ** remote repository. |
| 157 | 160 | ** |
| 158 | 161 | ** See also: clone, push, sync, remote-url |
| 159 | 162 | */ |
| 160 | 163 | void pull_cmd(void){ |
| 161 | - int syncFlags; | |
| 162 | - int bPrivate; | |
| 163 | - process_sync_args(&syncFlags, &bPrivate); | |
| 164 | - client_sync(0,1,0,bPrivate,syncFlags,0); | |
| 164 | + unsigned configFlags = 0; | |
| 165 | + unsigned syncFlags = SYNC_PULL; | |
| 166 | + process_sync_args(&configFlags, &syncFlags); | |
| 167 | + client_sync(syncFlags, configFlags, 0); | |
| 165 | 168 | } |
| 166 | 169 | |
| 167 | 170 | /* |
| 168 | 171 | ** COMMAND: push |
| 169 | 172 | ** |
| @@ -185,17 +188,17 @@ | ||
| 185 | 188 | ** remote repository. |
| 186 | 189 | ** |
| 187 | 190 | ** See also: clone, pull, sync, remote-url |
| 188 | 191 | */ |
| 189 | 192 | void push_cmd(void){ |
| 190 | - int syncFlags; | |
| 191 | - int bPrivate; | |
| 192 | - process_sync_args(&syncFlags, &bPrivate); | |
| 193 | + unsigned configFlags = 0; | |
| 194 | + unsigned syncFlags = SYNC_PUSH; | |
| 195 | + process_sync_args(&configFlags, &syncFlags); | |
| 193 | 196 | if( db_get_boolean("dont-push",0) ){ |
| 194 | 197 | fossil_fatal("pushing is prohibited: the 'dont-push' option is set"); |
| 195 | 198 | } |
| 196 | - client_sync(1,0,0,bPrivate,0,0); | |
| 199 | + client_sync(syncFlags, 0, 0); | |
| 197 | 200 | } |
| 198 | 201 | |
| 199 | 202 | |
| 200 | 203 | /* |
| 201 | 204 | ** COMMAND: sync |
| @@ -223,17 +226,16 @@ | ||
| 223 | 226 | ** remote repository. |
| 224 | 227 | ** |
| 225 | 228 | ** See also: clone, push, pull, remote-url |
| 226 | 229 | */ |
| 227 | 230 | void sync_cmd(void){ |
| 228 | - int syncFlags; | |
| 229 | - int bPrivate; | |
| 230 | - int pushFlag = 1; | |
| 231 | - process_sync_args(&syncFlags, &bPrivate); | |
| 232 | - if( db_get_boolean("dont-push",0) ) pushFlag = 0; | |
| 233 | - client_sync(pushFlag,1,0,bPrivate,syncFlags,0); | |
| 234 | - if( pushFlag==0 ){ | |
| 231 | + unsigned configFlags = 0; | |
| 232 | + unsigned syncFlags = SYNC_PUSH|SYNC_PULL; | |
| 233 | + process_sync_args(&configFlags, &syncFlags); | |
| 234 | + if( db_get_boolean("dont-push",0) ) syncFlags &= ~SYNC_PUSH; | |
| 235 | + client_sync(syncFlags, configFlags, 0); | |
| 236 | + if( (syncFlags & SYNC_PUSH)==0 ){ | |
| 235 | 237 | fossil_warning("pull only: the 'dont-push' option is set"); |
| 236 | 238 | } |
| 237 | 239 | } |
| 238 | 240 | |
| 239 | 241 | /* |
| 240 | 242 |
| --- src/sync.c | |
| +++ src/sync.c | |
| @@ -19,19 +19,10 @@ | |
| 19 | */ |
| 20 | #include "config.h" |
| 21 | #include "sync.h" |
| 22 | #include <assert.h> |
| 23 | |
| 24 | #if INTERFACE |
| 25 | /* |
| 26 | ** Flags used to determine which direction(s) an autosync goes in. |
| 27 | */ |
| 28 | #define AUTOSYNC_PUSH 1 |
| 29 | #define AUTOSYNC_PULL 2 |
| 30 | |
| 31 | #endif /* INTERFACE */ |
| 32 | |
| 33 | /* |
| 34 | ** If the repository is configured for autosyncing, then do an |
| 35 | ** autosync. This will be a pull if the argument is true or a push |
| 36 | ** if the argument is false. |
| 37 | ** |
| @@ -44,16 +35,16 @@ | |
| 44 | int rc; |
| 45 | int configSync = 0; /* configuration changes transferred */ |
| 46 | if( g.fNoSync ){ |
| 47 | return 0; |
| 48 | } |
| 49 | if( flags==AUTOSYNC_PUSH && db_get_boolean("dont-push",0) ){ |
| 50 | return 0; |
| 51 | } |
| 52 | zAutosync = db_get("autosync", 0); |
| 53 | if( zAutosync ){ |
| 54 | if( (flags & AUTOSYNC_PUSH)!=0 && memcmp(zAutosync,"pull",4)==0 ){ |
| 55 | return 0; /* Do not auto-push when autosync=pullonly */ |
| 56 | } |
| 57 | if( is_false(zAutosync) ){ |
| 58 | return 0; /* Autosync is completely off */ |
| 59 | } |
| @@ -79,13 +70,14 @@ | |
| 79 | ** autosync, or something? |
| 80 | */ |
| 81 | configSync = CONFIGSET_SHUN; |
| 82 | } |
| 83 | #endif |
| 84 | fossil_print("Autosync: %s\n", g.urlCanonical); |
| 85 | url_enable_proxy("via proxy: "); |
| 86 | rc = client_sync((flags & AUTOSYNC_PUSH)!=0, 1, 0, 0, configSync, 0); |
| 87 | if( rc ) fossil_warning("Autosync failed"); |
| 88 | return rc; |
| 89 | } |
| 90 | |
| 91 | /* |
| @@ -92,17 +84,22 @@ | |
| 92 | ** This routine processes the command-line argument for push, pull, |
| 93 | ** and sync. If a command-line argument is given, that is the URL |
| 94 | ** of a server to sync against. If no argument is given, use the |
| 95 | ** most recently synced URL. Remember the current URL for next time. |
| 96 | */ |
| 97 | static void process_sync_args(int *pConfigSync, int *pPrivate){ |
| 98 | const char *zUrl = 0; |
| 99 | const char *zPw = 0; |
| 100 | int configSync = 0; |
| 101 | int urlOptional = find_option("autourl",0,0)!=0; |
| 102 | g.dontKeepUrl = find_option("once",0,0)!=0; |
| 103 | *pPrivate = find_option("private",0,0)!=0; |
| 104 | url_proxy_options(); |
| 105 | db_find_and_open_repository(0, 0); |
| 106 | db_open_config(0); |
| 107 | if( g.argc==2 ){ |
| 108 | zUrl = db_get("last-sync-url", 0); |
| @@ -127,14 +124,20 @@ | |
| 127 | db_set("last-sync-url", g.urlCanonical, 0); |
| 128 | if( g.urlPasswd ) db_set("last-sync-pw", obscure(g.urlPasswd), 0); |
| 129 | } |
| 130 | user_select(); |
| 131 | if( g.argc==2 ){ |
| 132 | fossil_print("Server: %s\n", g.urlCanonical); |
| 133 | } |
| 134 | url_enable_proxy("via proxy: "); |
| 135 | *pConfigSync = configSync; |
| 136 | } |
| 137 | |
| 138 | /* |
| 139 | ** COMMAND: pull |
| 140 | ** |
| @@ -156,14 +159,14 @@ | |
| 156 | ** remote repository. |
| 157 | ** |
| 158 | ** See also: clone, push, sync, remote-url |
| 159 | */ |
| 160 | void pull_cmd(void){ |
| 161 | int syncFlags; |
| 162 | int bPrivate; |
| 163 | process_sync_args(&syncFlags, &bPrivate); |
| 164 | client_sync(0,1,0,bPrivate,syncFlags,0); |
| 165 | } |
| 166 | |
| 167 | /* |
| 168 | ** COMMAND: push |
| 169 | ** |
| @@ -185,17 +188,17 @@ | |
| 185 | ** remote repository. |
| 186 | ** |
| 187 | ** See also: clone, pull, sync, remote-url |
| 188 | */ |
| 189 | void push_cmd(void){ |
| 190 | int syncFlags; |
| 191 | int bPrivate; |
| 192 | process_sync_args(&syncFlags, &bPrivate); |
| 193 | if( db_get_boolean("dont-push",0) ){ |
| 194 | fossil_fatal("pushing is prohibited: the 'dont-push' option is set"); |
| 195 | } |
| 196 | client_sync(1,0,0,bPrivate,0,0); |
| 197 | } |
| 198 | |
| 199 | |
| 200 | /* |
| 201 | ** COMMAND: sync |
| @@ -223,17 +226,16 @@ | |
| 223 | ** remote repository. |
| 224 | ** |
| 225 | ** See also: clone, push, pull, remote-url |
| 226 | */ |
| 227 | void sync_cmd(void){ |
| 228 | int syncFlags; |
| 229 | int bPrivate; |
| 230 | int pushFlag = 1; |
| 231 | process_sync_args(&syncFlags, &bPrivate); |
| 232 | if( db_get_boolean("dont-push",0) ) pushFlag = 0; |
| 233 | client_sync(pushFlag,1,0,bPrivate,syncFlags,0); |
| 234 | if( pushFlag==0 ){ |
| 235 | fossil_warning("pull only: the 'dont-push' option is set"); |
| 236 | } |
| 237 | } |
| 238 | |
| 239 | /* |
| 240 |
| --- src/sync.c | |
| +++ src/sync.c | |
| @@ -19,19 +19,10 @@ | |
| 19 | */ |
| 20 | #include "config.h" |
| 21 | #include "sync.h" |
| 22 | #include <assert.h> |
| 23 | |
| 24 | /* |
| 25 | ** If the repository is configured for autosyncing, then do an |
| 26 | ** autosync. This will be a pull if the argument is true or a push |
| 27 | ** if the argument is false. |
| 28 | ** |
| @@ -44,16 +35,16 @@ | |
| 35 | int rc; |
| 36 | int configSync = 0; /* configuration changes transferred */ |
| 37 | if( g.fNoSync ){ |
| 38 | return 0; |
| 39 | } |
| 40 | if( flags==SYNC_PUSH && db_get_boolean("dont-push",0) ){ |
| 41 | return 0; |
| 42 | } |
| 43 | zAutosync = db_get("autosync", 0); |
| 44 | if( zAutosync ){ |
| 45 | if( (flags & SYNC_PUSH)!=0 && memcmp(zAutosync,"pull",4)==0 ){ |
| 46 | return 0; /* Do not auto-push when autosync=pullonly */ |
| 47 | } |
| 48 | if( is_false(zAutosync) ){ |
| 49 | return 0; /* Autosync is completely off */ |
| 50 | } |
| @@ -79,13 +70,14 @@ | |
| 70 | ** autosync, or something? |
| 71 | */ |
| 72 | configSync = CONFIGSET_SHUN; |
| 73 | } |
| 74 | #endif |
| 75 | if( find_option("verbose","v",0)!=0 ) flags |= SYNC_VERBOSE; |
| 76 | fossil_print("Autosync: %s\n", g.urlCanonical); |
| 77 | url_enable_proxy("via proxy: "); |
| 78 | rc = client_sync(flags, configSync, 0); |
| 79 | if( rc ) fossil_warning("Autosync failed"); |
| 80 | return rc; |
| 81 | } |
| 82 | |
| 83 | /* |
| @@ -92,17 +84,22 @@ | |
| 84 | ** This routine processes the command-line argument for push, pull, |
| 85 | ** and sync. If a command-line argument is given, that is the URL |
| 86 | ** of a server to sync against. If no argument is given, use the |
| 87 | ** most recently synced URL. Remember the current URL for next time. |
| 88 | */ |
| 89 | static void process_sync_args(unsigned *pConfigFlags, unsigned *pSyncFlags){ |
| 90 | const char *zUrl = 0; |
| 91 | const char *zPw = 0; |
| 92 | unsigned configSync = 0; |
| 93 | int urlOptional = find_option("autourl",0,0)!=0; |
| 94 | g.dontKeepUrl = find_option("once",0,0)!=0; |
| 95 | if( find_option("private",0,0)!=0 ){ |
| 96 | *pSyncFlags |= SYNC_PRIVATE; |
| 97 | } |
| 98 | if( find_option("verbose","v",0)!=0 ){ |
| 99 | *pSyncFlags |= SYNC_VERBOSE; |
| 100 | } |
| 101 | url_proxy_options(); |
| 102 | db_find_and_open_repository(0, 0); |
| 103 | db_open_config(0); |
| 104 | if( g.argc==2 ){ |
| 105 | zUrl = db_get("last-sync-url", 0); |
| @@ -127,14 +124,20 @@ | |
| 124 | db_set("last-sync-url", g.urlCanonical, 0); |
| 125 | if( g.urlPasswd ) db_set("last-sync-pw", obscure(g.urlPasswd), 0); |
| 126 | } |
| 127 | user_select(); |
| 128 | if( g.argc==2 ){ |
| 129 | if( ((*pSyncFlags) & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL) ){ |
| 130 | fossil_print("Sync with %s\n", g.urlCanonical); |
| 131 | }else if( (*pSyncFlags) & SYNC_PUSH ){ |
| 132 | fossil_print("Push to %s\n", g.urlCanonical); |
| 133 | }else if( (*pSyncFlags) & SYNC_PULL ){ |
| 134 | fossil_print("Pull from %s\n", g.urlCanonical); |
| 135 | } |
| 136 | } |
| 137 | url_enable_proxy("via proxy: "); |
| 138 | *pConfigFlags |= configSync; |
| 139 | } |
| 140 | |
| 141 | /* |
| 142 | ** COMMAND: pull |
| 143 | ** |
| @@ -156,14 +159,14 @@ | |
| 159 | ** remote repository. |
| 160 | ** |
| 161 | ** See also: clone, push, sync, remote-url |
| 162 | */ |
| 163 | void pull_cmd(void){ |
| 164 | unsigned configFlags = 0; |
| 165 | unsigned syncFlags = SYNC_PULL; |
| 166 | process_sync_args(&configFlags, &syncFlags); |
| 167 | client_sync(syncFlags, configFlags, 0); |
| 168 | } |
| 169 | |
| 170 | /* |
| 171 | ** COMMAND: push |
| 172 | ** |
| @@ -185,17 +188,17 @@ | |
| 188 | ** remote repository. |
| 189 | ** |
| 190 | ** See also: clone, pull, sync, remote-url |
| 191 | */ |
| 192 | void push_cmd(void){ |
| 193 | unsigned configFlags = 0; |
| 194 | unsigned syncFlags = SYNC_PUSH; |
| 195 | process_sync_args(&configFlags, &syncFlags); |
| 196 | if( db_get_boolean("dont-push",0) ){ |
| 197 | fossil_fatal("pushing is prohibited: the 'dont-push' option is set"); |
| 198 | } |
| 199 | client_sync(syncFlags, 0, 0); |
| 200 | } |
| 201 | |
| 202 | |
| 203 | /* |
| 204 | ** COMMAND: sync |
| @@ -223,17 +226,16 @@ | |
| 226 | ** remote repository. |
| 227 | ** |
| 228 | ** See also: clone, push, pull, remote-url |
| 229 | */ |
| 230 | void sync_cmd(void){ |
| 231 | unsigned configFlags = 0; |
| 232 | unsigned syncFlags = SYNC_PUSH|SYNC_PULL; |
| 233 | process_sync_args(&configFlags, &syncFlags); |
| 234 | if( db_get_boolean("dont-push",0) ) syncFlags &= ~SYNC_PUSH; |
| 235 | client_sync(syncFlags, configFlags, 0); |
| 236 | if( (syncFlags & SYNC_PUSH)==0 ){ |
| 237 | fossil_warning("pull only: the 'dont-push' option is set"); |
| 238 | } |
| 239 | } |
| 240 | |
| 241 | /* |
| 242 |
+34
-32
| --- src/sync.c | ||
| +++ src/sync.c | ||
| @@ -19,19 +19,10 @@ | ||
| 19 | 19 | */ |
| 20 | 20 | #include "config.h" |
| 21 | 21 | #include "sync.h" |
| 22 | 22 | #include <assert.h> |
| 23 | 23 | |
| 24 | -#if INTERFACE | |
| 25 | -/* | |
| 26 | -** Flags used to determine which direction(s) an autosync goes in. | |
| 27 | -*/ | |
| 28 | -#define AUTOSYNC_PUSH 1 | |
| 29 | -#define AUTOSYNC_PULL 2 | |
| 30 | - | |
| 31 | -#endif /* INTERFACE */ | |
| 32 | - | |
| 33 | 24 | /* |
| 34 | 25 | ** If the repository is configured for autosyncing, then do an |
| 35 | 26 | ** autosync. This will be a pull if the argument is true or a push |
| 36 | 27 | ** if the argument is false. |
| 37 | 28 | ** |
| @@ -44,16 +35,16 @@ | ||
| 44 | 35 | int rc; |
| 45 | 36 | int configSync = 0; /* configuration changes transferred */ |
| 46 | 37 | if( g.fNoSync ){ |
| 47 | 38 | return 0; |
| 48 | 39 | } |
| 49 | - if( flags==AUTOSYNC_PUSH && db_get_boolean("dont-push",0) ){ | |
| 40 | + if( flags==SYNC_PUSH && db_get_boolean("dont-push",0) ){ | |
| 50 | 41 | return 0; |
| 51 | 42 | } |
| 52 | 43 | zAutosync = db_get("autosync", 0); |
| 53 | 44 | if( zAutosync ){ |
| 54 | - if( (flags & AUTOSYNC_PUSH)!=0 && memcmp(zAutosync,"pull",4)==0 ){ | |
| 45 | + if( (flags & SYNC_PUSH)!=0 && memcmp(zAutosync,"pull",4)==0 ){ | |
| 55 | 46 | return 0; /* Do not auto-push when autosync=pullonly */ |
| 56 | 47 | } |
| 57 | 48 | if( is_false(zAutosync) ){ |
| 58 | 49 | return 0; /* Autosync is completely off */ |
| 59 | 50 | } |
| @@ -79,13 +70,14 @@ | ||
| 79 | 70 | ** autosync, or something? |
| 80 | 71 | */ |
| 81 | 72 | configSync = CONFIGSET_SHUN; |
| 82 | 73 | } |
| 83 | 74 | #endif |
| 75 | + if( find_option("verbose","v",0)!=0 ) flags |= SYNC_VERBOSE; | |
| 84 | 76 | fossil_print("Autosync: %s\n", g.urlCanonical); |
| 85 | 77 | url_enable_proxy("via proxy: "); |
| 86 | - rc = client_sync((flags & AUTOSYNC_PUSH)!=0, 1, 0, 0, configSync, 0); | |
| 78 | + rc = client_sync(flags, configSync, 0); | |
| 87 | 79 | if( rc ) fossil_warning("Autosync failed"); |
| 88 | 80 | return rc; |
| 89 | 81 | } |
| 90 | 82 | |
| 91 | 83 | /* |
| @@ -92,17 +84,22 @@ | ||
| 92 | 84 | ** This routine processes the command-line argument for push, pull, |
| 93 | 85 | ** and sync. If a command-line argument is given, that is the URL |
| 94 | 86 | ** of a server to sync against. If no argument is given, use the |
| 95 | 87 | ** most recently synced URL. Remember the current URL for next time. |
| 96 | 88 | */ |
| 97 | -static void process_sync_args(int *pConfigSync, int *pPrivate){ | |
| 89 | +static void process_sync_args(unsigned *pConfigFlags, unsigned *pSyncFlags){ | |
| 98 | 90 | const char *zUrl = 0; |
| 99 | 91 | const char *zPw = 0; |
| 100 | - int configSync = 0; | |
| 92 | + unsigned configSync = 0; | |
| 101 | 93 | int urlOptional = find_option("autourl",0,0)!=0; |
| 102 | 94 | g.dontKeepUrl = find_option("once",0,0)!=0; |
| 103 | - *pPrivate = find_option("private",0,0)!=0; | |
| 95 | + if( find_option("private",0,0)!=0 ){ | |
| 96 | + *pSyncFlags |= SYNC_PRIVATE; | |
| 97 | + } | |
| 98 | + if( find_option("verbose","v",0)!=0 ){ | |
| 99 | + *pSyncFlags |= SYNC_VERBOSE; | |
| 100 | + } | |
| 104 | 101 | url_proxy_options(); |
| 105 | 102 | db_find_and_open_repository(0, 0); |
| 106 | 103 | db_open_config(0); |
| 107 | 104 | if( g.argc==2 ){ |
| 108 | 105 | zUrl = db_get("last-sync-url", 0); |
| @@ -127,14 +124,20 @@ | ||
| 127 | 124 | db_set("last-sync-url", g.urlCanonical, 0); |
| 128 | 125 | if( g.urlPasswd ) db_set("last-sync-pw", obscure(g.urlPasswd), 0); |
| 129 | 126 | } |
| 130 | 127 | user_select(); |
| 131 | 128 | if( g.argc==2 ){ |
| 132 | - fossil_print("Server: %s\n", g.urlCanonical); | |
| 129 | + if( ((*pSyncFlags) & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL) ){ | |
| 130 | + fossil_print("Sync with %s\n", g.urlCanonical); | |
| 131 | + }else if( (*pSyncFlags) & SYNC_PUSH ){ | |
| 132 | + fossil_print("Push to %s\n", g.urlCanonical); | |
| 133 | + }else if( (*pSyncFlags) & SYNC_PULL ){ | |
| 134 | + fossil_print("Pull from %s\n", g.urlCanonical); | |
| 135 | + } | |
| 133 | 136 | } |
| 134 | 137 | url_enable_proxy("via proxy: "); |
| 135 | - *pConfigSync = configSync; | |
| 138 | + *pConfigFlags |= configSync; | |
| 136 | 139 | } |
| 137 | 140 | |
| 138 | 141 | /* |
| 139 | 142 | ** COMMAND: pull |
| 140 | 143 | ** |
| @@ -156,14 +159,14 @@ | ||
| 156 | 159 | ** remote repository. |
| 157 | 160 | ** |
| 158 | 161 | ** See also: clone, push, sync, remote-url |
| 159 | 162 | */ |
| 160 | 163 | void pull_cmd(void){ |
| 161 | - int syncFlags; | |
| 162 | - int bPrivate; | |
| 163 | - process_sync_args(&syncFlags, &bPrivate); | |
| 164 | - client_sync(0,1,0,bPrivate,syncFlags,0); | |
| 164 | + unsigned configFlags = 0; | |
| 165 | + unsigned syncFlags = SYNC_PULL; | |
| 166 | + process_sync_args(&configFlags, &syncFlags); | |
| 167 | + client_sync(syncFlags, configFlags, 0); | |
| 165 | 168 | } |
| 166 | 169 | |
| 167 | 170 | /* |
| 168 | 171 | ** COMMAND: push |
| 169 | 172 | ** |
| @@ -185,17 +188,17 @@ | ||
| 185 | 188 | ** remote repository. |
| 186 | 189 | ** |
| 187 | 190 | ** See also: clone, pull, sync, remote-url |
| 188 | 191 | */ |
| 189 | 192 | void push_cmd(void){ |
| 190 | - int syncFlags; | |
| 191 | - int bPrivate; | |
| 192 | - process_sync_args(&syncFlags, &bPrivate); | |
| 193 | + unsigned configFlags = 0; | |
| 194 | + unsigned syncFlags = SYNC_PUSH; | |
| 195 | + process_sync_args(&configFlags, &syncFlags); | |
| 193 | 196 | if( db_get_boolean("dont-push",0) ){ |
| 194 | 197 | fossil_fatal("pushing is prohibited: the 'dont-push' option is set"); |
| 195 | 198 | } |
| 196 | - client_sync(1,0,0,bPrivate,0,0); | |
| 199 | + client_sync(syncFlags, 0, 0); | |
| 197 | 200 | } |
| 198 | 201 | |
| 199 | 202 | |
| 200 | 203 | /* |
| 201 | 204 | ** COMMAND: sync |
| @@ -223,17 +226,16 @@ | ||
| 223 | 226 | ** remote repository. |
| 224 | 227 | ** |
| 225 | 228 | ** See also: clone, push, pull, remote-url |
| 226 | 229 | */ |
| 227 | 230 | void sync_cmd(void){ |
| 228 | - int syncFlags; | |
| 229 | - int bPrivate; | |
| 230 | - int pushFlag = 1; | |
| 231 | - process_sync_args(&syncFlags, &bPrivate); | |
| 232 | - if( db_get_boolean("dont-push",0) ) pushFlag = 0; | |
| 233 | - client_sync(pushFlag,1,0,bPrivate,syncFlags,0); | |
| 234 | - if( pushFlag==0 ){ | |
| 231 | + unsigned configFlags = 0; | |
| 232 | + unsigned syncFlags = SYNC_PUSH|SYNC_PULL; | |
| 233 | + process_sync_args(&configFlags, &syncFlags); | |
| 234 | + if( db_get_boolean("dont-push",0) ) syncFlags &= ~SYNC_PUSH; | |
| 235 | + client_sync(syncFlags, configFlags, 0); | |
| 236 | + if( (syncFlags & SYNC_PUSH)==0 ){ | |
| 235 | 237 | fossil_warning("pull only: the 'dont-push' option is set"); |
| 236 | 238 | } |
| 237 | 239 | } |
| 238 | 240 | |
| 239 | 241 | /* |
| 240 | 242 |
| --- src/sync.c | |
| +++ src/sync.c | |
| @@ -19,19 +19,10 @@ | |
| 19 | */ |
| 20 | #include "config.h" |
| 21 | #include "sync.h" |
| 22 | #include <assert.h> |
| 23 | |
| 24 | #if INTERFACE |
| 25 | /* |
| 26 | ** Flags used to determine which direction(s) an autosync goes in. |
| 27 | */ |
| 28 | #define AUTOSYNC_PUSH 1 |
| 29 | #define AUTOSYNC_PULL 2 |
| 30 | |
| 31 | #endif /* INTERFACE */ |
| 32 | |
| 33 | /* |
| 34 | ** If the repository is configured for autosyncing, then do an |
| 35 | ** autosync. This will be a pull if the argument is true or a push |
| 36 | ** if the argument is false. |
| 37 | ** |
| @@ -44,16 +35,16 @@ | |
| 44 | int rc; |
| 45 | int configSync = 0; /* configuration changes transferred */ |
| 46 | if( g.fNoSync ){ |
| 47 | return 0; |
| 48 | } |
| 49 | if( flags==AUTOSYNC_PUSH && db_get_boolean("dont-push",0) ){ |
| 50 | return 0; |
| 51 | } |
| 52 | zAutosync = db_get("autosync", 0); |
| 53 | if( zAutosync ){ |
| 54 | if( (flags & AUTOSYNC_PUSH)!=0 && memcmp(zAutosync,"pull",4)==0 ){ |
| 55 | return 0; /* Do not auto-push when autosync=pullonly */ |
| 56 | } |
| 57 | if( is_false(zAutosync) ){ |
| 58 | return 0; /* Autosync is completely off */ |
| 59 | } |
| @@ -79,13 +70,14 @@ | |
| 79 | ** autosync, or something? |
| 80 | */ |
| 81 | configSync = CONFIGSET_SHUN; |
| 82 | } |
| 83 | #endif |
| 84 | fossil_print("Autosync: %s\n", g.urlCanonical); |
| 85 | url_enable_proxy("via proxy: "); |
| 86 | rc = client_sync((flags & AUTOSYNC_PUSH)!=0, 1, 0, 0, configSync, 0); |
| 87 | if( rc ) fossil_warning("Autosync failed"); |
| 88 | return rc; |
| 89 | } |
| 90 | |
| 91 | /* |
| @@ -92,17 +84,22 @@ | |
| 92 | ** This routine processes the command-line argument for push, pull, |
| 93 | ** and sync. If a command-line argument is given, that is the URL |
| 94 | ** of a server to sync against. If no argument is given, use the |
| 95 | ** most recently synced URL. Remember the current URL for next time. |
| 96 | */ |
| 97 | static void process_sync_args(int *pConfigSync, int *pPrivate){ |
| 98 | const char *zUrl = 0; |
| 99 | const char *zPw = 0; |
| 100 | int configSync = 0; |
| 101 | int urlOptional = find_option("autourl",0,0)!=0; |
| 102 | g.dontKeepUrl = find_option("once",0,0)!=0; |
| 103 | *pPrivate = find_option("private",0,0)!=0; |
| 104 | url_proxy_options(); |
| 105 | db_find_and_open_repository(0, 0); |
| 106 | db_open_config(0); |
| 107 | if( g.argc==2 ){ |
| 108 | zUrl = db_get("last-sync-url", 0); |
| @@ -127,14 +124,20 @@ | |
| 127 | db_set("last-sync-url", g.urlCanonical, 0); |
| 128 | if( g.urlPasswd ) db_set("last-sync-pw", obscure(g.urlPasswd), 0); |
| 129 | } |
| 130 | user_select(); |
| 131 | if( g.argc==2 ){ |
| 132 | fossil_print("Server: %s\n", g.urlCanonical); |
| 133 | } |
| 134 | url_enable_proxy("via proxy: "); |
| 135 | *pConfigSync = configSync; |
| 136 | } |
| 137 | |
| 138 | /* |
| 139 | ** COMMAND: pull |
| 140 | ** |
| @@ -156,14 +159,14 @@ | |
| 156 | ** remote repository. |
| 157 | ** |
| 158 | ** See also: clone, push, sync, remote-url |
| 159 | */ |
| 160 | void pull_cmd(void){ |
| 161 | int syncFlags; |
| 162 | int bPrivate; |
| 163 | process_sync_args(&syncFlags, &bPrivate); |
| 164 | client_sync(0,1,0,bPrivate,syncFlags,0); |
| 165 | } |
| 166 | |
| 167 | /* |
| 168 | ** COMMAND: push |
| 169 | ** |
| @@ -185,17 +188,17 @@ | |
| 185 | ** remote repository. |
| 186 | ** |
| 187 | ** See also: clone, pull, sync, remote-url |
| 188 | */ |
| 189 | void push_cmd(void){ |
| 190 | int syncFlags; |
| 191 | int bPrivate; |
| 192 | process_sync_args(&syncFlags, &bPrivate); |
| 193 | if( db_get_boolean("dont-push",0) ){ |
| 194 | fossil_fatal("pushing is prohibited: the 'dont-push' option is set"); |
| 195 | } |
| 196 | client_sync(1,0,0,bPrivate,0,0); |
| 197 | } |
| 198 | |
| 199 | |
| 200 | /* |
| 201 | ** COMMAND: sync |
| @@ -223,17 +226,16 @@ | |
| 223 | ** remote repository. |
| 224 | ** |
| 225 | ** See also: clone, push, pull, remote-url |
| 226 | */ |
| 227 | void sync_cmd(void){ |
| 228 | int syncFlags; |
| 229 | int bPrivate; |
| 230 | int pushFlag = 1; |
| 231 | process_sync_args(&syncFlags, &bPrivate); |
| 232 | if( db_get_boolean("dont-push",0) ) pushFlag = 0; |
| 233 | client_sync(pushFlag,1,0,bPrivate,syncFlags,0); |
| 234 | if( pushFlag==0 ){ |
| 235 | fossil_warning("pull only: the 'dont-push' option is set"); |
| 236 | } |
| 237 | } |
| 238 | |
| 239 | /* |
| 240 |
| --- src/sync.c | |
| +++ src/sync.c | |
| @@ -19,19 +19,10 @@ | |
| 19 | */ |
| 20 | #include "config.h" |
| 21 | #include "sync.h" |
| 22 | #include <assert.h> |
| 23 | |
| 24 | /* |
| 25 | ** If the repository is configured for autosyncing, then do an |
| 26 | ** autosync. This will be a pull if the argument is true or a push |
| 27 | ** if the argument is false. |
| 28 | ** |
| @@ -44,16 +35,16 @@ | |
| 35 | int rc; |
| 36 | int configSync = 0; /* configuration changes transferred */ |
| 37 | if( g.fNoSync ){ |
| 38 | return 0; |
| 39 | } |
| 40 | if( flags==SYNC_PUSH && db_get_boolean("dont-push",0) ){ |
| 41 | return 0; |
| 42 | } |
| 43 | zAutosync = db_get("autosync", 0); |
| 44 | if( zAutosync ){ |
| 45 | if( (flags & SYNC_PUSH)!=0 && memcmp(zAutosync,"pull",4)==0 ){ |
| 46 | return 0; /* Do not auto-push when autosync=pullonly */ |
| 47 | } |
| 48 | if( is_false(zAutosync) ){ |
| 49 | return 0; /* Autosync is completely off */ |
| 50 | } |
| @@ -79,13 +70,14 @@ | |
| 70 | ** autosync, or something? |
| 71 | */ |
| 72 | configSync = CONFIGSET_SHUN; |
| 73 | } |
| 74 | #endif |
| 75 | if( find_option("verbose","v",0)!=0 ) flags |= SYNC_VERBOSE; |
| 76 | fossil_print("Autosync: %s\n", g.urlCanonical); |
| 77 | url_enable_proxy("via proxy: "); |
| 78 | rc = client_sync(flags, configSync, 0); |
| 79 | if( rc ) fossil_warning("Autosync failed"); |
| 80 | return rc; |
| 81 | } |
| 82 | |
| 83 | /* |
| @@ -92,17 +84,22 @@ | |
| 84 | ** This routine processes the command-line argument for push, pull, |
| 85 | ** and sync. If a command-line argument is given, that is the URL |
| 86 | ** of a server to sync against. If no argument is given, use the |
| 87 | ** most recently synced URL. Remember the current URL for next time. |
| 88 | */ |
| 89 | static void process_sync_args(unsigned *pConfigFlags, unsigned *pSyncFlags){ |
| 90 | const char *zUrl = 0; |
| 91 | const char *zPw = 0; |
| 92 | unsigned configSync = 0; |
| 93 | int urlOptional = find_option("autourl",0,0)!=0; |
| 94 | g.dontKeepUrl = find_option("once",0,0)!=0; |
| 95 | if( find_option("private",0,0)!=0 ){ |
| 96 | *pSyncFlags |= SYNC_PRIVATE; |
| 97 | } |
| 98 | if( find_option("verbose","v",0)!=0 ){ |
| 99 | *pSyncFlags |= SYNC_VERBOSE; |
| 100 | } |
| 101 | url_proxy_options(); |
| 102 | db_find_and_open_repository(0, 0); |
| 103 | db_open_config(0); |
| 104 | if( g.argc==2 ){ |
| 105 | zUrl = db_get("last-sync-url", 0); |
| @@ -127,14 +124,20 @@ | |
| 124 | db_set("last-sync-url", g.urlCanonical, 0); |
| 125 | if( g.urlPasswd ) db_set("last-sync-pw", obscure(g.urlPasswd), 0); |
| 126 | } |
| 127 | user_select(); |
| 128 | if( g.argc==2 ){ |
| 129 | if( ((*pSyncFlags) & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL) ){ |
| 130 | fossil_print("Sync with %s\n", g.urlCanonical); |
| 131 | }else if( (*pSyncFlags) & SYNC_PUSH ){ |
| 132 | fossil_print("Push to %s\n", g.urlCanonical); |
| 133 | }else if( (*pSyncFlags) & SYNC_PULL ){ |
| 134 | fossil_print("Pull from %s\n", g.urlCanonical); |
| 135 | } |
| 136 | } |
| 137 | url_enable_proxy("via proxy: "); |
| 138 | *pConfigFlags |= configSync; |
| 139 | } |
| 140 | |
| 141 | /* |
| 142 | ** COMMAND: pull |
| 143 | ** |
| @@ -156,14 +159,14 @@ | |
| 159 | ** remote repository. |
| 160 | ** |
| 161 | ** See also: clone, push, sync, remote-url |
| 162 | */ |
| 163 | void pull_cmd(void){ |
| 164 | unsigned configFlags = 0; |
| 165 | unsigned syncFlags = SYNC_PULL; |
| 166 | process_sync_args(&configFlags, &syncFlags); |
| 167 | client_sync(syncFlags, configFlags, 0); |
| 168 | } |
| 169 | |
| 170 | /* |
| 171 | ** COMMAND: push |
| 172 | ** |
| @@ -185,17 +188,17 @@ | |
| 188 | ** remote repository. |
| 189 | ** |
| 190 | ** See also: clone, pull, sync, remote-url |
| 191 | */ |
| 192 | void push_cmd(void){ |
| 193 | unsigned configFlags = 0; |
| 194 | unsigned syncFlags = SYNC_PUSH; |
| 195 | process_sync_args(&configFlags, &syncFlags); |
| 196 | if( db_get_boolean("dont-push",0) ){ |
| 197 | fossil_fatal("pushing is prohibited: the 'dont-push' option is set"); |
| 198 | } |
| 199 | client_sync(syncFlags, 0, 0); |
| 200 | } |
| 201 | |
| 202 | |
| 203 | /* |
| 204 | ** COMMAND: sync |
| @@ -223,17 +226,16 @@ | |
| 226 | ** remote repository. |
| 227 | ** |
| 228 | ** See also: clone, push, pull, remote-url |
| 229 | */ |
| 230 | void sync_cmd(void){ |
| 231 | unsigned configFlags = 0; |
| 232 | unsigned syncFlags = SYNC_PUSH|SYNC_PULL; |
| 233 | process_sync_args(&configFlags, &syncFlags); |
| 234 | if( db_get_boolean("dont-push",0) ) syncFlags &= ~SYNC_PUSH; |
| 235 | client_sync(syncFlags, configFlags, 0); |
| 236 | if( (syncFlags & SYNC_PUSH)==0 ){ |
| 237 | fossil_warning("pull only: the 'dont-push' option is set"); |
| 238 | } |
| 239 | } |
| 240 | |
| 241 | /* |
| 242 |
+34
-32
| --- src/sync.c | ||
| +++ src/sync.c | ||
| @@ -19,19 +19,10 @@ | ||
| 19 | 19 | */ |
| 20 | 20 | #include "config.h" |
| 21 | 21 | #include "sync.h" |
| 22 | 22 | #include <assert.h> |
| 23 | 23 | |
| 24 | -#if INTERFACE | |
| 25 | -/* | |
| 26 | -** Flags used to determine which direction(s) an autosync goes in. | |
| 27 | -*/ | |
| 28 | -#define AUTOSYNC_PUSH 1 | |
| 29 | -#define AUTOSYNC_PULL 2 | |
| 30 | - | |
| 31 | -#endif /* INTERFACE */ | |
| 32 | - | |
| 33 | 24 | /* |
| 34 | 25 | ** If the repository is configured for autosyncing, then do an |
| 35 | 26 | ** autosync. This will be a pull if the argument is true or a push |
| 36 | 27 | ** if the argument is false. |
| 37 | 28 | ** |
| @@ -44,16 +35,16 @@ | ||
| 44 | 35 | int rc; |
| 45 | 36 | int configSync = 0; /* configuration changes transferred */ |
| 46 | 37 | if( g.fNoSync ){ |
| 47 | 38 | return 0; |
| 48 | 39 | } |
| 49 | - if( flags==AUTOSYNC_PUSH && db_get_boolean("dont-push",0) ){ | |
| 40 | + if( flags==SYNC_PUSH && db_get_boolean("dont-push",0) ){ | |
| 50 | 41 | return 0; |
| 51 | 42 | } |
| 52 | 43 | zAutosync = db_get("autosync", 0); |
| 53 | 44 | if( zAutosync ){ |
| 54 | - if( (flags & AUTOSYNC_PUSH)!=0 && memcmp(zAutosync,"pull",4)==0 ){ | |
| 45 | + if( (flags & SYNC_PUSH)!=0 && memcmp(zAutosync,"pull",4)==0 ){ | |
| 55 | 46 | return 0; /* Do not auto-push when autosync=pullonly */ |
| 56 | 47 | } |
| 57 | 48 | if( is_false(zAutosync) ){ |
| 58 | 49 | return 0; /* Autosync is completely off */ |
| 59 | 50 | } |
| @@ -79,13 +70,14 @@ | ||
| 79 | 70 | ** autosync, or something? |
| 80 | 71 | */ |
| 81 | 72 | configSync = CONFIGSET_SHUN; |
| 82 | 73 | } |
| 83 | 74 | #endif |
| 75 | + if( find_option("verbose","v",0)!=0 ) flags |= SYNC_VERBOSE; | |
| 84 | 76 | fossil_print("Autosync: %s\n", g.urlCanonical); |
| 85 | 77 | url_enable_proxy("via proxy: "); |
| 86 | - rc = client_sync((flags & AUTOSYNC_PUSH)!=0, 1, 0, 0, configSync, 0); | |
| 78 | + rc = client_sync(flags, configSync, 0); | |
| 87 | 79 | if( rc ) fossil_warning("Autosync failed"); |
| 88 | 80 | return rc; |
| 89 | 81 | } |
| 90 | 82 | |
| 91 | 83 | /* |
| @@ -92,17 +84,22 @@ | ||
| 92 | 84 | ** This routine processes the command-line argument for push, pull, |
| 93 | 85 | ** and sync. If a command-line argument is given, that is the URL |
| 94 | 86 | ** of a server to sync against. If no argument is given, use the |
| 95 | 87 | ** most recently synced URL. Remember the current URL for next time. |
| 96 | 88 | */ |
| 97 | -static void process_sync_args(int *pConfigSync, int *pPrivate){ | |
| 89 | +static void process_sync_args(unsigned *pConfigFlags, unsigned *pSyncFlags){ | |
| 98 | 90 | const char *zUrl = 0; |
| 99 | 91 | const char *zPw = 0; |
| 100 | - int configSync = 0; | |
| 92 | + unsigned configSync = 0; | |
| 101 | 93 | int urlOptional = find_option("autourl",0,0)!=0; |
| 102 | 94 | g.dontKeepUrl = find_option("once",0,0)!=0; |
| 103 | - *pPrivate = find_option("private",0,0)!=0; | |
| 95 | + if( find_option("private",0,0)!=0 ){ | |
| 96 | + *pSyncFlags |= SYNC_PRIVATE; | |
| 97 | + } | |
| 98 | + if( find_option("verbose","v",0)!=0 ){ | |
| 99 | + *pSyncFlags |= SYNC_VERBOSE; | |
| 100 | + } | |
| 104 | 101 | url_proxy_options(); |
| 105 | 102 | db_find_and_open_repository(0, 0); |
| 106 | 103 | db_open_config(0); |
| 107 | 104 | if( g.argc==2 ){ |
| 108 | 105 | zUrl = db_get("last-sync-url", 0); |
| @@ -127,14 +124,20 @@ | ||
| 127 | 124 | db_set("last-sync-url", g.urlCanonical, 0); |
| 128 | 125 | if( g.urlPasswd ) db_set("last-sync-pw", obscure(g.urlPasswd), 0); |
| 129 | 126 | } |
| 130 | 127 | user_select(); |
| 131 | 128 | if( g.argc==2 ){ |
| 132 | - fossil_print("Server: %s\n", g.urlCanonical); | |
| 129 | + if( ((*pSyncFlags) & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL) ){ | |
| 130 | + fossil_print("Sync with %s\n", g.urlCanonical); | |
| 131 | + }else if( (*pSyncFlags) & SYNC_PUSH ){ | |
| 132 | + fossil_print("Push to %s\n", g.urlCanonical); | |
| 133 | + }else if( (*pSyncFlags) & SYNC_PULL ){ | |
| 134 | + fossil_print("Pull from %s\n", g.urlCanonical); | |
| 135 | + } | |
| 133 | 136 | } |
| 134 | 137 | url_enable_proxy("via proxy: "); |
| 135 | - *pConfigSync = configSync; | |
| 138 | + *pConfigFlags |= configSync; | |
| 136 | 139 | } |
| 137 | 140 | |
| 138 | 141 | /* |
| 139 | 142 | ** COMMAND: pull |
| 140 | 143 | ** |
| @@ -156,14 +159,14 @@ | ||
| 156 | 159 | ** remote repository. |
| 157 | 160 | ** |
| 158 | 161 | ** See also: clone, push, sync, remote-url |
| 159 | 162 | */ |
| 160 | 163 | void pull_cmd(void){ |
| 161 | - int syncFlags; | |
| 162 | - int bPrivate; | |
| 163 | - process_sync_args(&syncFlags, &bPrivate); | |
| 164 | - client_sync(0,1,0,bPrivate,syncFlags,0); | |
| 164 | + unsigned configFlags = 0; | |
| 165 | + unsigned syncFlags = SYNC_PULL; | |
| 166 | + process_sync_args(&configFlags, &syncFlags); | |
| 167 | + client_sync(syncFlags, configFlags, 0); | |
| 165 | 168 | } |
| 166 | 169 | |
| 167 | 170 | /* |
| 168 | 171 | ** COMMAND: push |
| 169 | 172 | ** |
| @@ -185,17 +188,17 @@ | ||
| 185 | 188 | ** remote repository. |
| 186 | 189 | ** |
| 187 | 190 | ** See also: clone, pull, sync, remote-url |
| 188 | 191 | */ |
| 189 | 192 | void push_cmd(void){ |
| 190 | - int syncFlags; | |
| 191 | - int bPrivate; | |
| 192 | - process_sync_args(&syncFlags, &bPrivate); | |
| 193 | + unsigned configFlags = 0; | |
| 194 | + unsigned syncFlags = SYNC_PUSH; | |
| 195 | + process_sync_args(&configFlags, &syncFlags); | |
| 193 | 196 | if( db_get_boolean("dont-push",0) ){ |
| 194 | 197 | fossil_fatal("pushing is prohibited: the 'dont-push' option is set"); |
| 195 | 198 | } |
| 196 | - client_sync(1,0,0,bPrivate,0,0); | |
| 199 | + client_sync(syncFlags, 0, 0); | |
| 197 | 200 | } |
| 198 | 201 | |
| 199 | 202 | |
| 200 | 203 | /* |
| 201 | 204 | ** COMMAND: sync |
| @@ -223,17 +226,16 @@ | ||
| 223 | 226 | ** remote repository. |
| 224 | 227 | ** |
| 225 | 228 | ** See also: clone, push, pull, remote-url |
| 226 | 229 | */ |
| 227 | 230 | void sync_cmd(void){ |
| 228 | - int syncFlags; | |
| 229 | - int bPrivate; | |
| 230 | - int pushFlag = 1; | |
| 231 | - process_sync_args(&syncFlags, &bPrivate); | |
| 232 | - if( db_get_boolean("dont-push",0) ) pushFlag = 0; | |
| 233 | - client_sync(pushFlag,1,0,bPrivate,syncFlags,0); | |
| 234 | - if( pushFlag==0 ){ | |
| 231 | + unsigned configFlags = 0; | |
| 232 | + unsigned syncFlags = SYNC_PUSH|SYNC_PULL; | |
| 233 | + process_sync_args(&configFlags, &syncFlags); | |
| 234 | + if( db_get_boolean("dont-push",0) ) syncFlags &= ~SYNC_PUSH; | |
| 235 | + client_sync(syncFlags, configFlags, 0); | |
| 236 | + if( (syncFlags & SYNC_PUSH)==0 ){ | |
| 235 | 237 | fossil_warning("pull only: the 'dont-push' option is set"); |
| 236 | 238 | } |
| 237 | 239 | } |
| 238 | 240 | |
| 239 | 241 | /* |
| 240 | 242 |
| --- src/sync.c | |
| +++ src/sync.c | |
| @@ -19,19 +19,10 @@ | |
| 19 | */ |
| 20 | #include "config.h" |
| 21 | #include "sync.h" |
| 22 | #include <assert.h> |
| 23 | |
| 24 | #if INTERFACE |
| 25 | /* |
| 26 | ** Flags used to determine which direction(s) an autosync goes in. |
| 27 | */ |
| 28 | #define AUTOSYNC_PUSH 1 |
| 29 | #define AUTOSYNC_PULL 2 |
| 30 | |
| 31 | #endif /* INTERFACE */ |
| 32 | |
| 33 | /* |
| 34 | ** If the repository is configured for autosyncing, then do an |
| 35 | ** autosync. This will be a pull if the argument is true or a push |
| 36 | ** if the argument is false. |
| 37 | ** |
| @@ -44,16 +35,16 @@ | |
| 44 | int rc; |
| 45 | int configSync = 0; /* configuration changes transferred */ |
| 46 | if( g.fNoSync ){ |
| 47 | return 0; |
| 48 | } |
| 49 | if( flags==AUTOSYNC_PUSH && db_get_boolean("dont-push",0) ){ |
| 50 | return 0; |
| 51 | } |
| 52 | zAutosync = db_get("autosync", 0); |
| 53 | if( zAutosync ){ |
| 54 | if( (flags & AUTOSYNC_PUSH)!=0 && memcmp(zAutosync,"pull",4)==0 ){ |
| 55 | return 0; /* Do not auto-push when autosync=pullonly */ |
| 56 | } |
| 57 | if( is_false(zAutosync) ){ |
| 58 | return 0; /* Autosync is completely off */ |
| 59 | } |
| @@ -79,13 +70,14 @@ | |
| 79 | ** autosync, or something? |
| 80 | */ |
| 81 | configSync = CONFIGSET_SHUN; |
| 82 | } |
| 83 | #endif |
| 84 | fossil_print("Autosync: %s\n", g.urlCanonical); |
| 85 | url_enable_proxy("via proxy: "); |
| 86 | rc = client_sync((flags & AUTOSYNC_PUSH)!=0, 1, 0, 0, configSync, 0); |
| 87 | if( rc ) fossil_warning("Autosync failed"); |
| 88 | return rc; |
| 89 | } |
| 90 | |
| 91 | /* |
| @@ -92,17 +84,22 @@ | |
| 92 | ** This routine processes the command-line argument for push, pull, |
| 93 | ** and sync. If a command-line argument is given, that is the URL |
| 94 | ** of a server to sync against. If no argument is given, use the |
| 95 | ** most recently synced URL. Remember the current URL for next time. |
| 96 | */ |
| 97 | static void process_sync_args(int *pConfigSync, int *pPrivate){ |
| 98 | const char *zUrl = 0; |
| 99 | const char *zPw = 0; |
| 100 | int configSync = 0; |
| 101 | int urlOptional = find_option("autourl",0,0)!=0; |
| 102 | g.dontKeepUrl = find_option("once",0,0)!=0; |
| 103 | *pPrivate = find_option("private",0,0)!=0; |
| 104 | url_proxy_options(); |
| 105 | db_find_and_open_repository(0, 0); |
| 106 | db_open_config(0); |
| 107 | if( g.argc==2 ){ |
| 108 | zUrl = db_get("last-sync-url", 0); |
| @@ -127,14 +124,20 @@ | |
| 127 | db_set("last-sync-url", g.urlCanonical, 0); |
| 128 | if( g.urlPasswd ) db_set("last-sync-pw", obscure(g.urlPasswd), 0); |
| 129 | } |
| 130 | user_select(); |
| 131 | if( g.argc==2 ){ |
| 132 | fossil_print("Server: %s\n", g.urlCanonical); |
| 133 | } |
| 134 | url_enable_proxy("via proxy: "); |
| 135 | *pConfigSync = configSync; |
| 136 | } |
| 137 | |
| 138 | /* |
| 139 | ** COMMAND: pull |
| 140 | ** |
| @@ -156,14 +159,14 @@ | |
| 156 | ** remote repository. |
| 157 | ** |
| 158 | ** See also: clone, push, sync, remote-url |
| 159 | */ |
| 160 | void pull_cmd(void){ |
| 161 | int syncFlags; |
| 162 | int bPrivate; |
| 163 | process_sync_args(&syncFlags, &bPrivate); |
| 164 | client_sync(0,1,0,bPrivate,syncFlags,0); |
| 165 | } |
| 166 | |
| 167 | /* |
| 168 | ** COMMAND: push |
| 169 | ** |
| @@ -185,17 +188,17 @@ | |
| 185 | ** remote repository. |
| 186 | ** |
| 187 | ** See also: clone, pull, sync, remote-url |
| 188 | */ |
| 189 | void push_cmd(void){ |
| 190 | int syncFlags; |
| 191 | int bPrivate; |
| 192 | process_sync_args(&syncFlags, &bPrivate); |
| 193 | if( db_get_boolean("dont-push",0) ){ |
| 194 | fossil_fatal("pushing is prohibited: the 'dont-push' option is set"); |
| 195 | } |
| 196 | client_sync(1,0,0,bPrivate,0,0); |
| 197 | } |
| 198 | |
| 199 | |
| 200 | /* |
| 201 | ** COMMAND: sync |
| @@ -223,17 +226,16 @@ | |
| 223 | ** remote repository. |
| 224 | ** |
| 225 | ** See also: clone, push, pull, remote-url |
| 226 | */ |
| 227 | void sync_cmd(void){ |
| 228 | int syncFlags; |
| 229 | int bPrivate; |
| 230 | int pushFlag = 1; |
| 231 | process_sync_args(&syncFlags, &bPrivate); |
| 232 | if( db_get_boolean("dont-push",0) ) pushFlag = 0; |
| 233 | client_sync(pushFlag,1,0,bPrivate,syncFlags,0); |
| 234 | if( pushFlag==0 ){ |
| 235 | fossil_warning("pull only: the 'dont-push' option is set"); |
| 236 | } |
| 237 | } |
| 238 | |
| 239 | /* |
| 240 |
| --- src/sync.c | |
| +++ src/sync.c | |
| @@ -19,19 +19,10 @@ | |
| 19 | */ |
| 20 | #include "config.h" |
| 21 | #include "sync.h" |
| 22 | #include <assert.h> |
| 23 | |
| 24 | /* |
| 25 | ** If the repository is configured for autosyncing, then do an |
| 26 | ** autosync. This will be a pull if the argument is true or a push |
| 27 | ** if the argument is false. |
| 28 | ** |
| @@ -44,16 +35,16 @@ | |
| 35 | int rc; |
| 36 | int configSync = 0; /* configuration changes transferred */ |
| 37 | if( g.fNoSync ){ |
| 38 | return 0; |
| 39 | } |
| 40 | if( flags==SYNC_PUSH && db_get_boolean("dont-push",0) ){ |
| 41 | return 0; |
| 42 | } |
| 43 | zAutosync = db_get("autosync", 0); |
| 44 | if( zAutosync ){ |
| 45 | if( (flags & SYNC_PUSH)!=0 && memcmp(zAutosync,"pull",4)==0 ){ |
| 46 | return 0; /* Do not auto-push when autosync=pullonly */ |
| 47 | } |
| 48 | if( is_false(zAutosync) ){ |
| 49 | return 0; /* Autosync is completely off */ |
| 50 | } |
| @@ -79,13 +70,14 @@ | |
| 70 | ** autosync, or something? |
| 71 | */ |
| 72 | configSync = CONFIGSET_SHUN; |
| 73 | } |
| 74 | #endif |
| 75 | if( find_option("verbose","v",0)!=0 ) flags |= SYNC_VERBOSE; |
| 76 | fossil_print("Autosync: %s\n", g.urlCanonical); |
| 77 | url_enable_proxy("via proxy: "); |
| 78 | rc = client_sync(flags, configSync, 0); |
| 79 | if( rc ) fossil_warning("Autosync failed"); |
| 80 | return rc; |
| 81 | } |
| 82 | |
| 83 | /* |
| @@ -92,17 +84,22 @@ | |
| 84 | ** This routine processes the command-line argument for push, pull, |
| 85 | ** and sync. If a command-line argument is given, that is the URL |
| 86 | ** of a server to sync against. If no argument is given, use the |
| 87 | ** most recently synced URL. Remember the current URL for next time. |
| 88 | */ |
| 89 | static void process_sync_args(unsigned *pConfigFlags, unsigned *pSyncFlags){ |
| 90 | const char *zUrl = 0; |
| 91 | const char *zPw = 0; |
| 92 | unsigned configSync = 0; |
| 93 | int urlOptional = find_option("autourl",0,0)!=0; |
| 94 | g.dontKeepUrl = find_option("once",0,0)!=0; |
| 95 | if( find_option("private",0,0)!=0 ){ |
| 96 | *pSyncFlags |= SYNC_PRIVATE; |
| 97 | } |
| 98 | if( find_option("verbose","v",0)!=0 ){ |
| 99 | *pSyncFlags |= SYNC_VERBOSE; |
| 100 | } |
| 101 | url_proxy_options(); |
| 102 | db_find_and_open_repository(0, 0); |
| 103 | db_open_config(0); |
| 104 | if( g.argc==2 ){ |
| 105 | zUrl = db_get("last-sync-url", 0); |
| @@ -127,14 +124,20 @@ | |
| 124 | db_set("last-sync-url", g.urlCanonical, 0); |
| 125 | if( g.urlPasswd ) db_set("last-sync-pw", obscure(g.urlPasswd), 0); |
| 126 | } |
| 127 | user_select(); |
| 128 | if( g.argc==2 ){ |
| 129 | if( ((*pSyncFlags) & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL) ){ |
| 130 | fossil_print("Sync with %s\n", g.urlCanonical); |
| 131 | }else if( (*pSyncFlags) & SYNC_PUSH ){ |
| 132 | fossil_print("Push to %s\n", g.urlCanonical); |
| 133 | }else if( (*pSyncFlags) & SYNC_PULL ){ |
| 134 | fossil_print("Pull from %s\n", g.urlCanonical); |
| 135 | } |
| 136 | } |
| 137 | url_enable_proxy("via proxy: "); |
| 138 | *pConfigFlags |= configSync; |
| 139 | } |
| 140 | |
| 141 | /* |
| 142 | ** COMMAND: pull |
| 143 | ** |
| @@ -156,14 +159,14 @@ | |
| 159 | ** remote repository. |
| 160 | ** |
| 161 | ** See also: clone, push, sync, remote-url |
| 162 | */ |
| 163 | void pull_cmd(void){ |
| 164 | unsigned configFlags = 0; |
| 165 | unsigned syncFlags = SYNC_PULL; |
| 166 | process_sync_args(&configFlags, &syncFlags); |
| 167 | client_sync(syncFlags, configFlags, 0); |
| 168 | } |
| 169 | |
| 170 | /* |
| 171 | ** COMMAND: push |
| 172 | ** |
| @@ -185,17 +188,17 @@ | |
| 188 | ** remote repository. |
| 189 | ** |
| 190 | ** See also: clone, pull, sync, remote-url |
| 191 | */ |
| 192 | void push_cmd(void){ |
| 193 | unsigned configFlags = 0; |
| 194 | unsigned syncFlags = SYNC_PUSH; |
| 195 | process_sync_args(&configFlags, &syncFlags); |
| 196 | if( db_get_boolean("dont-push",0) ){ |
| 197 | fossil_fatal("pushing is prohibited: the 'dont-push' option is set"); |
| 198 | } |
| 199 | client_sync(syncFlags, 0, 0); |
| 200 | } |
| 201 | |
| 202 | |
| 203 | /* |
| 204 | ** COMMAND: sync |
| @@ -223,17 +226,16 @@ | |
| 226 | ** remote repository. |
| 227 | ** |
| 228 | ** See also: clone, push, pull, remote-url |
| 229 | */ |
| 230 | void sync_cmd(void){ |
| 231 | unsigned configFlags = 0; |
| 232 | unsigned syncFlags = SYNC_PUSH|SYNC_PULL; |
| 233 | process_sync_args(&configFlags, &syncFlags); |
| 234 | if( db_get_boolean("dont-push",0) ) syncFlags &= ~SYNC_PUSH; |
| 235 | client_sync(syncFlags, configFlags, 0); |
| 236 | if( (syncFlags & SYNC_PUSH)==0 ){ |
| 237 | fossil_warning("pull only: the 'dont-push' option is set"); |
| 238 | } |
| 239 | } |
| 240 | |
| 241 | /* |
| 242 |
+6
-4
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -85,10 +85,11 @@ | ||
| 85 | 85 | ** Generate a hyperlink to a user. This will link to a timeline showing |
| 86 | 86 | ** events by that user. If the date+time is specified, then the timeline |
| 87 | 87 | ** is centered on that date+time. |
| 88 | 88 | */ |
| 89 | 89 | void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){ |
| 90 | + if( zU==0 || zU[0]==0 ) zU = "anonymous"; | |
| 90 | 91 | if( zSuf==0 ) zSuf = ""; |
| 91 | 92 | if( g.perm.Hyperlink ){ |
| 92 | 93 | if( zD && zD[0] ){ |
| 93 | 94 | @ %z(href("%R/timeline?c=%T&u=%T",zD,zU))%h(zU)</a>%s(zSuf) |
| 94 | 95 | }else{ |
| @@ -237,10 +238,11 @@ | ||
| 237 | 238 | const char *zDate = db_column_text(pQuery, 2); |
| 238 | 239 | const char *zType = db_column_text(pQuery, 7); |
| 239 | 240 | const char *zUser = db_column_text(pQuery, 4); |
| 240 | 241 | const char *zTagList = db_column_text(pQuery, 8); |
| 241 | 242 | int tagid = db_column_int(pQuery, 9); |
| 243 | + const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous"; | |
| 242 | 244 | const char *zBr = 0; /* Branch */ |
| 243 | 245 | int commentColumn = 3; /* Column containing comment text */ |
| 244 | 246 | int modPending; /* Pending moderation */ |
| 245 | 247 | char zTime[8]; |
| 246 | 248 | |
| @@ -372,15 +374,15 @@ | ||
| 372 | 374 | |
| 373 | 375 | /* Generate the "user: USERNAME" at the end of the comment, together |
| 374 | 376 | ** with a hyperlink to another timeline for that user. |
| 375 | 377 | */ |
| 376 | 378 | if( zTagList && zTagList[0]==0 ) zTagList = 0; |
| 377 | - if( g.perm.Hyperlink && fossil_strcmp(zUser, zThisUser)!=0 ){ | |
| 378 | - char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd", zUser, zDate); | |
| 379 | - @ (user: %z(href("%z",zLink))%h(zUser)</a>%s(zTagList?",":"\051") | |
| 379 | + if( g.perm.Hyperlink && fossil_strcmp(zDispUser, zThisUser)!=0 ){ | |
| 380 | + char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd", zDispUser, zDate); | |
| 381 | + @ (user: %z(href("%z",zLink))%h(zDispUser)</a>%s(zTagList?",":"\051") | |
| 380 | 382 | }else{ |
| 381 | - @ (user: %h(zUser)%s(zTagList?",":"\051") | |
| 383 | + @ (user: %h(zDispUser)%s(zTagList?",":"\051") | |
| 382 | 384 | } |
| 383 | 385 | |
| 384 | 386 | /* Generate a "detail" link for tags. */ |
| 385 | 387 | if( (zType[0]=='g' || zType[0]=='w' || zType[0]=='t') && g.perm.Hyperlink ){ |
| 386 | 388 | @ [%z(href("%R/info/%S",zUuid))details</a>] |
| 387 | 389 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -85,10 +85,11 @@ | |
| 85 | ** Generate a hyperlink to a user. This will link to a timeline showing |
| 86 | ** events by that user. If the date+time is specified, then the timeline |
| 87 | ** is centered on that date+time. |
| 88 | */ |
| 89 | void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){ |
| 90 | if( zSuf==0 ) zSuf = ""; |
| 91 | if( g.perm.Hyperlink ){ |
| 92 | if( zD && zD[0] ){ |
| 93 | @ %z(href("%R/timeline?c=%T&u=%T",zD,zU))%h(zU)</a>%s(zSuf) |
| 94 | }else{ |
| @@ -237,10 +238,11 @@ | |
| 237 | const char *zDate = db_column_text(pQuery, 2); |
| 238 | const char *zType = db_column_text(pQuery, 7); |
| 239 | const char *zUser = db_column_text(pQuery, 4); |
| 240 | const char *zTagList = db_column_text(pQuery, 8); |
| 241 | int tagid = db_column_int(pQuery, 9); |
| 242 | const char *zBr = 0; /* Branch */ |
| 243 | int commentColumn = 3; /* Column containing comment text */ |
| 244 | int modPending; /* Pending moderation */ |
| 245 | char zTime[8]; |
| 246 | |
| @@ -372,15 +374,15 @@ | |
| 372 | |
| 373 | /* Generate the "user: USERNAME" at the end of the comment, together |
| 374 | ** with a hyperlink to another timeline for that user. |
| 375 | */ |
| 376 | if( zTagList && zTagList[0]==0 ) zTagList = 0; |
| 377 | if( g.perm.Hyperlink && fossil_strcmp(zUser, zThisUser)!=0 ){ |
| 378 | char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd", zUser, zDate); |
| 379 | @ (user: %z(href("%z",zLink))%h(zUser)</a>%s(zTagList?",":"\051") |
| 380 | }else{ |
| 381 | @ (user: %h(zUser)%s(zTagList?",":"\051") |
| 382 | } |
| 383 | |
| 384 | /* Generate a "detail" link for tags. */ |
| 385 | if( (zType[0]=='g' || zType[0]=='w' || zType[0]=='t') && g.perm.Hyperlink ){ |
| 386 | @ [%z(href("%R/info/%S",zUuid))details</a>] |
| 387 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -85,10 +85,11 @@ | |
| 85 | ** Generate a hyperlink to a user. This will link to a timeline showing |
| 86 | ** events by that user. If the date+time is specified, then the timeline |
| 87 | ** is centered on that date+time. |
| 88 | */ |
| 89 | void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){ |
| 90 | if( zU==0 || zU[0]==0 ) zU = "anonymous"; |
| 91 | if( zSuf==0 ) zSuf = ""; |
| 92 | if( g.perm.Hyperlink ){ |
| 93 | if( zD && zD[0] ){ |
| 94 | @ %z(href("%R/timeline?c=%T&u=%T",zD,zU))%h(zU)</a>%s(zSuf) |
| 95 | }else{ |
| @@ -237,10 +238,11 @@ | |
| 238 | const char *zDate = db_column_text(pQuery, 2); |
| 239 | const char *zType = db_column_text(pQuery, 7); |
| 240 | const char *zUser = db_column_text(pQuery, 4); |
| 241 | const char *zTagList = db_column_text(pQuery, 8); |
| 242 | int tagid = db_column_int(pQuery, 9); |
| 243 | const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous"; |
| 244 | const char *zBr = 0; /* Branch */ |
| 245 | int commentColumn = 3; /* Column containing comment text */ |
| 246 | int modPending; /* Pending moderation */ |
| 247 | char zTime[8]; |
| 248 | |
| @@ -372,15 +374,15 @@ | |
| 374 | |
| 375 | /* Generate the "user: USERNAME" at the end of the comment, together |
| 376 | ** with a hyperlink to another timeline for that user. |
| 377 | */ |
| 378 | if( zTagList && zTagList[0]==0 ) zTagList = 0; |
| 379 | if( g.perm.Hyperlink && fossil_strcmp(zDispUser, zThisUser)!=0 ){ |
| 380 | char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd", zDispUser, zDate); |
| 381 | @ (user: %z(href("%z",zLink))%h(zDispUser)</a>%s(zTagList?",":"\051") |
| 382 | }else{ |
| 383 | @ (user: %h(zDispUser)%s(zTagList?",":"\051") |
| 384 | } |
| 385 | |
| 386 | /* Generate a "detail" link for tags. */ |
| 387 | if( (zType[0]=='g' || zType[0]=='w' || zType[0]=='t') && g.perm.Hyperlink ){ |
| 388 | @ [%z(href("%R/info/%S",zUuid))details</a>] |
| 389 |
+6
-4
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -85,10 +85,11 @@ | ||
| 85 | 85 | ** Generate a hyperlink to a user. This will link to a timeline showing |
| 86 | 86 | ** events by that user. If the date+time is specified, then the timeline |
| 87 | 87 | ** is centered on that date+time. |
| 88 | 88 | */ |
| 89 | 89 | void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){ |
| 90 | + if( zU==0 || zU[0]==0 ) zU = "anonymous"; | |
| 90 | 91 | if( zSuf==0 ) zSuf = ""; |
| 91 | 92 | if( g.perm.Hyperlink ){ |
| 92 | 93 | if( zD && zD[0] ){ |
| 93 | 94 | @ %z(href("%R/timeline?c=%T&u=%T",zD,zU))%h(zU)</a>%s(zSuf) |
| 94 | 95 | }else{ |
| @@ -237,10 +238,11 @@ | ||
| 237 | 238 | const char *zDate = db_column_text(pQuery, 2); |
| 238 | 239 | const char *zType = db_column_text(pQuery, 7); |
| 239 | 240 | const char *zUser = db_column_text(pQuery, 4); |
| 240 | 241 | const char *zTagList = db_column_text(pQuery, 8); |
| 241 | 242 | int tagid = db_column_int(pQuery, 9); |
| 243 | + const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous"; | |
| 242 | 244 | const char *zBr = 0; /* Branch */ |
| 243 | 245 | int commentColumn = 3; /* Column containing comment text */ |
| 244 | 246 | int modPending; /* Pending moderation */ |
| 245 | 247 | char zTime[8]; |
| 246 | 248 | |
| @@ -372,15 +374,15 @@ | ||
| 372 | 374 | |
| 373 | 375 | /* Generate the "user: USERNAME" at the end of the comment, together |
| 374 | 376 | ** with a hyperlink to another timeline for that user. |
| 375 | 377 | */ |
| 376 | 378 | if( zTagList && zTagList[0]==0 ) zTagList = 0; |
| 377 | - if( g.perm.Hyperlink && fossil_strcmp(zUser, zThisUser)!=0 ){ | |
| 378 | - char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd", zUser, zDate); | |
| 379 | - @ (user: %z(href("%z",zLink))%h(zUser)</a>%s(zTagList?",":"\051") | |
| 379 | + if( g.perm.Hyperlink && fossil_strcmp(zDispUser, zThisUser)!=0 ){ | |
| 380 | + char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd", zDispUser, zDate); | |
| 381 | + @ (user: %z(href("%z",zLink))%h(zDispUser)</a>%s(zTagList?",":"\051") | |
| 380 | 382 | }else{ |
| 381 | - @ (user: %h(zUser)%s(zTagList?",":"\051") | |
| 383 | + @ (user: %h(zDispUser)%s(zTagList?",":"\051") | |
| 382 | 384 | } |
| 383 | 385 | |
| 384 | 386 | /* Generate a "detail" link for tags. */ |
| 385 | 387 | if( (zType[0]=='g' || zType[0]=='w' || zType[0]=='t') && g.perm.Hyperlink ){ |
| 386 | 388 | @ [%z(href("%R/info/%S",zUuid))details</a>] |
| 387 | 389 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -85,10 +85,11 @@ | |
| 85 | ** Generate a hyperlink to a user. This will link to a timeline showing |
| 86 | ** events by that user. If the date+time is specified, then the timeline |
| 87 | ** is centered on that date+time. |
| 88 | */ |
| 89 | void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){ |
| 90 | if( zSuf==0 ) zSuf = ""; |
| 91 | if( g.perm.Hyperlink ){ |
| 92 | if( zD && zD[0] ){ |
| 93 | @ %z(href("%R/timeline?c=%T&u=%T",zD,zU))%h(zU)</a>%s(zSuf) |
| 94 | }else{ |
| @@ -237,10 +238,11 @@ | |
| 237 | const char *zDate = db_column_text(pQuery, 2); |
| 238 | const char *zType = db_column_text(pQuery, 7); |
| 239 | const char *zUser = db_column_text(pQuery, 4); |
| 240 | const char *zTagList = db_column_text(pQuery, 8); |
| 241 | int tagid = db_column_int(pQuery, 9); |
| 242 | const char *zBr = 0; /* Branch */ |
| 243 | int commentColumn = 3; /* Column containing comment text */ |
| 244 | int modPending; /* Pending moderation */ |
| 245 | char zTime[8]; |
| 246 | |
| @@ -372,15 +374,15 @@ | |
| 372 | |
| 373 | /* Generate the "user: USERNAME" at the end of the comment, together |
| 374 | ** with a hyperlink to another timeline for that user. |
| 375 | */ |
| 376 | if( zTagList && zTagList[0]==0 ) zTagList = 0; |
| 377 | if( g.perm.Hyperlink && fossil_strcmp(zUser, zThisUser)!=0 ){ |
| 378 | char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd", zUser, zDate); |
| 379 | @ (user: %z(href("%z",zLink))%h(zUser)</a>%s(zTagList?",":"\051") |
| 380 | }else{ |
| 381 | @ (user: %h(zUser)%s(zTagList?",":"\051") |
| 382 | } |
| 383 | |
| 384 | /* Generate a "detail" link for tags. */ |
| 385 | if( (zType[0]=='g' || zType[0]=='w' || zType[0]=='t') && g.perm.Hyperlink ){ |
| 386 | @ [%z(href("%R/info/%S",zUuid))details</a>] |
| 387 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -85,10 +85,11 @@ | |
| 85 | ** Generate a hyperlink to a user. This will link to a timeline showing |
| 86 | ** events by that user. If the date+time is specified, then the timeline |
| 87 | ** is centered on that date+time. |
| 88 | */ |
| 89 | void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){ |
| 90 | if( zU==0 || zU[0]==0 ) zU = "anonymous"; |
| 91 | if( zSuf==0 ) zSuf = ""; |
| 92 | if( g.perm.Hyperlink ){ |
| 93 | if( zD && zD[0] ){ |
| 94 | @ %z(href("%R/timeline?c=%T&u=%T",zD,zU))%h(zU)</a>%s(zSuf) |
| 95 | }else{ |
| @@ -237,10 +238,11 @@ | |
| 238 | const char *zDate = db_column_text(pQuery, 2); |
| 239 | const char *zType = db_column_text(pQuery, 7); |
| 240 | const char *zUser = db_column_text(pQuery, 4); |
| 241 | const char *zTagList = db_column_text(pQuery, 8); |
| 242 | int tagid = db_column_int(pQuery, 9); |
| 243 | const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous"; |
| 244 | const char *zBr = 0; /* Branch */ |
| 245 | int commentColumn = 3; /* Column containing comment text */ |
| 246 | int modPending; /* Pending moderation */ |
| 247 | char zTime[8]; |
| 248 | |
| @@ -372,15 +374,15 @@ | |
| 374 | |
| 375 | /* Generate the "user: USERNAME" at the end of the comment, together |
| 376 | ** with a hyperlink to another timeline for that user. |
| 377 | */ |
| 378 | if( zTagList && zTagList[0]==0 ) zTagList = 0; |
| 379 | if( g.perm.Hyperlink && fossil_strcmp(zDispUser, zThisUser)!=0 ){ |
| 380 | char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd", zDispUser, zDate); |
| 381 | @ (user: %z(href("%z",zLink))%h(zDispUser)</a>%s(zTagList?",":"\051") |
| 382 | }else{ |
| 383 | @ (user: %h(zDispUser)%s(zTagList?",":"\051") |
| 384 | } |
| 385 | |
| 386 | /* Generate a "detail" link for tags. */ |
| 387 | if( (zType[0]=='g' || zType[0]=='w' || zType[0]=='t') && g.perm.Hyperlink ){ |
| 388 | @ [%z(href("%R/info/%S",zUuid))details</a>] |
| 389 |
+6
-4
| --- src/timeline.c | ||
| +++ src/timeline.c | ||
| @@ -85,10 +85,11 @@ | ||
| 85 | 85 | ** Generate a hyperlink to a user. This will link to a timeline showing |
| 86 | 86 | ** events by that user. If the date+time is specified, then the timeline |
| 87 | 87 | ** is centered on that date+time. |
| 88 | 88 | */ |
| 89 | 89 | void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){ |
| 90 | + if( zU==0 || zU[0]==0 ) zU = "anonymous"; | |
| 90 | 91 | if( zSuf==0 ) zSuf = ""; |
| 91 | 92 | if( g.perm.Hyperlink ){ |
| 92 | 93 | if( zD && zD[0] ){ |
| 93 | 94 | @ %z(href("%R/timeline?c=%T&u=%T",zD,zU))%h(zU)</a>%s(zSuf) |
| 94 | 95 | }else{ |
| @@ -237,10 +238,11 @@ | ||
| 237 | 238 | const char *zDate = db_column_text(pQuery, 2); |
| 238 | 239 | const char *zType = db_column_text(pQuery, 7); |
| 239 | 240 | const char *zUser = db_column_text(pQuery, 4); |
| 240 | 241 | const char *zTagList = db_column_text(pQuery, 8); |
| 241 | 242 | int tagid = db_column_int(pQuery, 9); |
| 243 | + const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous"; | |
| 242 | 244 | const char *zBr = 0; /* Branch */ |
| 243 | 245 | int commentColumn = 3; /* Column containing comment text */ |
| 244 | 246 | int modPending; /* Pending moderation */ |
| 245 | 247 | char zTime[8]; |
| 246 | 248 | |
| @@ -372,15 +374,15 @@ | ||
| 372 | 374 | |
| 373 | 375 | /* Generate the "user: USERNAME" at the end of the comment, together |
| 374 | 376 | ** with a hyperlink to another timeline for that user. |
| 375 | 377 | */ |
| 376 | 378 | if( zTagList && zTagList[0]==0 ) zTagList = 0; |
| 377 | - if( g.perm.Hyperlink && fossil_strcmp(zUser, zThisUser)!=0 ){ | |
| 378 | - char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd", zUser, zDate); | |
| 379 | - @ (user: %z(href("%z",zLink))%h(zUser)</a>%s(zTagList?",":"\051") | |
| 379 | + if( g.perm.Hyperlink && fossil_strcmp(zDispUser, zThisUser)!=0 ){ | |
| 380 | + char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd", zDispUser, zDate); | |
| 381 | + @ (user: %z(href("%z",zLink))%h(zDispUser)</a>%s(zTagList?",":"\051") | |
| 380 | 382 | }else{ |
| 381 | - @ (user: %h(zUser)%s(zTagList?",":"\051") | |
| 383 | + @ (user: %h(zDispUser)%s(zTagList?",":"\051") | |
| 382 | 384 | } |
| 383 | 385 | |
| 384 | 386 | /* Generate a "detail" link for tags. */ |
| 385 | 387 | if( (zType[0]=='g' || zType[0]=='w' || zType[0]=='t') && g.perm.Hyperlink ){ |
| 386 | 388 | @ [%z(href("%R/info/%S",zUuid))details</a>] |
| 387 | 389 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -85,10 +85,11 @@ | |
| 85 | ** Generate a hyperlink to a user. This will link to a timeline showing |
| 86 | ** events by that user. If the date+time is specified, then the timeline |
| 87 | ** is centered on that date+time. |
| 88 | */ |
| 89 | void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){ |
| 90 | if( zSuf==0 ) zSuf = ""; |
| 91 | if( g.perm.Hyperlink ){ |
| 92 | if( zD && zD[0] ){ |
| 93 | @ %z(href("%R/timeline?c=%T&u=%T",zD,zU))%h(zU)</a>%s(zSuf) |
| 94 | }else{ |
| @@ -237,10 +238,11 @@ | |
| 237 | const char *zDate = db_column_text(pQuery, 2); |
| 238 | const char *zType = db_column_text(pQuery, 7); |
| 239 | const char *zUser = db_column_text(pQuery, 4); |
| 240 | const char *zTagList = db_column_text(pQuery, 8); |
| 241 | int tagid = db_column_int(pQuery, 9); |
| 242 | const char *zBr = 0; /* Branch */ |
| 243 | int commentColumn = 3; /* Column containing comment text */ |
| 244 | int modPending; /* Pending moderation */ |
| 245 | char zTime[8]; |
| 246 | |
| @@ -372,15 +374,15 @@ | |
| 372 | |
| 373 | /* Generate the "user: USERNAME" at the end of the comment, together |
| 374 | ** with a hyperlink to another timeline for that user. |
| 375 | */ |
| 376 | if( zTagList && zTagList[0]==0 ) zTagList = 0; |
| 377 | if( g.perm.Hyperlink && fossil_strcmp(zUser, zThisUser)!=0 ){ |
| 378 | char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd", zUser, zDate); |
| 379 | @ (user: %z(href("%z",zLink))%h(zUser)</a>%s(zTagList?",":"\051") |
| 380 | }else{ |
| 381 | @ (user: %h(zUser)%s(zTagList?",":"\051") |
| 382 | } |
| 383 | |
| 384 | /* Generate a "detail" link for tags. */ |
| 385 | if( (zType[0]=='g' || zType[0]=='w' || zType[0]=='t') && g.perm.Hyperlink ){ |
| 386 | @ [%z(href("%R/info/%S",zUuid))details</a>] |
| 387 |
| --- src/timeline.c | |
| +++ src/timeline.c | |
| @@ -85,10 +85,11 @@ | |
| 85 | ** Generate a hyperlink to a user. This will link to a timeline showing |
| 86 | ** events by that user. If the date+time is specified, then the timeline |
| 87 | ** is centered on that date+time. |
| 88 | */ |
| 89 | void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){ |
| 90 | if( zU==0 || zU[0]==0 ) zU = "anonymous"; |
| 91 | if( zSuf==0 ) zSuf = ""; |
| 92 | if( g.perm.Hyperlink ){ |
| 93 | if( zD && zD[0] ){ |
| 94 | @ %z(href("%R/timeline?c=%T&u=%T",zD,zU))%h(zU)</a>%s(zSuf) |
| 95 | }else{ |
| @@ -237,10 +238,11 @@ | |
| 238 | const char *zDate = db_column_text(pQuery, 2); |
| 239 | const char *zType = db_column_text(pQuery, 7); |
| 240 | const char *zUser = db_column_text(pQuery, 4); |
| 241 | const char *zTagList = db_column_text(pQuery, 8); |
| 242 | int tagid = db_column_int(pQuery, 9); |
| 243 | const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous"; |
| 244 | const char *zBr = 0; /* Branch */ |
| 245 | int commentColumn = 3; /* Column containing comment text */ |
| 246 | int modPending; /* Pending moderation */ |
| 247 | char zTime[8]; |
| 248 | |
| @@ -372,15 +374,15 @@ | |
| 374 | |
| 375 | /* Generate the "user: USERNAME" at the end of the comment, together |
| 376 | ** with a hyperlink to another timeline for that user. |
| 377 | */ |
| 378 | if( zTagList && zTagList[0]==0 ) zTagList = 0; |
| 379 | if( g.perm.Hyperlink && fossil_strcmp(zDispUser, zThisUser)!=0 ){ |
| 380 | char *zLink = mprintf("%R/timeline?u=%h&c=%t&nd", zDispUser, zDate); |
| 381 | @ (user: %z(href("%z",zLink))%h(zDispUser)</a>%s(zTagList?",":"\051") |
| 382 | }else{ |
| 383 | @ (user: %h(zDispUser)%s(zTagList?",":"\051") |
| 384 | } |
| 385 | |
| 386 | /* Generate a "detail" link for tags. */ |
| 387 | if( (zType[0]=='g' || zType[0]=='w' || zType[0]=='t') && g.perm.Hyperlink ){ |
| 388 | @ [%z(href("%R/info/%S",zUuid))details</a>] |
| 389 |
+3
-1
| --- src/update.c | ||
| +++ src/update.c | ||
| @@ -123,11 +123,13 @@ | ||
| 123 | 123 | db_must_be_within_tree(); |
| 124 | 124 | vid = db_lget_int("checkout", 0); |
| 125 | 125 | if( vid==0 ){ |
| 126 | 126 | fossil_fatal("cannot find current version"); |
| 127 | 127 | } |
| 128 | - if( !nochangeFlag && !internalUpdate ) autosync(AUTOSYNC_PULL); | |
| 128 | + if( !nochangeFlag && !internalUpdate ){ | |
| 129 | + autosync(SYNC_PULL + SYNC_VERBOSE*verboseFlag); | |
| 130 | + } | |
| 129 | 131 | |
| 130 | 132 | /* Create any empty directories now, as well as after the update, |
| 131 | 133 | ** so changes in settings are reflected now */ |
| 132 | 134 | if( !nochangeFlag ) ensure_empty_dirs_created(); |
| 133 | 135 | |
| 134 | 136 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -123,11 +123,13 @@ | |
| 123 | db_must_be_within_tree(); |
| 124 | vid = db_lget_int("checkout", 0); |
| 125 | if( vid==0 ){ |
| 126 | fossil_fatal("cannot find current version"); |
| 127 | } |
| 128 | if( !nochangeFlag && !internalUpdate ) autosync(AUTOSYNC_PULL); |
| 129 | |
| 130 | /* Create any empty directories now, as well as after the update, |
| 131 | ** so changes in settings are reflected now */ |
| 132 | if( !nochangeFlag ) ensure_empty_dirs_created(); |
| 133 | |
| 134 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -123,11 +123,13 @@ | |
| 123 | db_must_be_within_tree(); |
| 124 | vid = db_lget_int("checkout", 0); |
| 125 | if( vid==0 ){ |
| 126 | fossil_fatal("cannot find current version"); |
| 127 | } |
| 128 | if( !nochangeFlag && !internalUpdate ){ |
| 129 | autosync(SYNC_PULL + SYNC_VERBOSE*verboseFlag); |
| 130 | } |
| 131 | |
| 132 | /* Create any empty directories now, as well as after the update, |
| 133 | ** so changes in settings are reflected now */ |
| 134 | if( !nochangeFlag ) ensure_empty_dirs_created(); |
| 135 | |
| 136 |
+3
-1
| --- src/update.c | ||
| +++ src/update.c | ||
| @@ -123,11 +123,13 @@ | ||
| 123 | 123 | db_must_be_within_tree(); |
| 124 | 124 | vid = db_lget_int("checkout", 0); |
| 125 | 125 | if( vid==0 ){ |
| 126 | 126 | fossil_fatal("cannot find current version"); |
| 127 | 127 | } |
| 128 | - if( !nochangeFlag && !internalUpdate ) autosync(AUTOSYNC_PULL); | |
| 128 | + if( !nochangeFlag && !internalUpdate ){ | |
| 129 | + autosync(SYNC_PULL + SYNC_VERBOSE*verboseFlag); | |
| 130 | + } | |
| 129 | 131 | |
| 130 | 132 | /* Create any empty directories now, as well as after the update, |
| 131 | 133 | ** so changes in settings are reflected now */ |
| 132 | 134 | if( !nochangeFlag ) ensure_empty_dirs_created(); |
| 133 | 135 | |
| 134 | 136 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -123,11 +123,13 @@ | |
| 123 | db_must_be_within_tree(); |
| 124 | vid = db_lget_int("checkout", 0); |
| 125 | if( vid==0 ){ |
| 126 | fossil_fatal("cannot find current version"); |
| 127 | } |
| 128 | if( !nochangeFlag && !internalUpdate ) autosync(AUTOSYNC_PULL); |
| 129 | |
| 130 | /* Create any empty directories now, as well as after the update, |
| 131 | ** so changes in settings are reflected now */ |
| 132 | if( !nochangeFlag ) ensure_empty_dirs_created(); |
| 133 | |
| 134 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -123,11 +123,13 @@ | |
| 123 | db_must_be_within_tree(); |
| 124 | vid = db_lget_int("checkout", 0); |
| 125 | if( vid==0 ){ |
| 126 | fossil_fatal("cannot find current version"); |
| 127 | } |
| 128 | if( !nochangeFlag && !internalUpdate ){ |
| 129 | autosync(SYNC_PULL + SYNC_VERBOSE*verboseFlag); |
| 130 | } |
| 131 | |
| 132 | /* Create any empty directories now, as well as after the update, |
| 133 | ** so changes in settings are reflected now */ |
| 134 | if( !nochangeFlag ) ensure_empty_dirs_created(); |
| 135 | |
| 136 |
+3
-1
| --- src/update.c | ||
| +++ src/update.c | ||
| @@ -123,11 +123,13 @@ | ||
| 123 | 123 | db_must_be_within_tree(); |
| 124 | 124 | vid = db_lget_int("checkout", 0); |
| 125 | 125 | if( vid==0 ){ |
| 126 | 126 | fossil_fatal("cannot find current version"); |
| 127 | 127 | } |
| 128 | - if( !nochangeFlag && !internalUpdate ) autosync(AUTOSYNC_PULL); | |
| 128 | + if( !nochangeFlag && !internalUpdate ){ | |
| 129 | + autosync(SYNC_PULL + SYNC_VERBOSE*verboseFlag); | |
| 130 | + } | |
| 129 | 131 | |
| 130 | 132 | /* Create any empty directories now, as well as after the update, |
| 131 | 133 | ** so changes in settings are reflected now */ |
| 132 | 134 | if( !nochangeFlag ) ensure_empty_dirs_created(); |
| 133 | 135 | |
| 134 | 136 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -123,11 +123,13 @@ | |
| 123 | db_must_be_within_tree(); |
| 124 | vid = db_lget_int("checkout", 0); |
| 125 | if( vid==0 ){ |
| 126 | fossil_fatal("cannot find current version"); |
| 127 | } |
| 128 | if( !nochangeFlag && !internalUpdate ) autosync(AUTOSYNC_PULL); |
| 129 | |
| 130 | /* Create any empty directories now, as well as after the update, |
| 131 | ** so changes in settings are reflected now */ |
| 132 | if( !nochangeFlag ) ensure_empty_dirs_created(); |
| 133 | |
| 134 |
| --- src/update.c | |
| +++ src/update.c | |
| @@ -123,11 +123,13 @@ | |
| 123 | db_must_be_within_tree(); |
| 124 | vid = db_lget_int("checkout", 0); |
| 125 | if( vid==0 ){ |
| 126 | fossil_fatal("cannot find current version"); |
| 127 | } |
| 128 | if( !nochangeFlag && !internalUpdate ){ |
| 129 | autosync(SYNC_PULL + SYNC_VERBOSE*verboseFlag); |
| 130 | } |
| 131 | |
| 132 | /* Create any empty directories now, as well as after the update, |
| 133 | ** so changes in settings are reflected now */ |
| 134 | if( !nochangeFlag ) ensure_empty_dirs_created(); |
| 135 | |
| 136 |
+80
-43
| --- src/xfer.c | ||
| +++ src/xfer.c | ||
| @@ -1266,11 +1266,23 @@ | ||
| 1266 | 1266 | /* |
| 1267 | 1267 | ** Format strings for progress reporting. |
| 1268 | 1268 | */ |
| 1269 | 1269 | static const char zLabelFormat[] = "%-10s %10s %10s %10s %10s\n"; |
| 1270 | 1270 | static const char zValueFormat[] = "\r%-10s %10d %10d %10d %10d\n"; |
| 1271 | +static const char zBriefFormat[] = | |
| 1272 | + "Round-trips: %d Artifacts sent: %d received: %d\r"; | |
| 1271 | 1273 | |
| 1274 | +#if INTERFACE | |
| 1275 | +/* | |
| 1276 | +** Flag options for controlling client_sync() | |
| 1277 | +*/ | |
| 1278 | +#define SYNC_PUSH 0x0001 | |
| 1279 | +#define SYNC_PULL 0x0002 | |
| 1280 | +#define SYNC_CLONE 0x0004 | |
| 1281 | +#define SYNC_PRIVATE 0x0008 | |
| 1282 | +#define SYNC_VERBOSE 0x0010 | |
| 1283 | +#endif | |
| 1272 | 1284 | |
| 1273 | 1285 | /* |
| 1274 | 1286 | ** Sync to the host identified in g.urlName and g.urlPath. This |
| 1275 | 1287 | ** routine is called by the client. |
| 1276 | 1288 | ** |
| @@ -1277,16 +1289,13 @@ | ||
| 1277 | 1289 | ** Records are pushed to the server if pushFlag is true. Records |
| 1278 | 1290 | ** are pulled if pullFlag is true. A full sync occurs if both are |
| 1279 | 1291 | ** true. |
| 1280 | 1292 | */ |
| 1281 | 1293 | int client_sync( |
| 1282 | - int pushFlag, /* True to do a push (or a sync) */ | |
| 1283 | - int pullFlag, /* True to do a pull (or a sync) */ | |
| 1284 | - int cloneFlag, /* True if this is a clone */ | |
| 1285 | - int privateFlag, /* True to exchange private branches */ | |
| 1286 | - int configRcvMask, /* Receive these configuration items */ | |
| 1287 | - int configSendMask /* Send these configuration items */ | |
| 1294 | + unsigned syncFlags, /* Mask of SYNC_* flags */ | |
| 1295 | + unsigned configRcvMask, /* Receive these configuration items */ | |
| 1296 | + unsigned configSendMask /* Send these configuration items */ | |
| 1288 | 1297 | ){ |
| 1289 | 1298 | int go = 1; /* Loop until zero */ |
| 1290 | 1299 | int nCardSent = 0; /* Number of cards sent */ |
| 1291 | 1300 | int nCardRcvd = 0; /* Number of cards received */ |
| 1292 | 1301 | int nCycle = 0; /* Number of round trips to the server */ |
| @@ -1304,27 +1313,30 @@ | ||
| 1304 | 1313 | int lastPctDone = -1; /* Last displayed pctDone */ |
| 1305 | 1314 | double rArrivalTime; /* Time at which a message arrived */ |
| 1306 | 1315 | const char *zSCode = db_get("server-code", "x"); |
| 1307 | 1316 | const char *zPCode = db_get("project-code", 0); |
| 1308 | 1317 | int nErr = 0; /* Number of errors */ |
| 1318 | + int nRoundtrip= 0; /* Number of HTTP requests */ | |
| 1319 | + int nArtifactSent = 0; /* Total artifacts sent */ | |
| 1320 | + int nArtifactRcvd = 0; /* Total artifacts received */ | |
| 1321 | + const char *zOpType = 0;/* Push, Pull, Sync, Clone */ | |
| 1309 | 1322 | |
| 1310 | - if( db_get_boolean("dont-push", 0) ) pushFlag = 0; | |
| 1311 | - if( pushFlag + pullFlag + cloneFlag == 0 | |
| 1323 | + if( db_get_boolean("dont-push", 0) ) syncFlags &= ~SYNC_PUSH; | |
| 1324 | + if( (syncFlags & (SYNC_PUSH|SYNC_PULL|SYNC_CLONE))==0 | |
| 1312 | 1325 | && configRcvMask==0 && configSendMask==0 ) return 0; |
| 1313 | 1326 | |
| 1314 | 1327 | transport_stats(0, 0, 1); |
| 1315 | 1328 | socket_global_init(); |
| 1316 | 1329 | memset(&xfer, 0, sizeof(xfer)); |
| 1317 | 1330 | xfer.pIn = &recv; |
| 1318 | 1331 | xfer.pOut = &send; |
| 1319 | 1332 | xfer.mxSend = db_get_int("max-upload", 250000); |
| 1320 | - if( privateFlag ){ | |
| 1333 | + if( syncFlags & SYNC_PRIVATE ){ | |
| 1321 | 1334 | g.perm.Private = 1; |
| 1322 | 1335 | xfer.syncPrivate = 1; |
| 1323 | 1336 | } |
| 1324 | 1337 | |
| 1325 | - assert( pushFlag | pullFlag | cloneFlag | configRcvMask | configSendMask ); | |
| 1326 | 1338 | db_begin_transaction(); |
| 1327 | 1339 | db_record_repository_filename(0); |
| 1328 | 1340 | db_multi_exec( |
| 1329 | 1341 | "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);" |
| 1330 | 1342 | ); |
| @@ -1335,33 +1347,39 @@ | ||
| 1335 | 1347 | blob_zero(&xfer.line); |
| 1336 | 1348 | origConfigRcvMask = 0; |
| 1337 | 1349 | |
| 1338 | 1350 | |
| 1339 | 1351 | /* Send the send-private pragma if we are trying to sync private data */ |
| 1340 | - if( privateFlag ) blob_append(&send, "pragma send-private\n", -1); | |
| 1352 | + if( syncFlags & SYNC_PRIVATE ){ | |
| 1353 | + blob_append(&send, "pragma send-private\n", -1); | |
| 1354 | + } | |
| 1341 | 1355 | |
| 1342 | 1356 | /* |
| 1343 | 1357 | ** Always begin with a clone, pull, or push message |
| 1344 | 1358 | */ |
| 1345 | - if( cloneFlag ){ | |
| 1359 | + if( syncFlags & SYNC_CLONE ){ | |
| 1346 | 1360 | blob_appendf(&send, "clone 3 %d\n", cloneSeqno); |
| 1347 | - pushFlag = 0; | |
| 1348 | - pullFlag = 0; | |
| 1361 | + syncFlags &= ~(SYNC_PUSH|SYNC_PULL); | |
| 1349 | 1362 | nCardSent++; |
| 1350 | 1363 | /* TBD: Request all transferable configuration values */ |
| 1351 | 1364 | content_enable_dephantomize(0); |
| 1352 | - }else if( pullFlag ){ | |
| 1365 | + zOpType = "Clone"; | |
| 1366 | + }else if( syncFlags & SYNC_PULL ){ | |
| 1353 | 1367 | blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); |
| 1354 | 1368 | nCardSent++; |
| 1369 | + zOpType = "Pull"; | |
| 1355 | 1370 | } |
| 1356 | - if( pushFlag ){ | |
| 1371 | + if( syncFlags & SYNC_PUSH ){ | |
| 1357 | 1372 | blob_appendf(&send, "push %s %s\n", zSCode, zPCode); |
| 1358 | 1373 | nCardSent++; |
| 1374 | + if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push"; | |
| 1359 | 1375 | } |
| 1360 | 1376 | manifest_crosslink_begin(); |
| 1361 | 1377 | transport_global_startup(); |
| 1362 | - fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas"); | |
| 1378 | + if( syncFlags & SYNC_VERBOSE ){ | |
| 1379 | + fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas"); | |
| 1380 | + } | |
| 1363 | 1381 | |
| 1364 | 1382 | while( go ){ |
| 1365 | 1383 | int newPhantom = 0; |
| 1366 | 1384 | char *zRandomness; |
| 1367 | 1385 | |
| @@ -1374,25 +1392,28 @@ | ||
| 1374 | 1392 | } |
| 1375 | 1393 | |
| 1376 | 1394 | /* Generate gimme cards for phantoms and leaf cards |
| 1377 | 1395 | ** for all leaves. |
| 1378 | 1396 | */ |
| 1379 | - if( pullFlag || (cloneFlag && cloneSeqno==1) ){ | |
| 1397 | + if( (syncFlags & SYNC_PULL)!=0 | |
| 1398 | + || ((syncFlags & SYNC_CLONE)!=0 && cloneSeqno==1) | |
| 1399 | + ){ | |
| 1380 | 1400 | request_phantoms(&xfer, mxPhantomReq); |
| 1381 | 1401 | } |
| 1382 | - if( pushFlag ){ | |
| 1402 | + if( syncFlags & SYNC_PUSH ){ | |
| 1383 | 1403 | send_unsent(&xfer); |
| 1384 | 1404 | nCardSent += send_unclustered(&xfer); |
| 1385 | - if( privateFlag ) send_private(&xfer); | |
| 1405 | + if( syncFlags & SYNC_PRIVATE ) send_private(&xfer); | |
| 1386 | 1406 | } |
| 1387 | 1407 | |
| 1388 | 1408 | /* Send configuration parameter requests. On a clone, delay sending |
| 1389 | 1409 | ** this until the second cycle since the login card might fail on |
| 1390 | 1410 | ** the first cycle. |
| 1391 | 1411 | */ |
| 1392 | - if( configRcvMask && (cloneFlag==0 || nCycle>0) ){ | |
| 1412 | + if( configRcvMask && ((syncFlags & SYNC_CLONE)==0 || nCycle>0) ){ | |
| 1393 | 1413 | const char *zName; |
| 1414 | + if( zOpType==0 ) zOpType = "Pull"; | |
| 1394 | 1415 | zName = configure_first_name(configRcvMask); |
| 1395 | 1416 | while( zName ){ |
| 1396 | 1417 | blob_appendf(&send, "reqconfig %s\n", zName); |
| 1397 | 1418 | zName = configure_next_name(configRcvMask); |
| 1398 | 1419 | nCardSent++; |
| @@ -1407,10 +1428,11 @@ | ||
| 1407 | 1428 | configRcvMask = 0; |
| 1408 | 1429 | } |
| 1409 | 1430 | |
| 1410 | 1431 | /* Send configuration parameters being pushed */ |
| 1411 | 1432 | if( configSendMask ){ |
| 1433 | + if( zOpType==0 ) zOpType = "Push"; | |
| 1412 | 1434 | if( configSendMask & CONFIGSET_OLDFORMAT ){ |
| 1413 | 1435 | const char *zName; |
| 1414 | 1436 | zName = configure_first_name(configSendMask); |
| 1415 | 1437 | while( zName ){ |
| 1416 | 1438 | send_legacy_config_card(&xfer, zName); |
| @@ -1430,42 +1452,50 @@ | ||
| 1430 | 1452 | zRandomness = db_text(0, "SELECT hex(randomblob(20))"); |
| 1431 | 1453 | blob_appendf(&send, "# %s\n", zRandomness); |
| 1432 | 1454 | free(zRandomness); |
| 1433 | 1455 | |
| 1434 | 1456 | /* Exchange messages with the server */ |
| 1435 | - fossil_print(zValueFormat, "Sent:", | |
| 1436 | - blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent, | |
| 1437 | - xfer.nFileSent, xfer.nDeltaSent); | |
| 1457 | + if( syncFlags & SYNC_VERBOSE ){ | |
| 1458 | + fossil_print(zValueFormat, "Sent:", | |
| 1459 | + blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent, | |
| 1460 | + xfer.nFileSent, xfer.nDeltaSent); | |
| 1461 | + }else{ | |
| 1462 | + nRoundtrip++; | |
| 1463 | + nArtifactSent += xfer.nFileSent + xfer.nDeltaSent; | |
| 1464 | + fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd); | |
| 1465 | + } | |
| 1438 | 1466 | nCardSent = 0; |
| 1439 | 1467 | nCardRcvd = 0; |
| 1440 | 1468 | xfer.nFileSent = 0; |
| 1441 | 1469 | xfer.nDeltaSent = 0; |
| 1442 | 1470 | xfer.nGimmeSent = 0; |
| 1443 | 1471 | xfer.nIGotSent = 0; |
| 1444 | - if( !g.cgiOutput && !g.fQuiet ){ | |
| 1472 | + if( syncFlags & SYNC_VERBOSE ){ | |
| 1445 | 1473 | fossil_print("waiting for server..."); |
| 1446 | 1474 | } |
| 1447 | 1475 | fflush(stdout); |
| 1448 | - if( http_exchange(&send, &recv, cloneFlag==0 || nCycle>0) ){ | |
| 1476 | + if( http_exchange(&send, &recv, (syncFlags & SYNC_CLONE)==0 || nCycle>0) ){ | |
| 1449 | 1477 | nErr++; |
| 1450 | 1478 | break; |
| 1451 | 1479 | } |
| 1452 | 1480 | lastPctDone = -1; |
| 1453 | 1481 | blob_reset(&send); |
| 1454 | 1482 | rArrivalTime = db_double(0.0, "SELECT julianday('now')"); |
| 1455 | 1483 | |
| 1456 | 1484 | /* Send the send-private pragma if we are trying to sync private data */ |
| 1457 | - if( privateFlag ) blob_append(&send, "pragma send-private\n", -1); | |
| 1485 | + if( syncFlags & SYNC_PRIVATE ){ | |
| 1486 | + blob_append(&send, "pragma send-private\n", -1); | |
| 1487 | + } | |
| 1458 | 1488 | |
| 1459 | 1489 | /* Begin constructing the next message (which might never be |
| 1460 | 1490 | ** sent) by beginning with the pull or push cards |
| 1461 | 1491 | */ |
| 1462 | - if( pullFlag ){ | |
| 1492 | + if( syncFlags & SYNC_PULL ){ | |
| 1463 | 1493 | blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); |
| 1464 | 1494 | nCardSent++; |
| 1465 | 1495 | } |
| 1466 | - if( pushFlag ){ | |
| 1496 | + if( syncFlags & SYNC_PUSH ){ | |
| 1467 | 1497 | blob_appendf(&send, "push %s %s\n", zSCode, zPCode); |
| 1468 | 1498 | nCardSent++; |
| 1469 | 1499 | } |
| 1470 | 1500 | go = 0; |
| 1471 | 1501 | |
| @@ -1493,11 +1523,11 @@ | ||
| 1493 | 1523 | nCardRcvd++; |
| 1494 | 1524 | continue; |
| 1495 | 1525 | } |
| 1496 | 1526 | xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken)); |
| 1497 | 1527 | nCardRcvd++; |
| 1498 | - if( !g.cgiOutput && !g.fQuiet && recv.nUsed>0 ){ | |
| 1528 | + if( (syncFlags & SYNC_VERBOSE)!=0 && recv.nUsed>0 ){ | |
| 1499 | 1529 | pctDone = (recv.iCursor*100)/recv.nUsed; |
| 1500 | 1530 | if( pctDone!=lastPctDone ){ |
| 1501 | 1531 | fossil_print("\rprocessed: %d%% ", pctDone); |
| 1502 | 1532 | lastPctDone = pctDone; |
| 1503 | 1533 | fflush(stdout); |
| @@ -1508,20 +1538,22 @@ | ||
| 1508 | 1538 | ** file UUID DELTASRC SIZE \n CONTENT |
| 1509 | 1539 | ** |
| 1510 | 1540 | ** Receive a file transmitted from the server. |
| 1511 | 1541 | */ |
| 1512 | 1542 | if( blob_eq(&xfer.aToken[0],"file") ){ |
| 1513 | - xfer_accept_file(&xfer, cloneFlag); | |
| 1543 | + xfer_accept_file(&xfer, (syncFlags & SYNC_CLONE)!=0); | |
| 1544 | + nArtifactRcvd++; | |
| 1514 | 1545 | }else |
| 1515 | 1546 | |
| 1516 | 1547 | /* cfile UUID USIZE CSIZE \n CONTENT |
| 1517 | 1548 | ** cfile UUID DELTASRC USIZE CSIZE \n CONTENT |
| 1518 | 1549 | ** |
| 1519 | 1550 | ** Receive a compressed file transmitted from the server. |
| 1520 | 1551 | */ |
| 1521 | 1552 | if( blob_eq(&xfer.aToken[0],"cfile") ){ |
| 1522 | 1553 | xfer_accept_compressed_file(&xfer); |
| 1554 | + nArtifactRcvd++; | |
| 1523 | 1555 | }else |
| 1524 | 1556 | |
| 1525 | 1557 | /* gimme UUID |
| 1526 | 1558 | ** |
| 1527 | 1559 | ** Server is requesting a file. If the file is a manifest, assume |
| @@ -1530,11 +1562,11 @@ | ||
| 1530 | 1562 | */ |
| 1531 | 1563 | if( blob_eq(&xfer.aToken[0], "gimme") |
| 1532 | 1564 | && xfer.nToken==2 |
| 1533 | 1565 | && blob_is_uuid(&xfer.aToken[1]) |
| 1534 | 1566 | ){ |
| 1535 | - if( pushFlag ){ | |
| 1567 | + if( syncFlags & SYNC_PUSH ){ | |
| 1536 | 1568 | int rid = rid_from_uuid(&xfer.aToken[1], 0, 0); |
| 1537 | 1569 | if( rid ) send_file(&xfer, rid, &xfer.aToken[1], 0); |
| 1538 | 1570 | } |
| 1539 | 1571 | }else |
| 1540 | 1572 | |
| @@ -1559,11 +1591,11 @@ | ||
| 1559 | 1591 | rid = rid_from_uuid(&xfer.aToken[1], 0, 0); |
| 1560 | 1592 | if( rid>0 ){ |
| 1561 | 1593 | if( !isPriv ) content_make_public(rid); |
| 1562 | 1594 | }else if( isPriv && !g.perm.Private ){ |
| 1563 | 1595 | /* ignore private files */ |
| 1564 | - }else if( pullFlag || cloneFlag ){ | |
| 1596 | + }else if( (syncFlags & (SYNC_PULL|SYNC_CLONE))!=0 ){ | |
| 1565 | 1597 | rid = content_new(blob_str(&xfer.aToken[1]), isPriv); |
| 1566 | 1598 | if( rid ) newPhantom = 1; |
| 1567 | 1599 | } |
| 1568 | 1600 | remote_has(rid); |
| 1569 | 1601 | }else |
| @@ -1574,11 +1606,11 @@ | ||
| 1574 | 1606 | ** Should only happen in response to a clone. This message tells |
| 1575 | 1607 | ** the client what product to use for the new database. |
| 1576 | 1608 | */ |
| 1577 | 1609 | if( blob_eq(&xfer.aToken[0],"push") |
| 1578 | 1610 | && xfer.nToken==3 |
| 1579 | - && cloneFlag | |
| 1611 | + && (syncFlags & SYNC_CLONE)!=0 | |
| 1580 | 1612 | && blob_is_uuid(&xfer.aToken[1]) |
| 1581 | 1613 | && blob_is_uuid(&xfer.aToken[2]) |
| 1582 | 1614 | ){ |
| 1583 | 1615 | if( blob_eq_str(&xfer.aToken[1], zSCode, -1) ){ |
| 1584 | 1616 | fossil_fatal("server loop"); |
| @@ -1604,11 +1636,12 @@ | ||
| 1604 | 1636 | Blob content; |
| 1605 | 1637 | blob_zero(&content); |
| 1606 | 1638 | blob_extract(xfer.pIn, size, &content); |
| 1607 | 1639 | g.perm.Admin = g.perm.RdAddr = 1; |
| 1608 | 1640 | configure_receive(zName, &content, origConfigRcvMask); |
| 1609 | - nCardSent++; | |
| 1641 | + nCardRcvd++; | |
| 1642 | + nArtifactRcvd++; | |
| 1610 | 1643 | blob_reset(&content); |
| 1611 | 1644 | blob_seek(xfer.pIn, 1, BLOB_SEEK_CUR); |
| 1612 | 1645 | }else |
| 1613 | 1646 | |
| 1614 | 1647 | |
| @@ -1655,12 +1688,12 @@ | ||
| 1655 | 1688 | ** to the next cycle. |
| 1656 | 1689 | */ |
| 1657 | 1690 | if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){ |
| 1658 | 1691 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1659 | 1692 | defossilize(zMsg); |
| 1660 | - if( pushFlag && zMsg && strglob("pull only *", zMsg) ){ | |
| 1661 | - pushFlag = 0; | |
| 1693 | + if( (syncFlags & SYNC_PUSH) && zMsg && strglob("pull only *", zMsg) ){ | |
| 1694 | + syncFlags &= ~SYNC_PUSH; | |
| 1662 | 1695 | zMsg = 0; |
| 1663 | 1696 | } |
| 1664 | 1697 | fossil_print("\rServer says: %s\n", zMsg); |
| 1665 | 1698 | }else |
| 1666 | 1699 | |
| @@ -1683,11 +1716,11 @@ | ||
| 1683 | 1716 | ** is returned in the reply before the error card, so second and |
| 1684 | 1717 | ** subsequent messages should be OK. Nevertheless, we need to ignore |
| 1685 | 1718 | ** the error card on the first message of a clone. |
| 1686 | 1719 | */ |
| 1687 | 1720 | if( blob_eq(&xfer.aToken[0],"error") && xfer.nToken==2 ){ |
| 1688 | - if( !cloneFlag || nCycle>0 ){ | |
| 1721 | + if( (syncFlags & SYNC_CLONE)==0 || nCycle>0 ){ | |
| 1689 | 1722 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1690 | 1723 | defossilize(zMsg); |
| 1691 | 1724 | if( fossil_strcmp(zMsg, "login failed")==0 ){ |
| 1692 | 1725 | if( nCycle<2 ){ |
| 1693 | 1726 | if( !g.dontKeepUrl ) db_unset("last-sync-pw", 0); |
| @@ -1727,14 +1760,16 @@ | ||
| 1727 | 1760 | && (configRcvMask & CONFIGSET_OLDFORMAT)!=0 |
| 1728 | 1761 | ){ |
| 1729 | 1762 | configure_finalize_receive(); |
| 1730 | 1763 | } |
| 1731 | 1764 | origConfigRcvMask = 0; |
| 1732 | - if( nCardRcvd>0 ){ | |
| 1765 | + if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){ | |
| 1733 | 1766 | fossil_print(zValueFormat, "Received:", |
| 1734 | 1767 | blob_size(&recv), nCardRcvd, |
| 1735 | 1768 | xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile); |
| 1769 | + }else{ | |
| 1770 | + fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd); | |
| 1736 | 1771 | } |
| 1737 | 1772 | blob_reset(&recv); |
| 1738 | 1773 | nCycle++; |
| 1739 | 1774 | |
| 1740 | 1775 | /* If we received one or more files on the previous exchange but |
| @@ -1743,11 +1778,11 @@ | ||
| 1743 | 1778 | nFileRecv = xfer.nFileRcvd + xfer.nDeltaRcvd + xfer.nDanglingFile; |
| 1744 | 1779 | if( (nFileRecv>0 || newPhantom) && db_exists("SELECT 1 FROM phantom") ){ |
| 1745 | 1780 | go = 1; |
| 1746 | 1781 | mxPhantomReq = nFileRecv*2; |
| 1747 | 1782 | if( mxPhantomReq<200 ) mxPhantomReq = 200; |
| 1748 | - }else if( cloneFlag && nFileRecv>0 ){ | |
| 1783 | + }else if( (syncFlags & SYNC_CLONE)!=0 && nFileRecv>0 ){ | |
| 1749 | 1784 | go = 1; |
| 1750 | 1785 | } |
| 1751 | 1786 | nCardRcvd = 0; |
| 1752 | 1787 | xfer.nFileRcvd = 0; |
| 1753 | 1788 | xfer.nDeltaRcvd = 0; |
| @@ -1759,25 +1794,27 @@ | ||
| 1759 | 1794 | if( xfer.nFileSent+xfer.nDeltaSent>0 ){ |
| 1760 | 1795 | go = 1; |
| 1761 | 1796 | } |
| 1762 | 1797 | |
| 1763 | 1798 | /* If this is a clone, the go at least two rounds */ |
| 1764 | - if( cloneFlag && nCycle==1 ) go = 1; | |
| 1799 | + if( (syncFlags & SYNC_CLONE)!=0 && nCycle==1 ) go = 1; | |
| 1765 | 1800 | |
| 1766 | 1801 | /* Stop the cycle if the server sends a "clone_seqno 0" card and |
| 1767 | 1802 | ** we have gone at least two rounds. Always go at least two rounds |
| 1768 | 1803 | ** on a clone in order to be sure to retrieve the configuration |
| 1769 | 1804 | ** information which is only sent on the second round. |
| 1770 | 1805 | */ |
| 1771 | 1806 | if( cloneSeqno<=0 && nCycle>1 ) go = 0; |
| 1772 | 1807 | }; |
| 1773 | 1808 | transport_stats(&nSent, &nRcvd, 1); |
| 1774 | - fossil_print("Total network traffic: %lld bytes sent, %lld bytes received\n", | |
| 1775 | - nSent, nRcvd); | |
| 1809 | + if( (syncFlags & SYNC_VERBOSE)==0 ) fossil_print("\n"); | |
| 1810 | + fossil_print( | |
| 1811 | + "%s finished with %lld bytes sent, %lld bytes received\n", | |
| 1812 | + zOpType, nSent, nRcvd); | |
| 1776 | 1813 | transport_close(); |
| 1777 | 1814 | transport_global_shutdown(); |
| 1778 | 1815 | db_multi_exec("DROP TABLE onremote"); |
| 1779 | 1816 | manifest_crosslink_end(); |
| 1780 | 1817 | content_enable_dephantomize(1); |
| 1781 | 1818 | db_end_transaction(0); |
| 1782 | 1819 | return nErr; |
| 1783 | 1820 | } |
| 1784 | 1821 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -1266,11 +1266,23 @@ | |
| 1266 | /* |
| 1267 | ** Format strings for progress reporting. |
| 1268 | */ |
| 1269 | static const char zLabelFormat[] = "%-10s %10s %10s %10s %10s\n"; |
| 1270 | static const char zValueFormat[] = "\r%-10s %10d %10d %10d %10d\n"; |
| 1271 | |
| 1272 | |
| 1273 | /* |
| 1274 | ** Sync to the host identified in g.urlName and g.urlPath. This |
| 1275 | ** routine is called by the client. |
| 1276 | ** |
| @@ -1277,16 +1289,13 @@ | |
| 1277 | ** Records are pushed to the server if pushFlag is true. Records |
| 1278 | ** are pulled if pullFlag is true. A full sync occurs if both are |
| 1279 | ** true. |
| 1280 | */ |
| 1281 | int client_sync( |
| 1282 | int pushFlag, /* True to do a push (or a sync) */ |
| 1283 | int pullFlag, /* True to do a pull (or a sync) */ |
| 1284 | int cloneFlag, /* True if this is a clone */ |
| 1285 | int privateFlag, /* True to exchange private branches */ |
| 1286 | int configRcvMask, /* Receive these configuration items */ |
| 1287 | int configSendMask /* Send these configuration items */ |
| 1288 | ){ |
| 1289 | int go = 1; /* Loop until zero */ |
| 1290 | int nCardSent = 0; /* Number of cards sent */ |
| 1291 | int nCardRcvd = 0; /* Number of cards received */ |
| 1292 | int nCycle = 0; /* Number of round trips to the server */ |
| @@ -1304,27 +1313,30 @@ | |
| 1304 | int lastPctDone = -1; /* Last displayed pctDone */ |
| 1305 | double rArrivalTime; /* Time at which a message arrived */ |
| 1306 | const char *zSCode = db_get("server-code", "x"); |
| 1307 | const char *zPCode = db_get("project-code", 0); |
| 1308 | int nErr = 0; /* Number of errors */ |
| 1309 | |
| 1310 | if( db_get_boolean("dont-push", 0) ) pushFlag = 0; |
| 1311 | if( pushFlag + pullFlag + cloneFlag == 0 |
| 1312 | && configRcvMask==0 && configSendMask==0 ) return 0; |
| 1313 | |
| 1314 | transport_stats(0, 0, 1); |
| 1315 | socket_global_init(); |
| 1316 | memset(&xfer, 0, sizeof(xfer)); |
| 1317 | xfer.pIn = &recv; |
| 1318 | xfer.pOut = &send; |
| 1319 | xfer.mxSend = db_get_int("max-upload", 250000); |
| 1320 | if( privateFlag ){ |
| 1321 | g.perm.Private = 1; |
| 1322 | xfer.syncPrivate = 1; |
| 1323 | } |
| 1324 | |
| 1325 | assert( pushFlag | pullFlag | cloneFlag | configRcvMask | configSendMask ); |
| 1326 | db_begin_transaction(); |
| 1327 | db_record_repository_filename(0); |
| 1328 | db_multi_exec( |
| 1329 | "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);" |
| 1330 | ); |
| @@ -1335,33 +1347,39 @@ | |
| 1335 | blob_zero(&xfer.line); |
| 1336 | origConfigRcvMask = 0; |
| 1337 | |
| 1338 | |
| 1339 | /* Send the send-private pragma if we are trying to sync private data */ |
| 1340 | if( privateFlag ) blob_append(&send, "pragma send-private\n", -1); |
| 1341 | |
| 1342 | /* |
| 1343 | ** Always begin with a clone, pull, or push message |
| 1344 | */ |
| 1345 | if( cloneFlag ){ |
| 1346 | blob_appendf(&send, "clone 3 %d\n", cloneSeqno); |
| 1347 | pushFlag = 0; |
| 1348 | pullFlag = 0; |
| 1349 | nCardSent++; |
| 1350 | /* TBD: Request all transferable configuration values */ |
| 1351 | content_enable_dephantomize(0); |
| 1352 | }else if( pullFlag ){ |
| 1353 | blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); |
| 1354 | nCardSent++; |
| 1355 | } |
| 1356 | if( pushFlag ){ |
| 1357 | blob_appendf(&send, "push %s %s\n", zSCode, zPCode); |
| 1358 | nCardSent++; |
| 1359 | } |
| 1360 | manifest_crosslink_begin(); |
| 1361 | transport_global_startup(); |
| 1362 | fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas"); |
| 1363 | |
| 1364 | while( go ){ |
| 1365 | int newPhantom = 0; |
| 1366 | char *zRandomness; |
| 1367 | |
| @@ -1374,25 +1392,28 @@ | |
| 1374 | } |
| 1375 | |
| 1376 | /* Generate gimme cards for phantoms and leaf cards |
| 1377 | ** for all leaves. |
| 1378 | */ |
| 1379 | if( pullFlag || (cloneFlag && cloneSeqno==1) ){ |
| 1380 | request_phantoms(&xfer, mxPhantomReq); |
| 1381 | } |
| 1382 | if( pushFlag ){ |
| 1383 | send_unsent(&xfer); |
| 1384 | nCardSent += send_unclustered(&xfer); |
| 1385 | if( privateFlag ) send_private(&xfer); |
| 1386 | } |
| 1387 | |
| 1388 | /* Send configuration parameter requests. On a clone, delay sending |
| 1389 | ** this until the second cycle since the login card might fail on |
| 1390 | ** the first cycle. |
| 1391 | */ |
| 1392 | if( configRcvMask && (cloneFlag==0 || nCycle>0) ){ |
| 1393 | const char *zName; |
| 1394 | zName = configure_first_name(configRcvMask); |
| 1395 | while( zName ){ |
| 1396 | blob_appendf(&send, "reqconfig %s\n", zName); |
| 1397 | zName = configure_next_name(configRcvMask); |
| 1398 | nCardSent++; |
| @@ -1407,10 +1428,11 @@ | |
| 1407 | configRcvMask = 0; |
| 1408 | } |
| 1409 | |
| 1410 | /* Send configuration parameters being pushed */ |
| 1411 | if( configSendMask ){ |
| 1412 | if( configSendMask & CONFIGSET_OLDFORMAT ){ |
| 1413 | const char *zName; |
| 1414 | zName = configure_first_name(configSendMask); |
| 1415 | while( zName ){ |
| 1416 | send_legacy_config_card(&xfer, zName); |
| @@ -1430,42 +1452,50 @@ | |
| 1430 | zRandomness = db_text(0, "SELECT hex(randomblob(20))"); |
| 1431 | blob_appendf(&send, "# %s\n", zRandomness); |
| 1432 | free(zRandomness); |
| 1433 | |
| 1434 | /* Exchange messages with the server */ |
| 1435 | fossil_print(zValueFormat, "Sent:", |
| 1436 | blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent, |
| 1437 | xfer.nFileSent, xfer.nDeltaSent); |
| 1438 | nCardSent = 0; |
| 1439 | nCardRcvd = 0; |
| 1440 | xfer.nFileSent = 0; |
| 1441 | xfer.nDeltaSent = 0; |
| 1442 | xfer.nGimmeSent = 0; |
| 1443 | xfer.nIGotSent = 0; |
| 1444 | if( !g.cgiOutput && !g.fQuiet ){ |
| 1445 | fossil_print("waiting for server..."); |
| 1446 | } |
| 1447 | fflush(stdout); |
| 1448 | if( http_exchange(&send, &recv, cloneFlag==0 || nCycle>0) ){ |
| 1449 | nErr++; |
| 1450 | break; |
| 1451 | } |
| 1452 | lastPctDone = -1; |
| 1453 | blob_reset(&send); |
| 1454 | rArrivalTime = db_double(0.0, "SELECT julianday('now')"); |
| 1455 | |
| 1456 | /* Send the send-private pragma if we are trying to sync private data */ |
| 1457 | if( privateFlag ) blob_append(&send, "pragma send-private\n", -1); |
| 1458 | |
| 1459 | /* Begin constructing the next message (which might never be |
| 1460 | ** sent) by beginning with the pull or push cards |
| 1461 | */ |
| 1462 | if( pullFlag ){ |
| 1463 | blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); |
| 1464 | nCardSent++; |
| 1465 | } |
| 1466 | if( pushFlag ){ |
| 1467 | blob_appendf(&send, "push %s %s\n", zSCode, zPCode); |
| 1468 | nCardSent++; |
| 1469 | } |
| 1470 | go = 0; |
| 1471 | |
| @@ -1493,11 +1523,11 @@ | |
| 1493 | nCardRcvd++; |
| 1494 | continue; |
| 1495 | } |
| 1496 | xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken)); |
| 1497 | nCardRcvd++; |
| 1498 | if( !g.cgiOutput && !g.fQuiet && recv.nUsed>0 ){ |
| 1499 | pctDone = (recv.iCursor*100)/recv.nUsed; |
| 1500 | if( pctDone!=lastPctDone ){ |
| 1501 | fossil_print("\rprocessed: %d%% ", pctDone); |
| 1502 | lastPctDone = pctDone; |
| 1503 | fflush(stdout); |
| @@ -1508,20 +1538,22 @@ | |
| 1508 | ** file UUID DELTASRC SIZE \n CONTENT |
| 1509 | ** |
| 1510 | ** Receive a file transmitted from the server. |
| 1511 | */ |
| 1512 | if( blob_eq(&xfer.aToken[0],"file") ){ |
| 1513 | xfer_accept_file(&xfer, cloneFlag); |
| 1514 | }else |
| 1515 | |
| 1516 | /* cfile UUID USIZE CSIZE \n CONTENT |
| 1517 | ** cfile UUID DELTASRC USIZE CSIZE \n CONTENT |
| 1518 | ** |
| 1519 | ** Receive a compressed file transmitted from the server. |
| 1520 | */ |
| 1521 | if( blob_eq(&xfer.aToken[0],"cfile") ){ |
| 1522 | xfer_accept_compressed_file(&xfer); |
| 1523 | }else |
| 1524 | |
| 1525 | /* gimme UUID |
| 1526 | ** |
| 1527 | ** Server is requesting a file. If the file is a manifest, assume |
| @@ -1530,11 +1562,11 @@ | |
| 1530 | */ |
| 1531 | if( blob_eq(&xfer.aToken[0], "gimme") |
| 1532 | && xfer.nToken==2 |
| 1533 | && blob_is_uuid(&xfer.aToken[1]) |
| 1534 | ){ |
| 1535 | if( pushFlag ){ |
| 1536 | int rid = rid_from_uuid(&xfer.aToken[1], 0, 0); |
| 1537 | if( rid ) send_file(&xfer, rid, &xfer.aToken[1], 0); |
| 1538 | } |
| 1539 | }else |
| 1540 | |
| @@ -1559,11 +1591,11 @@ | |
| 1559 | rid = rid_from_uuid(&xfer.aToken[1], 0, 0); |
| 1560 | if( rid>0 ){ |
| 1561 | if( !isPriv ) content_make_public(rid); |
| 1562 | }else if( isPriv && !g.perm.Private ){ |
| 1563 | /* ignore private files */ |
| 1564 | }else if( pullFlag || cloneFlag ){ |
| 1565 | rid = content_new(blob_str(&xfer.aToken[1]), isPriv); |
| 1566 | if( rid ) newPhantom = 1; |
| 1567 | } |
| 1568 | remote_has(rid); |
| 1569 | }else |
| @@ -1574,11 +1606,11 @@ | |
| 1574 | ** Should only happen in response to a clone. This message tells |
| 1575 | ** the client what product to use for the new database. |
| 1576 | */ |
| 1577 | if( blob_eq(&xfer.aToken[0],"push") |
| 1578 | && xfer.nToken==3 |
| 1579 | && cloneFlag |
| 1580 | && blob_is_uuid(&xfer.aToken[1]) |
| 1581 | && blob_is_uuid(&xfer.aToken[2]) |
| 1582 | ){ |
| 1583 | if( blob_eq_str(&xfer.aToken[1], zSCode, -1) ){ |
| 1584 | fossil_fatal("server loop"); |
| @@ -1604,11 +1636,12 @@ | |
| 1604 | Blob content; |
| 1605 | blob_zero(&content); |
| 1606 | blob_extract(xfer.pIn, size, &content); |
| 1607 | g.perm.Admin = g.perm.RdAddr = 1; |
| 1608 | configure_receive(zName, &content, origConfigRcvMask); |
| 1609 | nCardSent++; |
| 1610 | blob_reset(&content); |
| 1611 | blob_seek(xfer.pIn, 1, BLOB_SEEK_CUR); |
| 1612 | }else |
| 1613 | |
| 1614 | |
| @@ -1655,12 +1688,12 @@ | |
| 1655 | ** to the next cycle. |
| 1656 | */ |
| 1657 | if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){ |
| 1658 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1659 | defossilize(zMsg); |
| 1660 | if( pushFlag && zMsg && strglob("pull only *", zMsg) ){ |
| 1661 | pushFlag = 0; |
| 1662 | zMsg = 0; |
| 1663 | } |
| 1664 | fossil_print("\rServer says: %s\n", zMsg); |
| 1665 | }else |
| 1666 | |
| @@ -1683,11 +1716,11 @@ | |
| 1683 | ** is returned in the reply before the error card, so second and |
| 1684 | ** subsequent messages should be OK. Nevertheless, we need to ignore |
| 1685 | ** the error card on the first message of a clone. |
| 1686 | */ |
| 1687 | if( blob_eq(&xfer.aToken[0],"error") && xfer.nToken==2 ){ |
| 1688 | if( !cloneFlag || nCycle>0 ){ |
| 1689 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1690 | defossilize(zMsg); |
| 1691 | if( fossil_strcmp(zMsg, "login failed")==0 ){ |
| 1692 | if( nCycle<2 ){ |
| 1693 | if( !g.dontKeepUrl ) db_unset("last-sync-pw", 0); |
| @@ -1727,14 +1760,16 @@ | |
| 1727 | && (configRcvMask & CONFIGSET_OLDFORMAT)!=0 |
| 1728 | ){ |
| 1729 | configure_finalize_receive(); |
| 1730 | } |
| 1731 | origConfigRcvMask = 0; |
| 1732 | if( nCardRcvd>0 ){ |
| 1733 | fossil_print(zValueFormat, "Received:", |
| 1734 | blob_size(&recv), nCardRcvd, |
| 1735 | xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile); |
| 1736 | } |
| 1737 | blob_reset(&recv); |
| 1738 | nCycle++; |
| 1739 | |
| 1740 | /* If we received one or more files on the previous exchange but |
| @@ -1743,11 +1778,11 @@ | |
| 1743 | nFileRecv = xfer.nFileRcvd + xfer.nDeltaRcvd + xfer.nDanglingFile; |
| 1744 | if( (nFileRecv>0 || newPhantom) && db_exists("SELECT 1 FROM phantom") ){ |
| 1745 | go = 1; |
| 1746 | mxPhantomReq = nFileRecv*2; |
| 1747 | if( mxPhantomReq<200 ) mxPhantomReq = 200; |
| 1748 | }else if( cloneFlag && nFileRecv>0 ){ |
| 1749 | go = 1; |
| 1750 | } |
| 1751 | nCardRcvd = 0; |
| 1752 | xfer.nFileRcvd = 0; |
| 1753 | xfer.nDeltaRcvd = 0; |
| @@ -1759,25 +1794,27 @@ | |
| 1759 | if( xfer.nFileSent+xfer.nDeltaSent>0 ){ |
| 1760 | go = 1; |
| 1761 | } |
| 1762 | |
| 1763 | /* If this is a clone, the go at least two rounds */ |
| 1764 | if( cloneFlag && nCycle==1 ) go = 1; |
| 1765 | |
| 1766 | /* Stop the cycle if the server sends a "clone_seqno 0" card and |
| 1767 | ** we have gone at least two rounds. Always go at least two rounds |
| 1768 | ** on a clone in order to be sure to retrieve the configuration |
| 1769 | ** information which is only sent on the second round. |
| 1770 | */ |
| 1771 | if( cloneSeqno<=0 && nCycle>1 ) go = 0; |
| 1772 | }; |
| 1773 | transport_stats(&nSent, &nRcvd, 1); |
| 1774 | fossil_print("Total network traffic: %lld bytes sent, %lld bytes received\n", |
| 1775 | nSent, nRcvd); |
| 1776 | transport_close(); |
| 1777 | transport_global_shutdown(); |
| 1778 | db_multi_exec("DROP TABLE onremote"); |
| 1779 | manifest_crosslink_end(); |
| 1780 | content_enable_dephantomize(1); |
| 1781 | db_end_transaction(0); |
| 1782 | return nErr; |
| 1783 | } |
| 1784 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -1266,11 +1266,23 @@ | |
| 1266 | /* |
| 1267 | ** Format strings for progress reporting. |
| 1268 | */ |
| 1269 | static const char zLabelFormat[] = "%-10s %10s %10s %10s %10s\n"; |
| 1270 | static const char zValueFormat[] = "\r%-10s %10d %10d %10d %10d\n"; |
| 1271 | static const char zBriefFormat[] = |
| 1272 | "Round-trips: %d Artifacts sent: %d received: %d\r"; |
| 1273 | |
| 1274 | #if INTERFACE |
| 1275 | /* |
| 1276 | ** Flag options for controlling client_sync() |
| 1277 | */ |
| 1278 | #define SYNC_PUSH 0x0001 |
| 1279 | #define SYNC_PULL 0x0002 |
| 1280 | #define SYNC_CLONE 0x0004 |
| 1281 | #define SYNC_PRIVATE 0x0008 |
| 1282 | #define SYNC_VERBOSE 0x0010 |
| 1283 | #endif |
| 1284 | |
| 1285 | /* |
| 1286 | ** Sync to the host identified in g.urlName and g.urlPath. This |
| 1287 | ** routine is called by the client. |
| 1288 | ** |
| @@ -1277,16 +1289,13 @@ | |
| 1289 | ** Records are pushed to the server if pushFlag is true. Records |
| 1290 | ** are pulled if pullFlag is true. A full sync occurs if both are |
| 1291 | ** true. |
| 1292 | */ |
| 1293 | int client_sync( |
| 1294 | unsigned syncFlags, /* Mask of SYNC_* flags */ |
| 1295 | unsigned configRcvMask, /* Receive these configuration items */ |
| 1296 | unsigned configSendMask /* Send these configuration items */ |
| 1297 | ){ |
| 1298 | int go = 1; /* Loop until zero */ |
| 1299 | int nCardSent = 0; /* Number of cards sent */ |
| 1300 | int nCardRcvd = 0; /* Number of cards received */ |
| 1301 | int nCycle = 0; /* Number of round trips to the server */ |
| @@ -1304,27 +1313,30 @@ | |
| 1313 | int lastPctDone = -1; /* Last displayed pctDone */ |
| 1314 | double rArrivalTime; /* Time at which a message arrived */ |
| 1315 | const char *zSCode = db_get("server-code", "x"); |
| 1316 | const char *zPCode = db_get("project-code", 0); |
| 1317 | int nErr = 0; /* Number of errors */ |
| 1318 | int nRoundtrip= 0; /* Number of HTTP requests */ |
| 1319 | int nArtifactSent = 0; /* Total artifacts sent */ |
| 1320 | int nArtifactRcvd = 0; /* Total artifacts received */ |
| 1321 | const char *zOpType = 0;/* Push, Pull, Sync, Clone */ |
| 1322 | |
| 1323 | if( db_get_boolean("dont-push", 0) ) syncFlags &= ~SYNC_PUSH; |
| 1324 | if( (syncFlags & (SYNC_PUSH|SYNC_PULL|SYNC_CLONE))==0 |
| 1325 | && configRcvMask==0 && configSendMask==0 ) return 0; |
| 1326 | |
| 1327 | transport_stats(0, 0, 1); |
| 1328 | socket_global_init(); |
| 1329 | memset(&xfer, 0, sizeof(xfer)); |
| 1330 | xfer.pIn = &recv; |
| 1331 | xfer.pOut = &send; |
| 1332 | xfer.mxSend = db_get_int("max-upload", 250000); |
| 1333 | if( syncFlags & SYNC_PRIVATE ){ |
| 1334 | g.perm.Private = 1; |
| 1335 | xfer.syncPrivate = 1; |
| 1336 | } |
| 1337 | |
| 1338 | db_begin_transaction(); |
| 1339 | db_record_repository_filename(0); |
| 1340 | db_multi_exec( |
| 1341 | "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);" |
| 1342 | ); |
| @@ -1335,33 +1347,39 @@ | |
| 1347 | blob_zero(&xfer.line); |
| 1348 | origConfigRcvMask = 0; |
| 1349 | |
| 1350 | |
| 1351 | /* Send the send-private pragma if we are trying to sync private data */ |
| 1352 | if( syncFlags & SYNC_PRIVATE ){ |
| 1353 | blob_append(&send, "pragma send-private\n", -1); |
| 1354 | } |
| 1355 | |
| 1356 | /* |
| 1357 | ** Always begin with a clone, pull, or push message |
| 1358 | */ |
| 1359 | if( syncFlags & SYNC_CLONE ){ |
| 1360 | blob_appendf(&send, "clone 3 %d\n", cloneSeqno); |
| 1361 | syncFlags &= ~(SYNC_PUSH|SYNC_PULL); |
| 1362 | nCardSent++; |
| 1363 | /* TBD: Request all transferable configuration values */ |
| 1364 | content_enable_dephantomize(0); |
| 1365 | zOpType = "Clone"; |
| 1366 | }else if( syncFlags & SYNC_PULL ){ |
| 1367 | blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); |
| 1368 | nCardSent++; |
| 1369 | zOpType = "Pull"; |
| 1370 | } |
| 1371 | if( syncFlags & SYNC_PUSH ){ |
| 1372 | blob_appendf(&send, "push %s %s\n", zSCode, zPCode); |
| 1373 | nCardSent++; |
| 1374 | if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push"; |
| 1375 | } |
| 1376 | manifest_crosslink_begin(); |
| 1377 | transport_global_startup(); |
| 1378 | if( syncFlags & SYNC_VERBOSE ){ |
| 1379 | fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas"); |
| 1380 | } |
| 1381 | |
| 1382 | while( go ){ |
| 1383 | int newPhantom = 0; |
| 1384 | char *zRandomness; |
| 1385 | |
| @@ -1374,25 +1392,28 @@ | |
| 1392 | } |
| 1393 | |
| 1394 | /* Generate gimme cards for phantoms and leaf cards |
| 1395 | ** for all leaves. |
| 1396 | */ |
| 1397 | if( (syncFlags & SYNC_PULL)!=0 |
| 1398 | || ((syncFlags & SYNC_CLONE)!=0 && cloneSeqno==1) |
| 1399 | ){ |
| 1400 | request_phantoms(&xfer, mxPhantomReq); |
| 1401 | } |
| 1402 | if( syncFlags & SYNC_PUSH ){ |
| 1403 | send_unsent(&xfer); |
| 1404 | nCardSent += send_unclustered(&xfer); |
| 1405 | if( syncFlags & SYNC_PRIVATE ) send_private(&xfer); |
| 1406 | } |
| 1407 | |
| 1408 | /* Send configuration parameter requests. On a clone, delay sending |
| 1409 | ** this until the second cycle since the login card might fail on |
| 1410 | ** the first cycle. |
| 1411 | */ |
| 1412 | if( configRcvMask && ((syncFlags & SYNC_CLONE)==0 || nCycle>0) ){ |
| 1413 | const char *zName; |
| 1414 | if( zOpType==0 ) zOpType = "Pull"; |
| 1415 | zName = configure_first_name(configRcvMask); |
| 1416 | while( zName ){ |
| 1417 | blob_appendf(&send, "reqconfig %s\n", zName); |
| 1418 | zName = configure_next_name(configRcvMask); |
| 1419 | nCardSent++; |
| @@ -1407,10 +1428,11 @@ | |
| 1428 | configRcvMask = 0; |
| 1429 | } |
| 1430 | |
| 1431 | /* Send configuration parameters being pushed */ |
| 1432 | if( configSendMask ){ |
| 1433 | if( zOpType==0 ) zOpType = "Push"; |
| 1434 | if( configSendMask & CONFIGSET_OLDFORMAT ){ |
| 1435 | const char *zName; |
| 1436 | zName = configure_first_name(configSendMask); |
| 1437 | while( zName ){ |
| 1438 | send_legacy_config_card(&xfer, zName); |
| @@ -1430,42 +1452,50 @@ | |
| 1452 | zRandomness = db_text(0, "SELECT hex(randomblob(20))"); |
| 1453 | blob_appendf(&send, "# %s\n", zRandomness); |
| 1454 | free(zRandomness); |
| 1455 | |
| 1456 | /* Exchange messages with the server */ |
| 1457 | if( syncFlags & SYNC_VERBOSE ){ |
| 1458 | fossil_print(zValueFormat, "Sent:", |
| 1459 | blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent, |
| 1460 | xfer.nFileSent, xfer.nDeltaSent); |
| 1461 | }else{ |
| 1462 | nRoundtrip++; |
| 1463 | nArtifactSent += xfer.nFileSent + xfer.nDeltaSent; |
| 1464 | fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd); |
| 1465 | } |
| 1466 | nCardSent = 0; |
| 1467 | nCardRcvd = 0; |
| 1468 | xfer.nFileSent = 0; |
| 1469 | xfer.nDeltaSent = 0; |
| 1470 | xfer.nGimmeSent = 0; |
| 1471 | xfer.nIGotSent = 0; |
| 1472 | if( syncFlags & SYNC_VERBOSE ){ |
| 1473 | fossil_print("waiting for server..."); |
| 1474 | } |
| 1475 | fflush(stdout); |
| 1476 | if( http_exchange(&send, &recv, (syncFlags & SYNC_CLONE)==0 || nCycle>0) ){ |
| 1477 | nErr++; |
| 1478 | break; |
| 1479 | } |
| 1480 | lastPctDone = -1; |
| 1481 | blob_reset(&send); |
| 1482 | rArrivalTime = db_double(0.0, "SELECT julianday('now')"); |
| 1483 | |
| 1484 | /* Send the send-private pragma if we are trying to sync private data */ |
| 1485 | if( syncFlags & SYNC_PRIVATE ){ |
| 1486 | blob_append(&send, "pragma send-private\n", -1); |
| 1487 | } |
| 1488 | |
| 1489 | /* Begin constructing the next message (which might never be |
| 1490 | ** sent) by beginning with the pull or push cards |
| 1491 | */ |
| 1492 | if( syncFlags & SYNC_PULL ){ |
| 1493 | blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); |
| 1494 | nCardSent++; |
| 1495 | } |
| 1496 | if( syncFlags & SYNC_PUSH ){ |
| 1497 | blob_appendf(&send, "push %s %s\n", zSCode, zPCode); |
| 1498 | nCardSent++; |
| 1499 | } |
| 1500 | go = 0; |
| 1501 | |
| @@ -1493,11 +1523,11 @@ | |
| 1523 | nCardRcvd++; |
| 1524 | continue; |
| 1525 | } |
| 1526 | xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken)); |
| 1527 | nCardRcvd++; |
| 1528 | if( (syncFlags & SYNC_VERBOSE)!=0 && recv.nUsed>0 ){ |
| 1529 | pctDone = (recv.iCursor*100)/recv.nUsed; |
| 1530 | if( pctDone!=lastPctDone ){ |
| 1531 | fossil_print("\rprocessed: %d%% ", pctDone); |
| 1532 | lastPctDone = pctDone; |
| 1533 | fflush(stdout); |
| @@ -1508,20 +1538,22 @@ | |
| 1538 | ** file UUID DELTASRC SIZE \n CONTENT |
| 1539 | ** |
| 1540 | ** Receive a file transmitted from the server. |
| 1541 | */ |
| 1542 | if( blob_eq(&xfer.aToken[0],"file") ){ |
| 1543 | xfer_accept_file(&xfer, (syncFlags & SYNC_CLONE)!=0); |
| 1544 | nArtifactRcvd++; |
| 1545 | }else |
| 1546 | |
| 1547 | /* cfile UUID USIZE CSIZE \n CONTENT |
| 1548 | ** cfile UUID DELTASRC USIZE CSIZE \n CONTENT |
| 1549 | ** |
| 1550 | ** Receive a compressed file transmitted from the server. |
| 1551 | */ |
| 1552 | if( blob_eq(&xfer.aToken[0],"cfile") ){ |
| 1553 | xfer_accept_compressed_file(&xfer); |
| 1554 | nArtifactRcvd++; |
| 1555 | }else |
| 1556 | |
| 1557 | /* gimme UUID |
| 1558 | ** |
| 1559 | ** Server is requesting a file. If the file is a manifest, assume |
| @@ -1530,11 +1562,11 @@ | |
| 1562 | */ |
| 1563 | if( blob_eq(&xfer.aToken[0], "gimme") |
| 1564 | && xfer.nToken==2 |
| 1565 | && blob_is_uuid(&xfer.aToken[1]) |
| 1566 | ){ |
| 1567 | if( syncFlags & SYNC_PUSH ){ |
| 1568 | int rid = rid_from_uuid(&xfer.aToken[1], 0, 0); |
| 1569 | if( rid ) send_file(&xfer, rid, &xfer.aToken[1], 0); |
| 1570 | } |
| 1571 | }else |
| 1572 | |
| @@ -1559,11 +1591,11 @@ | |
| 1591 | rid = rid_from_uuid(&xfer.aToken[1], 0, 0); |
| 1592 | if( rid>0 ){ |
| 1593 | if( !isPriv ) content_make_public(rid); |
| 1594 | }else if( isPriv && !g.perm.Private ){ |
| 1595 | /* ignore private files */ |
| 1596 | }else if( (syncFlags & (SYNC_PULL|SYNC_CLONE))!=0 ){ |
| 1597 | rid = content_new(blob_str(&xfer.aToken[1]), isPriv); |
| 1598 | if( rid ) newPhantom = 1; |
| 1599 | } |
| 1600 | remote_has(rid); |
| 1601 | }else |
| @@ -1574,11 +1606,11 @@ | |
| 1606 | ** Should only happen in response to a clone. This message tells |
| 1607 | ** the client what product to use for the new database. |
| 1608 | */ |
| 1609 | if( blob_eq(&xfer.aToken[0],"push") |
| 1610 | && xfer.nToken==3 |
| 1611 | && (syncFlags & SYNC_CLONE)!=0 |
| 1612 | && blob_is_uuid(&xfer.aToken[1]) |
| 1613 | && blob_is_uuid(&xfer.aToken[2]) |
| 1614 | ){ |
| 1615 | if( blob_eq_str(&xfer.aToken[1], zSCode, -1) ){ |
| 1616 | fossil_fatal("server loop"); |
| @@ -1604,11 +1636,12 @@ | |
| 1636 | Blob content; |
| 1637 | blob_zero(&content); |
| 1638 | blob_extract(xfer.pIn, size, &content); |
| 1639 | g.perm.Admin = g.perm.RdAddr = 1; |
| 1640 | configure_receive(zName, &content, origConfigRcvMask); |
| 1641 | nCardRcvd++; |
| 1642 | nArtifactRcvd++; |
| 1643 | blob_reset(&content); |
| 1644 | blob_seek(xfer.pIn, 1, BLOB_SEEK_CUR); |
| 1645 | }else |
| 1646 | |
| 1647 | |
| @@ -1655,12 +1688,12 @@ | |
| 1688 | ** to the next cycle. |
| 1689 | */ |
| 1690 | if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){ |
| 1691 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1692 | defossilize(zMsg); |
| 1693 | if( (syncFlags & SYNC_PUSH) && zMsg && strglob("pull only *", zMsg) ){ |
| 1694 | syncFlags &= ~SYNC_PUSH; |
| 1695 | zMsg = 0; |
| 1696 | } |
| 1697 | fossil_print("\rServer says: %s\n", zMsg); |
| 1698 | }else |
| 1699 | |
| @@ -1683,11 +1716,11 @@ | |
| 1716 | ** is returned in the reply before the error card, so second and |
| 1717 | ** subsequent messages should be OK. Nevertheless, we need to ignore |
| 1718 | ** the error card on the first message of a clone. |
| 1719 | */ |
| 1720 | if( blob_eq(&xfer.aToken[0],"error") && xfer.nToken==2 ){ |
| 1721 | if( (syncFlags & SYNC_CLONE)==0 || nCycle>0 ){ |
| 1722 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1723 | defossilize(zMsg); |
| 1724 | if( fossil_strcmp(zMsg, "login failed")==0 ){ |
| 1725 | if( nCycle<2 ){ |
| 1726 | if( !g.dontKeepUrl ) db_unset("last-sync-pw", 0); |
| @@ -1727,14 +1760,16 @@ | |
| 1760 | && (configRcvMask & CONFIGSET_OLDFORMAT)!=0 |
| 1761 | ){ |
| 1762 | configure_finalize_receive(); |
| 1763 | } |
| 1764 | origConfigRcvMask = 0; |
| 1765 | if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){ |
| 1766 | fossil_print(zValueFormat, "Received:", |
| 1767 | blob_size(&recv), nCardRcvd, |
| 1768 | xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile); |
| 1769 | }else{ |
| 1770 | fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd); |
| 1771 | } |
| 1772 | blob_reset(&recv); |
| 1773 | nCycle++; |
| 1774 | |
| 1775 | /* If we received one or more files on the previous exchange but |
| @@ -1743,11 +1778,11 @@ | |
| 1778 | nFileRecv = xfer.nFileRcvd + xfer.nDeltaRcvd + xfer.nDanglingFile; |
| 1779 | if( (nFileRecv>0 || newPhantom) && db_exists("SELECT 1 FROM phantom") ){ |
| 1780 | go = 1; |
| 1781 | mxPhantomReq = nFileRecv*2; |
| 1782 | if( mxPhantomReq<200 ) mxPhantomReq = 200; |
| 1783 | }else if( (syncFlags & SYNC_CLONE)!=0 && nFileRecv>0 ){ |
| 1784 | go = 1; |
| 1785 | } |
| 1786 | nCardRcvd = 0; |
| 1787 | xfer.nFileRcvd = 0; |
| 1788 | xfer.nDeltaRcvd = 0; |
| @@ -1759,25 +1794,27 @@ | |
| 1794 | if( xfer.nFileSent+xfer.nDeltaSent>0 ){ |
| 1795 | go = 1; |
| 1796 | } |
| 1797 | |
| 1798 | /* If this is a clone, the go at least two rounds */ |
| 1799 | if( (syncFlags & SYNC_CLONE)!=0 && nCycle==1 ) go = 1; |
| 1800 | |
| 1801 | /* Stop the cycle if the server sends a "clone_seqno 0" card and |
| 1802 | ** we have gone at least two rounds. Always go at least two rounds |
| 1803 | ** on a clone in order to be sure to retrieve the configuration |
| 1804 | ** information which is only sent on the second round. |
| 1805 | */ |
| 1806 | if( cloneSeqno<=0 && nCycle>1 ) go = 0; |
| 1807 | }; |
| 1808 | transport_stats(&nSent, &nRcvd, 1); |
| 1809 | if( (syncFlags & SYNC_VERBOSE)==0 ) fossil_print("\n"); |
| 1810 | fossil_print( |
| 1811 | "%s finished with %lld bytes sent, %lld bytes received\n", |
| 1812 | zOpType, nSent, nRcvd); |
| 1813 | transport_close(); |
| 1814 | transport_global_shutdown(); |
| 1815 | db_multi_exec("DROP TABLE onremote"); |
| 1816 | manifest_crosslink_end(); |
| 1817 | content_enable_dephantomize(1); |
| 1818 | db_end_transaction(0); |
| 1819 | return nErr; |
| 1820 | } |
| 1821 |
+80
-43
| --- src/xfer.c | ||
| +++ src/xfer.c | ||
| @@ -1266,11 +1266,23 @@ | ||
| 1266 | 1266 | /* |
| 1267 | 1267 | ** Format strings for progress reporting. |
| 1268 | 1268 | */ |
| 1269 | 1269 | static const char zLabelFormat[] = "%-10s %10s %10s %10s %10s\n"; |
| 1270 | 1270 | static const char zValueFormat[] = "\r%-10s %10d %10d %10d %10d\n"; |
| 1271 | +static const char zBriefFormat[] = | |
| 1272 | + "Round-trips: %d Artifacts sent: %d received: %d\r"; | |
| 1271 | 1273 | |
| 1274 | +#if INTERFACE | |
| 1275 | +/* | |
| 1276 | +** Flag options for controlling client_sync() | |
| 1277 | +*/ | |
| 1278 | +#define SYNC_PUSH 0x0001 | |
| 1279 | +#define SYNC_PULL 0x0002 | |
| 1280 | +#define SYNC_CLONE 0x0004 | |
| 1281 | +#define SYNC_PRIVATE 0x0008 | |
| 1282 | +#define SYNC_VERBOSE 0x0010 | |
| 1283 | +#endif | |
| 1272 | 1284 | |
| 1273 | 1285 | /* |
| 1274 | 1286 | ** Sync to the host identified in g.urlName and g.urlPath. This |
| 1275 | 1287 | ** routine is called by the client. |
| 1276 | 1288 | ** |
| @@ -1277,16 +1289,13 @@ | ||
| 1277 | 1289 | ** Records are pushed to the server if pushFlag is true. Records |
| 1278 | 1290 | ** are pulled if pullFlag is true. A full sync occurs if both are |
| 1279 | 1291 | ** true. |
| 1280 | 1292 | */ |
| 1281 | 1293 | int client_sync( |
| 1282 | - int pushFlag, /* True to do a push (or a sync) */ | |
| 1283 | - int pullFlag, /* True to do a pull (or a sync) */ | |
| 1284 | - int cloneFlag, /* True if this is a clone */ | |
| 1285 | - int privateFlag, /* True to exchange private branches */ | |
| 1286 | - int configRcvMask, /* Receive these configuration items */ | |
| 1287 | - int configSendMask /* Send these configuration items */ | |
| 1294 | + unsigned syncFlags, /* Mask of SYNC_* flags */ | |
| 1295 | + unsigned configRcvMask, /* Receive these configuration items */ | |
| 1296 | + unsigned configSendMask /* Send these configuration items */ | |
| 1288 | 1297 | ){ |
| 1289 | 1298 | int go = 1; /* Loop until zero */ |
| 1290 | 1299 | int nCardSent = 0; /* Number of cards sent */ |
| 1291 | 1300 | int nCardRcvd = 0; /* Number of cards received */ |
| 1292 | 1301 | int nCycle = 0; /* Number of round trips to the server */ |
| @@ -1304,27 +1313,30 @@ | ||
| 1304 | 1313 | int lastPctDone = -1; /* Last displayed pctDone */ |
| 1305 | 1314 | double rArrivalTime; /* Time at which a message arrived */ |
| 1306 | 1315 | const char *zSCode = db_get("server-code", "x"); |
| 1307 | 1316 | const char *zPCode = db_get("project-code", 0); |
| 1308 | 1317 | int nErr = 0; /* Number of errors */ |
| 1318 | + int nRoundtrip= 0; /* Number of HTTP requests */ | |
| 1319 | + int nArtifactSent = 0; /* Total artifacts sent */ | |
| 1320 | + int nArtifactRcvd = 0; /* Total artifacts received */ | |
| 1321 | + const char *zOpType = 0;/* Push, Pull, Sync, Clone */ | |
| 1309 | 1322 | |
| 1310 | - if( db_get_boolean("dont-push", 0) ) pushFlag = 0; | |
| 1311 | - if( pushFlag + pullFlag + cloneFlag == 0 | |
| 1323 | + if( db_get_boolean("dont-push", 0) ) syncFlags &= ~SYNC_PUSH; | |
| 1324 | + if( (syncFlags & (SYNC_PUSH|SYNC_PULL|SYNC_CLONE))==0 | |
| 1312 | 1325 | && configRcvMask==0 && configSendMask==0 ) return 0; |
| 1313 | 1326 | |
| 1314 | 1327 | transport_stats(0, 0, 1); |
| 1315 | 1328 | socket_global_init(); |
| 1316 | 1329 | memset(&xfer, 0, sizeof(xfer)); |
| 1317 | 1330 | xfer.pIn = &recv; |
| 1318 | 1331 | xfer.pOut = &send; |
| 1319 | 1332 | xfer.mxSend = db_get_int("max-upload", 250000); |
| 1320 | - if( privateFlag ){ | |
| 1333 | + if( syncFlags & SYNC_PRIVATE ){ | |
| 1321 | 1334 | g.perm.Private = 1; |
| 1322 | 1335 | xfer.syncPrivate = 1; |
| 1323 | 1336 | } |
| 1324 | 1337 | |
| 1325 | - assert( pushFlag | pullFlag | cloneFlag | configRcvMask | configSendMask ); | |
| 1326 | 1338 | db_begin_transaction(); |
| 1327 | 1339 | db_record_repository_filename(0); |
| 1328 | 1340 | db_multi_exec( |
| 1329 | 1341 | "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);" |
| 1330 | 1342 | ); |
| @@ -1335,33 +1347,39 @@ | ||
| 1335 | 1347 | blob_zero(&xfer.line); |
| 1336 | 1348 | origConfigRcvMask = 0; |
| 1337 | 1349 | |
| 1338 | 1350 | |
| 1339 | 1351 | /* Send the send-private pragma if we are trying to sync private data */ |
| 1340 | - if( privateFlag ) blob_append(&send, "pragma send-private\n", -1); | |
| 1352 | + if( syncFlags & SYNC_PRIVATE ){ | |
| 1353 | + blob_append(&send, "pragma send-private\n", -1); | |
| 1354 | + } | |
| 1341 | 1355 | |
| 1342 | 1356 | /* |
| 1343 | 1357 | ** Always begin with a clone, pull, or push message |
| 1344 | 1358 | */ |
| 1345 | - if( cloneFlag ){ | |
| 1359 | + if( syncFlags & SYNC_CLONE ){ | |
| 1346 | 1360 | blob_appendf(&send, "clone 3 %d\n", cloneSeqno); |
| 1347 | - pushFlag = 0; | |
| 1348 | - pullFlag = 0; | |
| 1361 | + syncFlags &= ~(SYNC_PUSH|SYNC_PULL); | |
| 1349 | 1362 | nCardSent++; |
| 1350 | 1363 | /* TBD: Request all transferable configuration values */ |
| 1351 | 1364 | content_enable_dephantomize(0); |
| 1352 | - }else if( pullFlag ){ | |
| 1365 | + zOpType = "Clone"; | |
| 1366 | + }else if( syncFlags & SYNC_PULL ){ | |
| 1353 | 1367 | blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); |
| 1354 | 1368 | nCardSent++; |
| 1369 | + zOpType = "Pull"; | |
| 1355 | 1370 | } |
| 1356 | - if( pushFlag ){ | |
| 1371 | + if( syncFlags & SYNC_PUSH ){ | |
| 1357 | 1372 | blob_appendf(&send, "push %s %s\n", zSCode, zPCode); |
| 1358 | 1373 | nCardSent++; |
| 1374 | + if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push"; | |
| 1359 | 1375 | } |
| 1360 | 1376 | manifest_crosslink_begin(); |
| 1361 | 1377 | transport_global_startup(); |
| 1362 | - fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas"); | |
| 1378 | + if( syncFlags & SYNC_VERBOSE ){ | |
| 1379 | + fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas"); | |
| 1380 | + } | |
| 1363 | 1381 | |
| 1364 | 1382 | while( go ){ |
| 1365 | 1383 | int newPhantom = 0; |
| 1366 | 1384 | char *zRandomness; |
| 1367 | 1385 | |
| @@ -1374,25 +1392,28 @@ | ||
| 1374 | 1392 | } |
| 1375 | 1393 | |
| 1376 | 1394 | /* Generate gimme cards for phantoms and leaf cards |
| 1377 | 1395 | ** for all leaves. |
| 1378 | 1396 | */ |
| 1379 | - if( pullFlag || (cloneFlag && cloneSeqno==1) ){ | |
| 1397 | + if( (syncFlags & SYNC_PULL)!=0 | |
| 1398 | + || ((syncFlags & SYNC_CLONE)!=0 && cloneSeqno==1) | |
| 1399 | + ){ | |
| 1380 | 1400 | request_phantoms(&xfer, mxPhantomReq); |
| 1381 | 1401 | } |
| 1382 | - if( pushFlag ){ | |
| 1402 | + if( syncFlags & SYNC_PUSH ){ | |
| 1383 | 1403 | send_unsent(&xfer); |
| 1384 | 1404 | nCardSent += send_unclustered(&xfer); |
| 1385 | - if( privateFlag ) send_private(&xfer); | |
| 1405 | + if( syncFlags & SYNC_PRIVATE ) send_private(&xfer); | |
| 1386 | 1406 | } |
| 1387 | 1407 | |
| 1388 | 1408 | /* Send configuration parameter requests. On a clone, delay sending |
| 1389 | 1409 | ** this until the second cycle since the login card might fail on |
| 1390 | 1410 | ** the first cycle. |
| 1391 | 1411 | */ |
| 1392 | - if( configRcvMask && (cloneFlag==0 || nCycle>0) ){ | |
| 1412 | + if( configRcvMask && ((syncFlags & SYNC_CLONE)==0 || nCycle>0) ){ | |
| 1393 | 1413 | const char *zName; |
| 1414 | + if( zOpType==0 ) zOpType = "Pull"; | |
| 1394 | 1415 | zName = configure_first_name(configRcvMask); |
| 1395 | 1416 | while( zName ){ |
| 1396 | 1417 | blob_appendf(&send, "reqconfig %s\n", zName); |
| 1397 | 1418 | zName = configure_next_name(configRcvMask); |
| 1398 | 1419 | nCardSent++; |
| @@ -1407,10 +1428,11 @@ | ||
| 1407 | 1428 | configRcvMask = 0; |
| 1408 | 1429 | } |
| 1409 | 1430 | |
| 1410 | 1431 | /* Send configuration parameters being pushed */ |
| 1411 | 1432 | if( configSendMask ){ |
| 1433 | + if( zOpType==0 ) zOpType = "Push"; | |
| 1412 | 1434 | if( configSendMask & CONFIGSET_OLDFORMAT ){ |
| 1413 | 1435 | const char *zName; |
| 1414 | 1436 | zName = configure_first_name(configSendMask); |
| 1415 | 1437 | while( zName ){ |
| 1416 | 1438 | send_legacy_config_card(&xfer, zName); |
| @@ -1430,42 +1452,50 @@ | ||
| 1430 | 1452 | zRandomness = db_text(0, "SELECT hex(randomblob(20))"); |
| 1431 | 1453 | blob_appendf(&send, "# %s\n", zRandomness); |
| 1432 | 1454 | free(zRandomness); |
| 1433 | 1455 | |
| 1434 | 1456 | /* Exchange messages with the server */ |
| 1435 | - fossil_print(zValueFormat, "Sent:", | |
| 1436 | - blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent, | |
| 1437 | - xfer.nFileSent, xfer.nDeltaSent); | |
| 1457 | + if( syncFlags & SYNC_VERBOSE ){ | |
| 1458 | + fossil_print(zValueFormat, "Sent:", | |
| 1459 | + blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent, | |
| 1460 | + xfer.nFileSent, xfer.nDeltaSent); | |
| 1461 | + }else{ | |
| 1462 | + nRoundtrip++; | |
| 1463 | + nArtifactSent += xfer.nFileSent + xfer.nDeltaSent; | |
| 1464 | + fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd); | |
| 1465 | + } | |
| 1438 | 1466 | nCardSent = 0; |
| 1439 | 1467 | nCardRcvd = 0; |
| 1440 | 1468 | xfer.nFileSent = 0; |
| 1441 | 1469 | xfer.nDeltaSent = 0; |
| 1442 | 1470 | xfer.nGimmeSent = 0; |
| 1443 | 1471 | xfer.nIGotSent = 0; |
| 1444 | - if( !g.cgiOutput && !g.fQuiet ){ | |
| 1472 | + if( syncFlags & SYNC_VERBOSE ){ | |
| 1445 | 1473 | fossil_print("waiting for server..."); |
| 1446 | 1474 | } |
| 1447 | 1475 | fflush(stdout); |
| 1448 | - if( http_exchange(&send, &recv, cloneFlag==0 || nCycle>0) ){ | |
| 1476 | + if( http_exchange(&send, &recv, (syncFlags & SYNC_CLONE)==0 || nCycle>0) ){ | |
| 1449 | 1477 | nErr++; |
| 1450 | 1478 | break; |
| 1451 | 1479 | } |
| 1452 | 1480 | lastPctDone = -1; |
| 1453 | 1481 | blob_reset(&send); |
| 1454 | 1482 | rArrivalTime = db_double(0.0, "SELECT julianday('now')"); |
| 1455 | 1483 | |
| 1456 | 1484 | /* Send the send-private pragma if we are trying to sync private data */ |
| 1457 | - if( privateFlag ) blob_append(&send, "pragma send-private\n", -1); | |
| 1485 | + if( syncFlags & SYNC_PRIVATE ){ | |
| 1486 | + blob_append(&send, "pragma send-private\n", -1); | |
| 1487 | + } | |
| 1458 | 1488 | |
| 1459 | 1489 | /* Begin constructing the next message (which might never be |
| 1460 | 1490 | ** sent) by beginning with the pull or push cards |
| 1461 | 1491 | */ |
| 1462 | - if( pullFlag ){ | |
| 1492 | + if( syncFlags & SYNC_PULL ){ | |
| 1463 | 1493 | blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); |
| 1464 | 1494 | nCardSent++; |
| 1465 | 1495 | } |
| 1466 | - if( pushFlag ){ | |
| 1496 | + if( syncFlags & SYNC_PUSH ){ | |
| 1467 | 1497 | blob_appendf(&send, "push %s %s\n", zSCode, zPCode); |
| 1468 | 1498 | nCardSent++; |
| 1469 | 1499 | } |
| 1470 | 1500 | go = 0; |
| 1471 | 1501 | |
| @@ -1493,11 +1523,11 @@ | ||
| 1493 | 1523 | nCardRcvd++; |
| 1494 | 1524 | continue; |
| 1495 | 1525 | } |
| 1496 | 1526 | xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken)); |
| 1497 | 1527 | nCardRcvd++; |
| 1498 | - if( !g.cgiOutput && !g.fQuiet && recv.nUsed>0 ){ | |
| 1528 | + if( (syncFlags & SYNC_VERBOSE)!=0 && recv.nUsed>0 ){ | |
| 1499 | 1529 | pctDone = (recv.iCursor*100)/recv.nUsed; |
| 1500 | 1530 | if( pctDone!=lastPctDone ){ |
| 1501 | 1531 | fossil_print("\rprocessed: %d%% ", pctDone); |
| 1502 | 1532 | lastPctDone = pctDone; |
| 1503 | 1533 | fflush(stdout); |
| @@ -1508,20 +1538,22 @@ | ||
| 1508 | 1538 | ** file UUID DELTASRC SIZE \n CONTENT |
| 1509 | 1539 | ** |
| 1510 | 1540 | ** Receive a file transmitted from the server. |
| 1511 | 1541 | */ |
| 1512 | 1542 | if( blob_eq(&xfer.aToken[0],"file") ){ |
| 1513 | - xfer_accept_file(&xfer, cloneFlag); | |
| 1543 | + xfer_accept_file(&xfer, (syncFlags & SYNC_CLONE)!=0); | |
| 1544 | + nArtifactRcvd++; | |
| 1514 | 1545 | }else |
| 1515 | 1546 | |
| 1516 | 1547 | /* cfile UUID USIZE CSIZE \n CONTENT |
| 1517 | 1548 | ** cfile UUID DELTASRC USIZE CSIZE \n CONTENT |
| 1518 | 1549 | ** |
| 1519 | 1550 | ** Receive a compressed file transmitted from the server. |
| 1520 | 1551 | */ |
| 1521 | 1552 | if( blob_eq(&xfer.aToken[0],"cfile") ){ |
| 1522 | 1553 | xfer_accept_compressed_file(&xfer); |
| 1554 | + nArtifactRcvd++; | |
| 1523 | 1555 | }else |
| 1524 | 1556 | |
| 1525 | 1557 | /* gimme UUID |
| 1526 | 1558 | ** |
| 1527 | 1559 | ** Server is requesting a file. If the file is a manifest, assume |
| @@ -1530,11 +1562,11 @@ | ||
| 1530 | 1562 | */ |
| 1531 | 1563 | if( blob_eq(&xfer.aToken[0], "gimme") |
| 1532 | 1564 | && xfer.nToken==2 |
| 1533 | 1565 | && blob_is_uuid(&xfer.aToken[1]) |
| 1534 | 1566 | ){ |
| 1535 | - if( pushFlag ){ | |
| 1567 | + if( syncFlags & SYNC_PUSH ){ | |
| 1536 | 1568 | int rid = rid_from_uuid(&xfer.aToken[1], 0, 0); |
| 1537 | 1569 | if( rid ) send_file(&xfer, rid, &xfer.aToken[1], 0); |
| 1538 | 1570 | } |
| 1539 | 1571 | }else |
| 1540 | 1572 | |
| @@ -1559,11 +1591,11 @@ | ||
| 1559 | 1591 | rid = rid_from_uuid(&xfer.aToken[1], 0, 0); |
| 1560 | 1592 | if( rid>0 ){ |
| 1561 | 1593 | if( !isPriv ) content_make_public(rid); |
| 1562 | 1594 | }else if( isPriv && !g.perm.Private ){ |
| 1563 | 1595 | /* ignore private files */ |
| 1564 | - }else if( pullFlag || cloneFlag ){ | |
| 1596 | + }else if( (syncFlags & (SYNC_PULL|SYNC_CLONE))!=0 ){ | |
| 1565 | 1597 | rid = content_new(blob_str(&xfer.aToken[1]), isPriv); |
| 1566 | 1598 | if( rid ) newPhantom = 1; |
| 1567 | 1599 | } |
| 1568 | 1600 | remote_has(rid); |
| 1569 | 1601 | }else |
| @@ -1574,11 +1606,11 @@ | ||
| 1574 | 1606 | ** Should only happen in response to a clone. This message tells |
| 1575 | 1607 | ** the client what product to use for the new database. |
| 1576 | 1608 | */ |
| 1577 | 1609 | if( blob_eq(&xfer.aToken[0],"push") |
| 1578 | 1610 | && xfer.nToken==3 |
| 1579 | - && cloneFlag | |
| 1611 | + && (syncFlags & SYNC_CLONE)!=0 | |
| 1580 | 1612 | && blob_is_uuid(&xfer.aToken[1]) |
| 1581 | 1613 | && blob_is_uuid(&xfer.aToken[2]) |
| 1582 | 1614 | ){ |
| 1583 | 1615 | if( blob_eq_str(&xfer.aToken[1], zSCode, -1) ){ |
| 1584 | 1616 | fossil_fatal("server loop"); |
| @@ -1604,11 +1636,12 @@ | ||
| 1604 | 1636 | Blob content; |
| 1605 | 1637 | blob_zero(&content); |
| 1606 | 1638 | blob_extract(xfer.pIn, size, &content); |
| 1607 | 1639 | g.perm.Admin = g.perm.RdAddr = 1; |
| 1608 | 1640 | configure_receive(zName, &content, origConfigRcvMask); |
| 1609 | - nCardSent++; | |
| 1641 | + nCardRcvd++; | |
| 1642 | + nArtifactRcvd++; | |
| 1610 | 1643 | blob_reset(&content); |
| 1611 | 1644 | blob_seek(xfer.pIn, 1, BLOB_SEEK_CUR); |
| 1612 | 1645 | }else |
| 1613 | 1646 | |
| 1614 | 1647 | |
| @@ -1655,12 +1688,12 @@ | ||
| 1655 | 1688 | ** to the next cycle. |
| 1656 | 1689 | */ |
| 1657 | 1690 | if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){ |
| 1658 | 1691 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1659 | 1692 | defossilize(zMsg); |
| 1660 | - if( pushFlag && zMsg && strglob("pull only *", zMsg) ){ | |
| 1661 | - pushFlag = 0; | |
| 1693 | + if( (syncFlags & SYNC_PUSH) && zMsg && strglob("pull only *", zMsg) ){ | |
| 1694 | + syncFlags &= ~SYNC_PUSH; | |
| 1662 | 1695 | zMsg = 0; |
| 1663 | 1696 | } |
| 1664 | 1697 | fossil_print("\rServer says: %s\n", zMsg); |
| 1665 | 1698 | }else |
| 1666 | 1699 | |
| @@ -1683,11 +1716,11 @@ | ||
| 1683 | 1716 | ** is returned in the reply before the error card, so second and |
| 1684 | 1717 | ** subsequent messages should be OK. Nevertheless, we need to ignore |
| 1685 | 1718 | ** the error card on the first message of a clone. |
| 1686 | 1719 | */ |
| 1687 | 1720 | if( blob_eq(&xfer.aToken[0],"error") && xfer.nToken==2 ){ |
| 1688 | - if( !cloneFlag || nCycle>0 ){ | |
| 1721 | + if( (syncFlags & SYNC_CLONE)==0 || nCycle>0 ){ | |
| 1689 | 1722 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1690 | 1723 | defossilize(zMsg); |
| 1691 | 1724 | if( fossil_strcmp(zMsg, "login failed")==0 ){ |
| 1692 | 1725 | if( nCycle<2 ){ |
| 1693 | 1726 | if( !g.dontKeepUrl ) db_unset("last-sync-pw", 0); |
| @@ -1727,14 +1760,16 @@ | ||
| 1727 | 1760 | && (configRcvMask & CONFIGSET_OLDFORMAT)!=0 |
| 1728 | 1761 | ){ |
| 1729 | 1762 | configure_finalize_receive(); |
| 1730 | 1763 | } |
| 1731 | 1764 | origConfigRcvMask = 0; |
| 1732 | - if( nCardRcvd>0 ){ | |
| 1765 | + if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){ | |
| 1733 | 1766 | fossil_print(zValueFormat, "Received:", |
| 1734 | 1767 | blob_size(&recv), nCardRcvd, |
| 1735 | 1768 | xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile); |
| 1769 | + }else{ | |
| 1770 | + fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd); | |
| 1736 | 1771 | } |
| 1737 | 1772 | blob_reset(&recv); |
| 1738 | 1773 | nCycle++; |
| 1739 | 1774 | |
| 1740 | 1775 | /* If we received one or more files on the previous exchange but |
| @@ -1743,11 +1778,11 @@ | ||
| 1743 | 1778 | nFileRecv = xfer.nFileRcvd + xfer.nDeltaRcvd + xfer.nDanglingFile; |
| 1744 | 1779 | if( (nFileRecv>0 || newPhantom) && db_exists("SELECT 1 FROM phantom") ){ |
| 1745 | 1780 | go = 1; |
| 1746 | 1781 | mxPhantomReq = nFileRecv*2; |
| 1747 | 1782 | if( mxPhantomReq<200 ) mxPhantomReq = 200; |
| 1748 | - }else if( cloneFlag && nFileRecv>0 ){ | |
| 1783 | + }else if( (syncFlags & SYNC_CLONE)!=0 && nFileRecv>0 ){ | |
| 1749 | 1784 | go = 1; |
| 1750 | 1785 | } |
| 1751 | 1786 | nCardRcvd = 0; |
| 1752 | 1787 | xfer.nFileRcvd = 0; |
| 1753 | 1788 | xfer.nDeltaRcvd = 0; |
| @@ -1759,25 +1794,27 @@ | ||
| 1759 | 1794 | if( xfer.nFileSent+xfer.nDeltaSent>0 ){ |
| 1760 | 1795 | go = 1; |
| 1761 | 1796 | } |
| 1762 | 1797 | |
| 1763 | 1798 | /* If this is a clone, the go at least two rounds */ |
| 1764 | - if( cloneFlag && nCycle==1 ) go = 1; | |
| 1799 | + if( (syncFlags & SYNC_CLONE)!=0 && nCycle==1 ) go = 1; | |
| 1765 | 1800 | |
| 1766 | 1801 | /* Stop the cycle if the server sends a "clone_seqno 0" card and |
| 1767 | 1802 | ** we have gone at least two rounds. Always go at least two rounds |
| 1768 | 1803 | ** on a clone in order to be sure to retrieve the configuration |
| 1769 | 1804 | ** information which is only sent on the second round. |
| 1770 | 1805 | */ |
| 1771 | 1806 | if( cloneSeqno<=0 && nCycle>1 ) go = 0; |
| 1772 | 1807 | }; |
| 1773 | 1808 | transport_stats(&nSent, &nRcvd, 1); |
| 1774 | - fossil_print("Total network traffic: %lld bytes sent, %lld bytes received\n", | |
| 1775 | - nSent, nRcvd); | |
| 1809 | + if( (syncFlags & SYNC_VERBOSE)==0 ) fossil_print("\n"); | |
| 1810 | + fossil_print( | |
| 1811 | + "%s finished with %lld bytes sent, %lld bytes received\n", | |
| 1812 | + zOpType, nSent, nRcvd); | |
| 1776 | 1813 | transport_close(); |
| 1777 | 1814 | transport_global_shutdown(); |
| 1778 | 1815 | db_multi_exec("DROP TABLE onremote"); |
| 1779 | 1816 | manifest_crosslink_end(); |
| 1780 | 1817 | content_enable_dephantomize(1); |
| 1781 | 1818 | db_end_transaction(0); |
| 1782 | 1819 | return nErr; |
| 1783 | 1820 | } |
| 1784 | 1821 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -1266,11 +1266,23 @@ | |
| 1266 | /* |
| 1267 | ** Format strings for progress reporting. |
| 1268 | */ |
| 1269 | static const char zLabelFormat[] = "%-10s %10s %10s %10s %10s\n"; |
| 1270 | static const char zValueFormat[] = "\r%-10s %10d %10d %10d %10d\n"; |
| 1271 | |
| 1272 | |
| 1273 | /* |
| 1274 | ** Sync to the host identified in g.urlName and g.urlPath. This |
| 1275 | ** routine is called by the client. |
| 1276 | ** |
| @@ -1277,16 +1289,13 @@ | |
| 1277 | ** Records are pushed to the server if pushFlag is true. Records |
| 1278 | ** are pulled if pullFlag is true. A full sync occurs if both are |
| 1279 | ** true. |
| 1280 | */ |
| 1281 | int client_sync( |
| 1282 | int pushFlag, /* True to do a push (or a sync) */ |
| 1283 | int pullFlag, /* True to do a pull (or a sync) */ |
| 1284 | int cloneFlag, /* True if this is a clone */ |
| 1285 | int privateFlag, /* True to exchange private branches */ |
| 1286 | int configRcvMask, /* Receive these configuration items */ |
| 1287 | int configSendMask /* Send these configuration items */ |
| 1288 | ){ |
| 1289 | int go = 1; /* Loop until zero */ |
| 1290 | int nCardSent = 0; /* Number of cards sent */ |
| 1291 | int nCardRcvd = 0; /* Number of cards received */ |
| 1292 | int nCycle = 0; /* Number of round trips to the server */ |
| @@ -1304,27 +1313,30 @@ | |
| 1304 | int lastPctDone = -1; /* Last displayed pctDone */ |
| 1305 | double rArrivalTime; /* Time at which a message arrived */ |
| 1306 | const char *zSCode = db_get("server-code", "x"); |
| 1307 | const char *zPCode = db_get("project-code", 0); |
| 1308 | int nErr = 0; /* Number of errors */ |
| 1309 | |
| 1310 | if( db_get_boolean("dont-push", 0) ) pushFlag = 0; |
| 1311 | if( pushFlag + pullFlag + cloneFlag == 0 |
| 1312 | && configRcvMask==0 && configSendMask==0 ) return 0; |
| 1313 | |
| 1314 | transport_stats(0, 0, 1); |
| 1315 | socket_global_init(); |
| 1316 | memset(&xfer, 0, sizeof(xfer)); |
| 1317 | xfer.pIn = &recv; |
| 1318 | xfer.pOut = &send; |
| 1319 | xfer.mxSend = db_get_int("max-upload", 250000); |
| 1320 | if( privateFlag ){ |
| 1321 | g.perm.Private = 1; |
| 1322 | xfer.syncPrivate = 1; |
| 1323 | } |
| 1324 | |
| 1325 | assert( pushFlag | pullFlag | cloneFlag | configRcvMask | configSendMask ); |
| 1326 | db_begin_transaction(); |
| 1327 | db_record_repository_filename(0); |
| 1328 | db_multi_exec( |
| 1329 | "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);" |
| 1330 | ); |
| @@ -1335,33 +1347,39 @@ | |
| 1335 | blob_zero(&xfer.line); |
| 1336 | origConfigRcvMask = 0; |
| 1337 | |
| 1338 | |
| 1339 | /* Send the send-private pragma if we are trying to sync private data */ |
| 1340 | if( privateFlag ) blob_append(&send, "pragma send-private\n", -1); |
| 1341 | |
| 1342 | /* |
| 1343 | ** Always begin with a clone, pull, or push message |
| 1344 | */ |
| 1345 | if( cloneFlag ){ |
| 1346 | blob_appendf(&send, "clone 3 %d\n", cloneSeqno); |
| 1347 | pushFlag = 0; |
| 1348 | pullFlag = 0; |
| 1349 | nCardSent++; |
| 1350 | /* TBD: Request all transferable configuration values */ |
| 1351 | content_enable_dephantomize(0); |
| 1352 | }else if( pullFlag ){ |
| 1353 | blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); |
| 1354 | nCardSent++; |
| 1355 | } |
| 1356 | if( pushFlag ){ |
| 1357 | blob_appendf(&send, "push %s %s\n", zSCode, zPCode); |
| 1358 | nCardSent++; |
| 1359 | } |
| 1360 | manifest_crosslink_begin(); |
| 1361 | transport_global_startup(); |
| 1362 | fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas"); |
| 1363 | |
| 1364 | while( go ){ |
| 1365 | int newPhantom = 0; |
| 1366 | char *zRandomness; |
| 1367 | |
| @@ -1374,25 +1392,28 @@ | |
| 1374 | } |
| 1375 | |
| 1376 | /* Generate gimme cards for phantoms and leaf cards |
| 1377 | ** for all leaves. |
| 1378 | */ |
| 1379 | if( pullFlag || (cloneFlag && cloneSeqno==1) ){ |
| 1380 | request_phantoms(&xfer, mxPhantomReq); |
| 1381 | } |
| 1382 | if( pushFlag ){ |
| 1383 | send_unsent(&xfer); |
| 1384 | nCardSent += send_unclustered(&xfer); |
| 1385 | if( privateFlag ) send_private(&xfer); |
| 1386 | } |
| 1387 | |
| 1388 | /* Send configuration parameter requests. On a clone, delay sending |
| 1389 | ** this until the second cycle since the login card might fail on |
| 1390 | ** the first cycle. |
| 1391 | */ |
| 1392 | if( configRcvMask && (cloneFlag==0 || nCycle>0) ){ |
| 1393 | const char *zName; |
| 1394 | zName = configure_first_name(configRcvMask); |
| 1395 | while( zName ){ |
| 1396 | blob_appendf(&send, "reqconfig %s\n", zName); |
| 1397 | zName = configure_next_name(configRcvMask); |
| 1398 | nCardSent++; |
| @@ -1407,10 +1428,11 @@ | |
| 1407 | configRcvMask = 0; |
| 1408 | } |
| 1409 | |
| 1410 | /* Send configuration parameters being pushed */ |
| 1411 | if( configSendMask ){ |
| 1412 | if( configSendMask & CONFIGSET_OLDFORMAT ){ |
| 1413 | const char *zName; |
| 1414 | zName = configure_first_name(configSendMask); |
| 1415 | while( zName ){ |
| 1416 | send_legacy_config_card(&xfer, zName); |
| @@ -1430,42 +1452,50 @@ | |
| 1430 | zRandomness = db_text(0, "SELECT hex(randomblob(20))"); |
| 1431 | blob_appendf(&send, "# %s\n", zRandomness); |
| 1432 | free(zRandomness); |
| 1433 | |
| 1434 | /* Exchange messages with the server */ |
| 1435 | fossil_print(zValueFormat, "Sent:", |
| 1436 | blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent, |
| 1437 | xfer.nFileSent, xfer.nDeltaSent); |
| 1438 | nCardSent = 0; |
| 1439 | nCardRcvd = 0; |
| 1440 | xfer.nFileSent = 0; |
| 1441 | xfer.nDeltaSent = 0; |
| 1442 | xfer.nGimmeSent = 0; |
| 1443 | xfer.nIGotSent = 0; |
| 1444 | if( !g.cgiOutput && !g.fQuiet ){ |
| 1445 | fossil_print("waiting for server..."); |
| 1446 | } |
| 1447 | fflush(stdout); |
| 1448 | if( http_exchange(&send, &recv, cloneFlag==0 || nCycle>0) ){ |
| 1449 | nErr++; |
| 1450 | break; |
| 1451 | } |
| 1452 | lastPctDone = -1; |
| 1453 | blob_reset(&send); |
| 1454 | rArrivalTime = db_double(0.0, "SELECT julianday('now')"); |
| 1455 | |
| 1456 | /* Send the send-private pragma if we are trying to sync private data */ |
| 1457 | if( privateFlag ) blob_append(&send, "pragma send-private\n", -1); |
| 1458 | |
| 1459 | /* Begin constructing the next message (which might never be |
| 1460 | ** sent) by beginning with the pull or push cards |
| 1461 | */ |
| 1462 | if( pullFlag ){ |
| 1463 | blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); |
| 1464 | nCardSent++; |
| 1465 | } |
| 1466 | if( pushFlag ){ |
| 1467 | blob_appendf(&send, "push %s %s\n", zSCode, zPCode); |
| 1468 | nCardSent++; |
| 1469 | } |
| 1470 | go = 0; |
| 1471 | |
| @@ -1493,11 +1523,11 @@ | |
| 1493 | nCardRcvd++; |
| 1494 | continue; |
| 1495 | } |
| 1496 | xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken)); |
| 1497 | nCardRcvd++; |
| 1498 | if( !g.cgiOutput && !g.fQuiet && recv.nUsed>0 ){ |
| 1499 | pctDone = (recv.iCursor*100)/recv.nUsed; |
| 1500 | if( pctDone!=lastPctDone ){ |
| 1501 | fossil_print("\rprocessed: %d%% ", pctDone); |
| 1502 | lastPctDone = pctDone; |
| 1503 | fflush(stdout); |
| @@ -1508,20 +1538,22 @@ | |
| 1508 | ** file UUID DELTASRC SIZE \n CONTENT |
| 1509 | ** |
| 1510 | ** Receive a file transmitted from the server. |
| 1511 | */ |
| 1512 | if( blob_eq(&xfer.aToken[0],"file") ){ |
| 1513 | xfer_accept_file(&xfer, cloneFlag); |
| 1514 | }else |
| 1515 | |
| 1516 | /* cfile UUID USIZE CSIZE \n CONTENT |
| 1517 | ** cfile UUID DELTASRC USIZE CSIZE \n CONTENT |
| 1518 | ** |
| 1519 | ** Receive a compressed file transmitted from the server. |
| 1520 | */ |
| 1521 | if( blob_eq(&xfer.aToken[0],"cfile") ){ |
| 1522 | xfer_accept_compressed_file(&xfer); |
| 1523 | }else |
| 1524 | |
| 1525 | /* gimme UUID |
| 1526 | ** |
| 1527 | ** Server is requesting a file. If the file is a manifest, assume |
| @@ -1530,11 +1562,11 @@ | |
| 1530 | */ |
| 1531 | if( blob_eq(&xfer.aToken[0], "gimme") |
| 1532 | && xfer.nToken==2 |
| 1533 | && blob_is_uuid(&xfer.aToken[1]) |
| 1534 | ){ |
| 1535 | if( pushFlag ){ |
| 1536 | int rid = rid_from_uuid(&xfer.aToken[1], 0, 0); |
| 1537 | if( rid ) send_file(&xfer, rid, &xfer.aToken[1], 0); |
| 1538 | } |
| 1539 | }else |
| 1540 | |
| @@ -1559,11 +1591,11 @@ | |
| 1559 | rid = rid_from_uuid(&xfer.aToken[1], 0, 0); |
| 1560 | if( rid>0 ){ |
| 1561 | if( !isPriv ) content_make_public(rid); |
| 1562 | }else if( isPriv && !g.perm.Private ){ |
| 1563 | /* ignore private files */ |
| 1564 | }else if( pullFlag || cloneFlag ){ |
| 1565 | rid = content_new(blob_str(&xfer.aToken[1]), isPriv); |
| 1566 | if( rid ) newPhantom = 1; |
| 1567 | } |
| 1568 | remote_has(rid); |
| 1569 | }else |
| @@ -1574,11 +1606,11 @@ | |
| 1574 | ** Should only happen in response to a clone. This message tells |
| 1575 | ** the client what product to use for the new database. |
| 1576 | */ |
| 1577 | if( blob_eq(&xfer.aToken[0],"push") |
| 1578 | && xfer.nToken==3 |
| 1579 | && cloneFlag |
| 1580 | && blob_is_uuid(&xfer.aToken[1]) |
| 1581 | && blob_is_uuid(&xfer.aToken[2]) |
| 1582 | ){ |
| 1583 | if( blob_eq_str(&xfer.aToken[1], zSCode, -1) ){ |
| 1584 | fossil_fatal("server loop"); |
| @@ -1604,11 +1636,12 @@ | |
| 1604 | Blob content; |
| 1605 | blob_zero(&content); |
| 1606 | blob_extract(xfer.pIn, size, &content); |
| 1607 | g.perm.Admin = g.perm.RdAddr = 1; |
| 1608 | configure_receive(zName, &content, origConfigRcvMask); |
| 1609 | nCardSent++; |
| 1610 | blob_reset(&content); |
| 1611 | blob_seek(xfer.pIn, 1, BLOB_SEEK_CUR); |
| 1612 | }else |
| 1613 | |
| 1614 | |
| @@ -1655,12 +1688,12 @@ | |
| 1655 | ** to the next cycle. |
| 1656 | */ |
| 1657 | if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){ |
| 1658 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1659 | defossilize(zMsg); |
| 1660 | if( pushFlag && zMsg && strglob("pull only *", zMsg) ){ |
| 1661 | pushFlag = 0; |
| 1662 | zMsg = 0; |
| 1663 | } |
| 1664 | fossil_print("\rServer says: %s\n", zMsg); |
| 1665 | }else |
| 1666 | |
| @@ -1683,11 +1716,11 @@ | |
| 1683 | ** is returned in the reply before the error card, so second and |
| 1684 | ** subsequent messages should be OK. Nevertheless, we need to ignore |
| 1685 | ** the error card on the first message of a clone. |
| 1686 | */ |
| 1687 | if( blob_eq(&xfer.aToken[0],"error") && xfer.nToken==2 ){ |
| 1688 | if( !cloneFlag || nCycle>0 ){ |
| 1689 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1690 | defossilize(zMsg); |
| 1691 | if( fossil_strcmp(zMsg, "login failed")==0 ){ |
| 1692 | if( nCycle<2 ){ |
| 1693 | if( !g.dontKeepUrl ) db_unset("last-sync-pw", 0); |
| @@ -1727,14 +1760,16 @@ | |
| 1727 | && (configRcvMask & CONFIGSET_OLDFORMAT)!=0 |
| 1728 | ){ |
| 1729 | configure_finalize_receive(); |
| 1730 | } |
| 1731 | origConfigRcvMask = 0; |
| 1732 | if( nCardRcvd>0 ){ |
| 1733 | fossil_print(zValueFormat, "Received:", |
| 1734 | blob_size(&recv), nCardRcvd, |
| 1735 | xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile); |
| 1736 | } |
| 1737 | blob_reset(&recv); |
| 1738 | nCycle++; |
| 1739 | |
| 1740 | /* If we received one or more files on the previous exchange but |
| @@ -1743,11 +1778,11 @@ | |
| 1743 | nFileRecv = xfer.nFileRcvd + xfer.nDeltaRcvd + xfer.nDanglingFile; |
| 1744 | if( (nFileRecv>0 || newPhantom) && db_exists("SELECT 1 FROM phantom") ){ |
| 1745 | go = 1; |
| 1746 | mxPhantomReq = nFileRecv*2; |
| 1747 | if( mxPhantomReq<200 ) mxPhantomReq = 200; |
| 1748 | }else if( cloneFlag && nFileRecv>0 ){ |
| 1749 | go = 1; |
| 1750 | } |
| 1751 | nCardRcvd = 0; |
| 1752 | xfer.nFileRcvd = 0; |
| 1753 | xfer.nDeltaRcvd = 0; |
| @@ -1759,25 +1794,27 @@ | |
| 1759 | if( xfer.nFileSent+xfer.nDeltaSent>0 ){ |
| 1760 | go = 1; |
| 1761 | } |
| 1762 | |
| 1763 | /* If this is a clone, the go at least two rounds */ |
| 1764 | if( cloneFlag && nCycle==1 ) go = 1; |
| 1765 | |
| 1766 | /* Stop the cycle if the server sends a "clone_seqno 0" card and |
| 1767 | ** we have gone at least two rounds. Always go at least two rounds |
| 1768 | ** on a clone in order to be sure to retrieve the configuration |
| 1769 | ** information which is only sent on the second round. |
| 1770 | */ |
| 1771 | if( cloneSeqno<=0 && nCycle>1 ) go = 0; |
| 1772 | }; |
| 1773 | transport_stats(&nSent, &nRcvd, 1); |
| 1774 | fossil_print("Total network traffic: %lld bytes sent, %lld bytes received\n", |
| 1775 | nSent, nRcvd); |
| 1776 | transport_close(); |
| 1777 | transport_global_shutdown(); |
| 1778 | db_multi_exec("DROP TABLE onremote"); |
| 1779 | manifest_crosslink_end(); |
| 1780 | content_enable_dephantomize(1); |
| 1781 | db_end_transaction(0); |
| 1782 | return nErr; |
| 1783 | } |
| 1784 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -1266,11 +1266,23 @@ | |
| 1266 | /* |
| 1267 | ** Format strings for progress reporting. |
| 1268 | */ |
| 1269 | static const char zLabelFormat[] = "%-10s %10s %10s %10s %10s\n"; |
| 1270 | static const char zValueFormat[] = "\r%-10s %10d %10d %10d %10d\n"; |
| 1271 | static const char zBriefFormat[] = |
| 1272 | "Round-trips: %d Artifacts sent: %d received: %d\r"; |
| 1273 | |
| 1274 | #if INTERFACE |
| 1275 | /* |
| 1276 | ** Flag options for controlling client_sync() |
| 1277 | */ |
| 1278 | #define SYNC_PUSH 0x0001 |
| 1279 | #define SYNC_PULL 0x0002 |
| 1280 | #define SYNC_CLONE 0x0004 |
| 1281 | #define SYNC_PRIVATE 0x0008 |
| 1282 | #define SYNC_VERBOSE 0x0010 |
| 1283 | #endif |
| 1284 | |
| 1285 | /* |
| 1286 | ** Sync to the host identified in g.urlName and g.urlPath. This |
| 1287 | ** routine is called by the client. |
| 1288 | ** |
| @@ -1277,16 +1289,13 @@ | |
| 1289 | ** Records are pushed to the server if pushFlag is true. Records |
| 1290 | ** are pulled if pullFlag is true. A full sync occurs if both are |
| 1291 | ** true. |
| 1292 | */ |
| 1293 | int client_sync( |
| 1294 | unsigned syncFlags, /* Mask of SYNC_* flags */ |
| 1295 | unsigned configRcvMask, /* Receive these configuration items */ |
| 1296 | unsigned configSendMask /* Send these configuration items */ |
| 1297 | ){ |
| 1298 | int go = 1; /* Loop until zero */ |
| 1299 | int nCardSent = 0; /* Number of cards sent */ |
| 1300 | int nCardRcvd = 0; /* Number of cards received */ |
| 1301 | int nCycle = 0; /* Number of round trips to the server */ |
| @@ -1304,27 +1313,30 @@ | |
| 1313 | int lastPctDone = -1; /* Last displayed pctDone */ |
| 1314 | double rArrivalTime; /* Time at which a message arrived */ |
| 1315 | const char *zSCode = db_get("server-code", "x"); |
| 1316 | const char *zPCode = db_get("project-code", 0); |
| 1317 | int nErr = 0; /* Number of errors */ |
| 1318 | int nRoundtrip= 0; /* Number of HTTP requests */ |
| 1319 | int nArtifactSent = 0; /* Total artifacts sent */ |
| 1320 | int nArtifactRcvd = 0; /* Total artifacts received */ |
| 1321 | const char *zOpType = 0;/* Push, Pull, Sync, Clone */ |
| 1322 | |
| 1323 | if( db_get_boolean("dont-push", 0) ) syncFlags &= ~SYNC_PUSH; |
| 1324 | if( (syncFlags & (SYNC_PUSH|SYNC_PULL|SYNC_CLONE))==0 |
| 1325 | && configRcvMask==0 && configSendMask==0 ) return 0; |
| 1326 | |
| 1327 | transport_stats(0, 0, 1); |
| 1328 | socket_global_init(); |
| 1329 | memset(&xfer, 0, sizeof(xfer)); |
| 1330 | xfer.pIn = &recv; |
| 1331 | xfer.pOut = &send; |
| 1332 | xfer.mxSend = db_get_int("max-upload", 250000); |
| 1333 | if( syncFlags & SYNC_PRIVATE ){ |
| 1334 | g.perm.Private = 1; |
| 1335 | xfer.syncPrivate = 1; |
| 1336 | } |
| 1337 | |
| 1338 | db_begin_transaction(); |
| 1339 | db_record_repository_filename(0); |
| 1340 | db_multi_exec( |
| 1341 | "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);" |
| 1342 | ); |
| @@ -1335,33 +1347,39 @@ | |
| 1347 | blob_zero(&xfer.line); |
| 1348 | origConfigRcvMask = 0; |
| 1349 | |
| 1350 | |
| 1351 | /* Send the send-private pragma if we are trying to sync private data */ |
| 1352 | if( syncFlags & SYNC_PRIVATE ){ |
| 1353 | blob_append(&send, "pragma send-private\n", -1); |
| 1354 | } |
| 1355 | |
| 1356 | /* |
| 1357 | ** Always begin with a clone, pull, or push message |
| 1358 | */ |
| 1359 | if( syncFlags & SYNC_CLONE ){ |
| 1360 | blob_appendf(&send, "clone 3 %d\n", cloneSeqno); |
| 1361 | syncFlags &= ~(SYNC_PUSH|SYNC_PULL); |
| 1362 | nCardSent++; |
| 1363 | /* TBD: Request all transferable configuration values */ |
| 1364 | content_enable_dephantomize(0); |
| 1365 | zOpType = "Clone"; |
| 1366 | }else if( syncFlags & SYNC_PULL ){ |
| 1367 | blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); |
| 1368 | nCardSent++; |
| 1369 | zOpType = "Pull"; |
| 1370 | } |
| 1371 | if( syncFlags & SYNC_PUSH ){ |
| 1372 | blob_appendf(&send, "push %s %s\n", zSCode, zPCode); |
| 1373 | nCardSent++; |
| 1374 | if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push"; |
| 1375 | } |
| 1376 | manifest_crosslink_begin(); |
| 1377 | transport_global_startup(); |
| 1378 | if( syncFlags & SYNC_VERBOSE ){ |
| 1379 | fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas"); |
| 1380 | } |
| 1381 | |
| 1382 | while( go ){ |
| 1383 | int newPhantom = 0; |
| 1384 | char *zRandomness; |
| 1385 | |
| @@ -1374,25 +1392,28 @@ | |
| 1392 | } |
| 1393 | |
| 1394 | /* Generate gimme cards for phantoms and leaf cards |
| 1395 | ** for all leaves. |
| 1396 | */ |
| 1397 | if( (syncFlags & SYNC_PULL)!=0 |
| 1398 | || ((syncFlags & SYNC_CLONE)!=0 && cloneSeqno==1) |
| 1399 | ){ |
| 1400 | request_phantoms(&xfer, mxPhantomReq); |
| 1401 | } |
| 1402 | if( syncFlags & SYNC_PUSH ){ |
| 1403 | send_unsent(&xfer); |
| 1404 | nCardSent += send_unclustered(&xfer); |
| 1405 | if( syncFlags & SYNC_PRIVATE ) send_private(&xfer); |
| 1406 | } |
| 1407 | |
| 1408 | /* Send configuration parameter requests. On a clone, delay sending |
| 1409 | ** this until the second cycle since the login card might fail on |
| 1410 | ** the first cycle. |
| 1411 | */ |
| 1412 | if( configRcvMask && ((syncFlags & SYNC_CLONE)==0 || nCycle>0) ){ |
| 1413 | const char *zName; |
| 1414 | if( zOpType==0 ) zOpType = "Pull"; |
| 1415 | zName = configure_first_name(configRcvMask); |
| 1416 | while( zName ){ |
| 1417 | blob_appendf(&send, "reqconfig %s\n", zName); |
| 1418 | zName = configure_next_name(configRcvMask); |
| 1419 | nCardSent++; |
| @@ -1407,10 +1428,11 @@ | |
| 1428 | configRcvMask = 0; |
| 1429 | } |
| 1430 | |
| 1431 | /* Send configuration parameters being pushed */ |
| 1432 | if( configSendMask ){ |
| 1433 | if( zOpType==0 ) zOpType = "Push"; |
| 1434 | if( configSendMask & CONFIGSET_OLDFORMAT ){ |
| 1435 | const char *zName; |
| 1436 | zName = configure_first_name(configSendMask); |
| 1437 | while( zName ){ |
| 1438 | send_legacy_config_card(&xfer, zName); |
| @@ -1430,42 +1452,50 @@ | |
| 1452 | zRandomness = db_text(0, "SELECT hex(randomblob(20))"); |
| 1453 | blob_appendf(&send, "# %s\n", zRandomness); |
| 1454 | free(zRandomness); |
| 1455 | |
| 1456 | /* Exchange messages with the server */ |
| 1457 | if( syncFlags & SYNC_VERBOSE ){ |
| 1458 | fossil_print(zValueFormat, "Sent:", |
| 1459 | blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent, |
| 1460 | xfer.nFileSent, xfer.nDeltaSent); |
| 1461 | }else{ |
| 1462 | nRoundtrip++; |
| 1463 | nArtifactSent += xfer.nFileSent + xfer.nDeltaSent; |
| 1464 | fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd); |
| 1465 | } |
| 1466 | nCardSent = 0; |
| 1467 | nCardRcvd = 0; |
| 1468 | xfer.nFileSent = 0; |
| 1469 | xfer.nDeltaSent = 0; |
| 1470 | xfer.nGimmeSent = 0; |
| 1471 | xfer.nIGotSent = 0; |
| 1472 | if( syncFlags & SYNC_VERBOSE ){ |
| 1473 | fossil_print("waiting for server..."); |
| 1474 | } |
| 1475 | fflush(stdout); |
| 1476 | if( http_exchange(&send, &recv, (syncFlags & SYNC_CLONE)==0 || nCycle>0) ){ |
| 1477 | nErr++; |
| 1478 | break; |
| 1479 | } |
| 1480 | lastPctDone = -1; |
| 1481 | blob_reset(&send); |
| 1482 | rArrivalTime = db_double(0.0, "SELECT julianday('now')"); |
| 1483 | |
| 1484 | /* Send the send-private pragma if we are trying to sync private data */ |
| 1485 | if( syncFlags & SYNC_PRIVATE ){ |
| 1486 | blob_append(&send, "pragma send-private\n", -1); |
| 1487 | } |
| 1488 | |
| 1489 | /* Begin constructing the next message (which might never be |
| 1490 | ** sent) by beginning with the pull or push cards |
| 1491 | */ |
| 1492 | if( syncFlags & SYNC_PULL ){ |
| 1493 | blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); |
| 1494 | nCardSent++; |
| 1495 | } |
| 1496 | if( syncFlags & SYNC_PUSH ){ |
| 1497 | blob_appendf(&send, "push %s %s\n", zSCode, zPCode); |
| 1498 | nCardSent++; |
| 1499 | } |
| 1500 | go = 0; |
| 1501 | |
| @@ -1493,11 +1523,11 @@ | |
| 1523 | nCardRcvd++; |
| 1524 | continue; |
| 1525 | } |
| 1526 | xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken)); |
| 1527 | nCardRcvd++; |
| 1528 | if( (syncFlags & SYNC_VERBOSE)!=0 && recv.nUsed>0 ){ |
| 1529 | pctDone = (recv.iCursor*100)/recv.nUsed; |
| 1530 | if( pctDone!=lastPctDone ){ |
| 1531 | fossil_print("\rprocessed: %d%% ", pctDone); |
| 1532 | lastPctDone = pctDone; |
| 1533 | fflush(stdout); |
| @@ -1508,20 +1538,22 @@ | |
| 1538 | ** file UUID DELTASRC SIZE \n CONTENT |
| 1539 | ** |
| 1540 | ** Receive a file transmitted from the server. |
| 1541 | */ |
| 1542 | if( blob_eq(&xfer.aToken[0],"file") ){ |
| 1543 | xfer_accept_file(&xfer, (syncFlags & SYNC_CLONE)!=0); |
| 1544 | nArtifactRcvd++; |
| 1545 | }else |
| 1546 | |
| 1547 | /* cfile UUID USIZE CSIZE \n CONTENT |
| 1548 | ** cfile UUID DELTASRC USIZE CSIZE \n CONTENT |
| 1549 | ** |
| 1550 | ** Receive a compressed file transmitted from the server. |
| 1551 | */ |
| 1552 | if( blob_eq(&xfer.aToken[0],"cfile") ){ |
| 1553 | xfer_accept_compressed_file(&xfer); |
| 1554 | nArtifactRcvd++; |
| 1555 | }else |
| 1556 | |
| 1557 | /* gimme UUID |
| 1558 | ** |
| 1559 | ** Server is requesting a file. If the file is a manifest, assume |
| @@ -1530,11 +1562,11 @@ | |
| 1562 | */ |
| 1563 | if( blob_eq(&xfer.aToken[0], "gimme") |
| 1564 | && xfer.nToken==2 |
| 1565 | && blob_is_uuid(&xfer.aToken[1]) |
| 1566 | ){ |
| 1567 | if( syncFlags & SYNC_PUSH ){ |
| 1568 | int rid = rid_from_uuid(&xfer.aToken[1], 0, 0); |
| 1569 | if( rid ) send_file(&xfer, rid, &xfer.aToken[1], 0); |
| 1570 | } |
| 1571 | }else |
| 1572 | |
| @@ -1559,11 +1591,11 @@ | |
| 1591 | rid = rid_from_uuid(&xfer.aToken[1], 0, 0); |
| 1592 | if( rid>0 ){ |
| 1593 | if( !isPriv ) content_make_public(rid); |
| 1594 | }else if( isPriv && !g.perm.Private ){ |
| 1595 | /* ignore private files */ |
| 1596 | }else if( (syncFlags & (SYNC_PULL|SYNC_CLONE))!=0 ){ |
| 1597 | rid = content_new(blob_str(&xfer.aToken[1]), isPriv); |
| 1598 | if( rid ) newPhantom = 1; |
| 1599 | } |
| 1600 | remote_has(rid); |
| 1601 | }else |
| @@ -1574,11 +1606,11 @@ | |
| 1606 | ** Should only happen in response to a clone. This message tells |
| 1607 | ** the client what product to use for the new database. |
| 1608 | */ |
| 1609 | if( blob_eq(&xfer.aToken[0],"push") |
| 1610 | && xfer.nToken==3 |
| 1611 | && (syncFlags & SYNC_CLONE)!=0 |
| 1612 | && blob_is_uuid(&xfer.aToken[1]) |
| 1613 | && blob_is_uuid(&xfer.aToken[2]) |
| 1614 | ){ |
| 1615 | if( blob_eq_str(&xfer.aToken[1], zSCode, -1) ){ |
| 1616 | fossil_fatal("server loop"); |
| @@ -1604,11 +1636,12 @@ | |
| 1636 | Blob content; |
| 1637 | blob_zero(&content); |
| 1638 | blob_extract(xfer.pIn, size, &content); |
| 1639 | g.perm.Admin = g.perm.RdAddr = 1; |
| 1640 | configure_receive(zName, &content, origConfigRcvMask); |
| 1641 | nCardRcvd++; |
| 1642 | nArtifactRcvd++; |
| 1643 | blob_reset(&content); |
| 1644 | blob_seek(xfer.pIn, 1, BLOB_SEEK_CUR); |
| 1645 | }else |
| 1646 | |
| 1647 | |
| @@ -1655,12 +1688,12 @@ | |
| 1688 | ** to the next cycle. |
| 1689 | */ |
| 1690 | if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){ |
| 1691 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1692 | defossilize(zMsg); |
| 1693 | if( (syncFlags & SYNC_PUSH) && zMsg && strglob("pull only *", zMsg) ){ |
| 1694 | syncFlags &= ~SYNC_PUSH; |
| 1695 | zMsg = 0; |
| 1696 | } |
| 1697 | fossil_print("\rServer says: %s\n", zMsg); |
| 1698 | }else |
| 1699 | |
| @@ -1683,11 +1716,11 @@ | |
| 1716 | ** is returned in the reply before the error card, so second and |
| 1717 | ** subsequent messages should be OK. Nevertheless, we need to ignore |
| 1718 | ** the error card on the first message of a clone. |
| 1719 | */ |
| 1720 | if( blob_eq(&xfer.aToken[0],"error") && xfer.nToken==2 ){ |
| 1721 | if( (syncFlags & SYNC_CLONE)==0 || nCycle>0 ){ |
| 1722 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1723 | defossilize(zMsg); |
| 1724 | if( fossil_strcmp(zMsg, "login failed")==0 ){ |
| 1725 | if( nCycle<2 ){ |
| 1726 | if( !g.dontKeepUrl ) db_unset("last-sync-pw", 0); |
| @@ -1727,14 +1760,16 @@ | |
| 1760 | && (configRcvMask & CONFIGSET_OLDFORMAT)!=0 |
| 1761 | ){ |
| 1762 | configure_finalize_receive(); |
| 1763 | } |
| 1764 | origConfigRcvMask = 0; |
| 1765 | if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){ |
| 1766 | fossil_print(zValueFormat, "Received:", |
| 1767 | blob_size(&recv), nCardRcvd, |
| 1768 | xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile); |
| 1769 | }else{ |
| 1770 | fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd); |
| 1771 | } |
| 1772 | blob_reset(&recv); |
| 1773 | nCycle++; |
| 1774 | |
| 1775 | /* If we received one or more files on the previous exchange but |
| @@ -1743,11 +1778,11 @@ | |
| 1778 | nFileRecv = xfer.nFileRcvd + xfer.nDeltaRcvd + xfer.nDanglingFile; |
| 1779 | if( (nFileRecv>0 || newPhantom) && db_exists("SELECT 1 FROM phantom") ){ |
| 1780 | go = 1; |
| 1781 | mxPhantomReq = nFileRecv*2; |
| 1782 | if( mxPhantomReq<200 ) mxPhantomReq = 200; |
| 1783 | }else if( (syncFlags & SYNC_CLONE)!=0 && nFileRecv>0 ){ |
| 1784 | go = 1; |
| 1785 | } |
| 1786 | nCardRcvd = 0; |
| 1787 | xfer.nFileRcvd = 0; |
| 1788 | xfer.nDeltaRcvd = 0; |
| @@ -1759,25 +1794,27 @@ | |
| 1794 | if( xfer.nFileSent+xfer.nDeltaSent>0 ){ |
| 1795 | go = 1; |
| 1796 | } |
| 1797 | |
| 1798 | /* If this is a clone, the go at least two rounds */ |
| 1799 | if( (syncFlags & SYNC_CLONE)!=0 && nCycle==1 ) go = 1; |
| 1800 | |
| 1801 | /* Stop the cycle if the server sends a "clone_seqno 0" card and |
| 1802 | ** we have gone at least two rounds. Always go at least two rounds |
| 1803 | ** on a clone in order to be sure to retrieve the configuration |
| 1804 | ** information which is only sent on the second round. |
| 1805 | */ |
| 1806 | if( cloneSeqno<=0 && nCycle>1 ) go = 0; |
| 1807 | }; |
| 1808 | transport_stats(&nSent, &nRcvd, 1); |
| 1809 | if( (syncFlags & SYNC_VERBOSE)==0 ) fossil_print("\n"); |
| 1810 | fossil_print( |
| 1811 | "%s finished with %lld bytes sent, %lld bytes received\n", |
| 1812 | zOpType, nSent, nRcvd); |
| 1813 | transport_close(); |
| 1814 | transport_global_shutdown(); |
| 1815 | db_multi_exec("DROP TABLE onremote"); |
| 1816 | manifest_crosslink_end(); |
| 1817 | content_enable_dephantomize(1); |
| 1818 | db_end_transaction(0); |
| 1819 | return nErr; |
| 1820 | } |
| 1821 |
+80
-43
| --- src/xfer.c | ||
| +++ src/xfer.c | ||
| @@ -1266,11 +1266,23 @@ | ||
| 1266 | 1266 | /* |
| 1267 | 1267 | ** Format strings for progress reporting. |
| 1268 | 1268 | */ |
| 1269 | 1269 | static const char zLabelFormat[] = "%-10s %10s %10s %10s %10s\n"; |
| 1270 | 1270 | static const char zValueFormat[] = "\r%-10s %10d %10d %10d %10d\n"; |
| 1271 | +static const char zBriefFormat[] = | |
| 1272 | + "Round-trips: %d Artifacts sent: %d received: %d\r"; | |
| 1271 | 1273 | |
| 1274 | +#if INTERFACE | |
| 1275 | +/* | |
| 1276 | +** Flag options for controlling client_sync() | |
| 1277 | +*/ | |
| 1278 | +#define SYNC_PUSH 0x0001 | |
| 1279 | +#define SYNC_PULL 0x0002 | |
| 1280 | +#define SYNC_CLONE 0x0004 | |
| 1281 | +#define SYNC_PRIVATE 0x0008 | |
| 1282 | +#define SYNC_VERBOSE 0x0010 | |
| 1283 | +#endif | |
| 1272 | 1284 | |
| 1273 | 1285 | /* |
| 1274 | 1286 | ** Sync to the host identified in g.urlName and g.urlPath. This |
| 1275 | 1287 | ** routine is called by the client. |
| 1276 | 1288 | ** |
| @@ -1277,16 +1289,13 @@ | ||
| 1277 | 1289 | ** Records are pushed to the server if pushFlag is true. Records |
| 1278 | 1290 | ** are pulled if pullFlag is true. A full sync occurs if both are |
| 1279 | 1291 | ** true. |
| 1280 | 1292 | */ |
| 1281 | 1293 | int client_sync( |
| 1282 | - int pushFlag, /* True to do a push (or a sync) */ | |
| 1283 | - int pullFlag, /* True to do a pull (or a sync) */ | |
| 1284 | - int cloneFlag, /* True if this is a clone */ | |
| 1285 | - int privateFlag, /* True to exchange private branches */ | |
| 1286 | - int configRcvMask, /* Receive these configuration items */ | |
| 1287 | - int configSendMask /* Send these configuration items */ | |
| 1294 | + unsigned syncFlags, /* Mask of SYNC_* flags */ | |
| 1295 | + unsigned configRcvMask, /* Receive these configuration items */ | |
| 1296 | + unsigned configSendMask /* Send these configuration items */ | |
| 1288 | 1297 | ){ |
| 1289 | 1298 | int go = 1; /* Loop until zero */ |
| 1290 | 1299 | int nCardSent = 0; /* Number of cards sent */ |
| 1291 | 1300 | int nCardRcvd = 0; /* Number of cards received */ |
| 1292 | 1301 | int nCycle = 0; /* Number of round trips to the server */ |
| @@ -1304,27 +1313,30 @@ | ||
| 1304 | 1313 | int lastPctDone = -1; /* Last displayed pctDone */ |
| 1305 | 1314 | double rArrivalTime; /* Time at which a message arrived */ |
| 1306 | 1315 | const char *zSCode = db_get("server-code", "x"); |
| 1307 | 1316 | const char *zPCode = db_get("project-code", 0); |
| 1308 | 1317 | int nErr = 0; /* Number of errors */ |
| 1318 | + int nRoundtrip= 0; /* Number of HTTP requests */ | |
| 1319 | + int nArtifactSent = 0; /* Total artifacts sent */ | |
| 1320 | + int nArtifactRcvd = 0; /* Total artifacts received */ | |
| 1321 | + const char *zOpType = 0;/* Push, Pull, Sync, Clone */ | |
| 1309 | 1322 | |
| 1310 | - if( db_get_boolean("dont-push", 0) ) pushFlag = 0; | |
| 1311 | - if( pushFlag + pullFlag + cloneFlag == 0 | |
| 1323 | + if( db_get_boolean("dont-push", 0) ) syncFlags &= ~SYNC_PUSH; | |
| 1324 | + if( (syncFlags & (SYNC_PUSH|SYNC_PULL|SYNC_CLONE))==0 | |
| 1312 | 1325 | && configRcvMask==0 && configSendMask==0 ) return 0; |
| 1313 | 1326 | |
| 1314 | 1327 | transport_stats(0, 0, 1); |
| 1315 | 1328 | socket_global_init(); |
| 1316 | 1329 | memset(&xfer, 0, sizeof(xfer)); |
| 1317 | 1330 | xfer.pIn = &recv; |
| 1318 | 1331 | xfer.pOut = &send; |
| 1319 | 1332 | xfer.mxSend = db_get_int("max-upload", 250000); |
| 1320 | - if( privateFlag ){ | |
| 1333 | + if( syncFlags & SYNC_PRIVATE ){ | |
| 1321 | 1334 | g.perm.Private = 1; |
| 1322 | 1335 | xfer.syncPrivate = 1; |
| 1323 | 1336 | } |
| 1324 | 1337 | |
| 1325 | - assert( pushFlag | pullFlag | cloneFlag | configRcvMask | configSendMask ); | |
| 1326 | 1338 | db_begin_transaction(); |
| 1327 | 1339 | db_record_repository_filename(0); |
| 1328 | 1340 | db_multi_exec( |
| 1329 | 1341 | "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);" |
| 1330 | 1342 | ); |
| @@ -1335,33 +1347,39 @@ | ||
| 1335 | 1347 | blob_zero(&xfer.line); |
| 1336 | 1348 | origConfigRcvMask = 0; |
| 1337 | 1349 | |
| 1338 | 1350 | |
| 1339 | 1351 | /* Send the send-private pragma if we are trying to sync private data */ |
| 1340 | - if( privateFlag ) blob_append(&send, "pragma send-private\n", -1); | |
| 1352 | + if( syncFlags & SYNC_PRIVATE ){ | |
| 1353 | + blob_append(&send, "pragma send-private\n", -1); | |
| 1354 | + } | |
| 1341 | 1355 | |
| 1342 | 1356 | /* |
| 1343 | 1357 | ** Always begin with a clone, pull, or push message |
| 1344 | 1358 | */ |
| 1345 | - if( cloneFlag ){ | |
| 1359 | + if( syncFlags & SYNC_CLONE ){ | |
| 1346 | 1360 | blob_appendf(&send, "clone 3 %d\n", cloneSeqno); |
| 1347 | - pushFlag = 0; | |
| 1348 | - pullFlag = 0; | |
| 1361 | + syncFlags &= ~(SYNC_PUSH|SYNC_PULL); | |
| 1349 | 1362 | nCardSent++; |
| 1350 | 1363 | /* TBD: Request all transferable configuration values */ |
| 1351 | 1364 | content_enable_dephantomize(0); |
| 1352 | - }else if( pullFlag ){ | |
| 1365 | + zOpType = "Clone"; | |
| 1366 | + }else if( syncFlags & SYNC_PULL ){ | |
| 1353 | 1367 | blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); |
| 1354 | 1368 | nCardSent++; |
| 1369 | + zOpType = "Pull"; | |
| 1355 | 1370 | } |
| 1356 | - if( pushFlag ){ | |
| 1371 | + if( syncFlags & SYNC_PUSH ){ | |
| 1357 | 1372 | blob_appendf(&send, "push %s %s\n", zSCode, zPCode); |
| 1358 | 1373 | nCardSent++; |
| 1374 | + if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push"; | |
| 1359 | 1375 | } |
| 1360 | 1376 | manifest_crosslink_begin(); |
| 1361 | 1377 | transport_global_startup(); |
| 1362 | - fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas"); | |
| 1378 | + if( syncFlags & SYNC_VERBOSE ){ | |
| 1379 | + fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas"); | |
| 1380 | + } | |
| 1363 | 1381 | |
| 1364 | 1382 | while( go ){ |
| 1365 | 1383 | int newPhantom = 0; |
| 1366 | 1384 | char *zRandomness; |
| 1367 | 1385 | |
| @@ -1374,25 +1392,28 @@ | ||
| 1374 | 1392 | } |
| 1375 | 1393 | |
| 1376 | 1394 | /* Generate gimme cards for phantoms and leaf cards |
| 1377 | 1395 | ** for all leaves. |
| 1378 | 1396 | */ |
| 1379 | - if( pullFlag || (cloneFlag && cloneSeqno==1) ){ | |
| 1397 | + if( (syncFlags & SYNC_PULL)!=0 | |
| 1398 | + || ((syncFlags & SYNC_CLONE)!=0 && cloneSeqno==1) | |
| 1399 | + ){ | |
| 1380 | 1400 | request_phantoms(&xfer, mxPhantomReq); |
| 1381 | 1401 | } |
| 1382 | - if( pushFlag ){ | |
| 1402 | + if( syncFlags & SYNC_PUSH ){ | |
| 1383 | 1403 | send_unsent(&xfer); |
| 1384 | 1404 | nCardSent += send_unclustered(&xfer); |
| 1385 | - if( privateFlag ) send_private(&xfer); | |
| 1405 | + if( syncFlags & SYNC_PRIVATE ) send_private(&xfer); | |
| 1386 | 1406 | } |
| 1387 | 1407 | |
| 1388 | 1408 | /* Send configuration parameter requests. On a clone, delay sending |
| 1389 | 1409 | ** this until the second cycle since the login card might fail on |
| 1390 | 1410 | ** the first cycle. |
| 1391 | 1411 | */ |
| 1392 | - if( configRcvMask && (cloneFlag==0 || nCycle>0) ){ | |
| 1412 | + if( configRcvMask && ((syncFlags & SYNC_CLONE)==0 || nCycle>0) ){ | |
| 1393 | 1413 | const char *zName; |
| 1414 | + if( zOpType==0 ) zOpType = "Pull"; | |
| 1394 | 1415 | zName = configure_first_name(configRcvMask); |
| 1395 | 1416 | while( zName ){ |
| 1396 | 1417 | blob_appendf(&send, "reqconfig %s\n", zName); |
| 1397 | 1418 | zName = configure_next_name(configRcvMask); |
| 1398 | 1419 | nCardSent++; |
| @@ -1407,10 +1428,11 @@ | ||
| 1407 | 1428 | configRcvMask = 0; |
| 1408 | 1429 | } |
| 1409 | 1430 | |
| 1410 | 1431 | /* Send configuration parameters being pushed */ |
| 1411 | 1432 | if( configSendMask ){ |
| 1433 | + if( zOpType==0 ) zOpType = "Push"; | |
| 1412 | 1434 | if( configSendMask & CONFIGSET_OLDFORMAT ){ |
| 1413 | 1435 | const char *zName; |
| 1414 | 1436 | zName = configure_first_name(configSendMask); |
| 1415 | 1437 | while( zName ){ |
| 1416 | 1438 | send_legacy_config_card(&xfer, zName); |
| @@ -1430,42 +1452,50 @@ | ||
| 1430 | 1452 | zRandomness = db_text(0, "SELECT hex(randomblob(20))"); |
| 1431 | 1453 | blob_appendf(&send, "# %s\n", zRandomness); |
| 1432 | 1454 | free(zRandomness); |
| 1433 | 1455 | |
| 1434 | 1456 | /* Exchange messages with the server */ |
| 1435 | - fossil_print(zValueFormat, "Sent:", | |
| 1436 | - blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent, | |
| 1437 | - xfer.nFileSent, xfer.nDeltaSent); | |
| 1457 | + if( syncFlags & SYNC_VERBOSE ){ | |
| 1458 | + fossil_print(zValueFormat, "Sent:", | |
| 1459 | + blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent, | |
| 1460 | + xfer.nFileSent, xfer.nDeltaSent); | |
| 1461 | + }else{ | |
| 1462 | + nRoundtrip++; | |
| 1463 | + nArtifactSent += xfer.nFileSent + xfer.nDeltaSent; | |
| 1464 | + fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd); | |
| 1465 | + } | |
| 1438 | 1466 | nCardSent = 0; |
| 1439 | 1467 | nCardRcvd = 0; |
| 1440 | 1468 | xfer.nFileSent = 0; |
| 1441 | 1469 | xfer.nDeltaSent = 0; |
| 1442 | 1470 | xfer.nGimmeSent = 0; |
| 1443 | 1471 | xfer.nIGotSent = 0; |
| 1444 | - if( !g.cgiOutput && !g.fQuiet ){ | |
| 1472 | + if( syncFlags & SYNC_VERBOSE ){ | |
| 1445 | 1473 | fossil_print("waiting for server..."); |
| 1446 | 1474 | } |
| 1447 | 1475 | fflush(stdout); |
| 1448 | - if( http_exchange(&send, &recv, cloneFlag==0 || nCycle>0) ){ | |
| 1476 | + if( http_exchange(&send, &recv, (syncFlags & SYNC_CLONE)==0 || nCycle>0) ){ | |
| 1449 | 1477 | nErr++; |
| 1450 | 1478 | break; |
| 1451 | 1479 | } |
| 1452 | 1480 | lastPctDone = -1; |
| 1453 | 1481 | blob_reset(&send); |
| 1454 | 1482 | rArrivalTime = db_double(0.0, "SELECT julianday('now')"); |
| 1455 | 1483 | |
| 1456 | 1484 | /* Send the send-private pragma if we are trying to sync private data */ |
| 1457 | - if( privateFlag ) blob_append(&send, "pragma send-private\n", -1); | |
| 1485 | + if( syncFlags & SYNC_PRIVATE ){ | |
| 1486 | + blob_append(&send, "pragma send-private\n", -1); | |
| 1487 | + } | |
| 1458 | 1488 | |
| 1459 | 1489 | /* Begin constructing the next message (which might never be |
| 1460 | 1490 | ** sent) by beginning with the pull or push cards |
| 1461 | 1491 | */ |
| 1462 | - if( pullFlag ){ | |
| 1492 | + if( syncFlags & SYNC_PULL ){ | |
| 1463 | 1493 | blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); |
| 1464 | 1494 | nCardSent++; |
| 1465 | 1495 | } |
| 1466 | - if( pushFlag ){ | |
| 1496 | + if( syncFlags & SYNC_PUSH ){ | |
| 1467 | 1497 | blob_appendf(&send, "push %s %s\n", zSCode, zPCode); |
| 1468 | 1498 | nCardSent++; |
| 1469 | 1499 | } |
| 1470 | 1500 | go = 0; |
| 1471 | 1501 | |
| @@ -1493,11 +1523,11 @@ | ||
| 1493 | 1523 | nCardRcvd++; |
| 1494 | 1524 | continue; |
| 1495 | 1525 | } |
| 1496 | 1526 | xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken)); |
| 1497 | 1527 | nCardRcvd++; |
| 1498 | - if( !g.cgiOutput && !g.fQuiet && recv.nUsed>0 ){ | |
| 1528 | + if( (syncFlags & SYNC_VERBOSE)!=0 && recv.nUsed>0 ){ | |
| 1499 | 1529 | pctDone = (recv.iCursor*100)/recv.nUsed; |
| 1500 | 1530 | if( pctDone!=lastPctDone ){ |
| 1501 | 1531 | fossil_print("\rprocessed: %d%% ", pctDone); |
| 1502 | 1532 | lastPctDone = pctDone; |
| 1503 | 1533 | fflush(stdout); |
| @@ -1508,20 +1538,22 @@ | ||
| 1508 | 1538 | ** file UUID DELTASRC SIZE \n CONTENT |
| 1509 | 1539 | ** |
| 1510 | 1540 | ** Receive a file transmitted from the server. |
| 1511 | 1541 | */ |
| 1512 | 1542 | if( blob_eq(&xfer.aToken[0],"file") ){ |
| 1513 | - xfer_accept_file(&xfer, cloneFlag); | |
| 1543 | + xfer_accept_file(&xfer, (syncFlags & SYNC_CLONE)!=0); | |
| 1544 | + nArtifactRcvd++; | |
| 1514 | 1545 | }else |
| 1515 | 1546 | |
| 1516 | 1547 | /* cfile UUID USIZE CSIZE \n CONTENT |
| 1517 | 1548 | ** cfile UUID DELTASRC USIZE CSIZE \n CONTENT |
| 1518 | 1549 | ** |
| 1519 | 1550 | ** Receive a compressed file transmitted from the server. |
| 1520 | 1551 | */ |
| 1521 | 1552 | if( blob_eq(&xfer.aToken[0],"cfile") ){ |
| 1522 | 1553 | xfer_accept_compressed_file(&xfer); |
| 1554 | + nArtifactRcvd++; | |
| 1523 | 1555 | }else |
| 1524 | 1556 | |
| 1525 | 1557 | /* gimme UUID |
| 1526 | 1558 | ** |
| 1527 | 1559 | ** Server is requesting a file. If the file is a manifest, assume |
| @@ -1530,11 +1562,11 @@ | ||
| 1530 | 1562 | */ |
| 1531 | 1563 | if( blob_eq(&xfer.aToken[0], "gimme") |
| 1532 | 1564 | && xfer.nToken==2 |
| 1533 | 1565 | && blob_is_uuid(&xfer.aToken[1]) |
| 1534 | 1566 | ){ |
| 1535 | - if( pushFlag ){ | |
| 1567 | + if( syncFlags & SYNC_PUSH ){ | |
| 1536 | 1568 | int rid = rid_from_uuid(&xfer.aToken[1], 0, 0); |
| 1537 | 1569 | if( rid ) send_file(&xfer, rid, &xfer.aToken[1], 0); |
| 1538 | 1570 | } |
| 1539 | 1571 | }else |
| 1540 | 1572 | |
| @@ -1559,11 +1591,11 @@ | ||
| 1559 | 1591 | rid = rid_from_uuid(&xfer.aToken[1], 0, 0); |
| 1560 | 1592 | if( rid>0 ){ |
| 1561 | 1593 | if( !isPriv ) content_make_public(rid); |
| 1562 | 1594 | }else if( isPriv && !g.perm.Private ){ |
| 1563 | 1595 | /* ignore private files */ |
| 1564 | - }else if( pullFlag || cloneFlag ){ | |
| 1596 | + }else if( (syncFlags & (SYNC_PULL|SYNC_CLONE))!=0 ){ | |
| 1565 | 1597 | rid = content_new(blob_str(&xfer.aToken[1]), isPriv); |
| 1566 | 1598 | if( rid ) newPhantom = 1; |
| 1567 | 1599 | } |
| 1568 | 1600 | remote_has(rid); |
| 1569 | 1601 | }else |
| @@ -1574,11 +1606,11 @@ | ||
| 1574 | 1606 | ** Should only happen in response to a clone. This message tells |
| 1575 | 1607 | ** the client what product to use for the new database. |
| 1576 | 1608 | */ |
| 1577 | 1609 | if( blob_eq(&xfer.aToken[0],"push") |
| 1578 | 1610 | && xfer.nToken==3 |
| 1579 | - && cloneFlag | |
| 1611 | + && (syncFlags & SYNC_CLONE)!=0 | |
| 1580 | 1612 | && blob_is_uuid(&xfer.aToken[1]) |
| 1581 | 1613 | && blob_is_uuid(&xfer.aToken[2]) |
| 1582 | 1614 | ){ |
| 1583 | 1615 | if( blob_eq_str(&xfer.aToken[1], zSCode, -1) ){ |
| 1584 | 1616 | fossil_fatal("server loop"); |
| @@ -1604,11 +1636,12 @@ | ||
| 1604 | 1636 | Blob content; |
| 1605 | 1637 | blob_zero(&content); |
| 1606 | 1638 | blob_extract(xfer.pIn, size, &content); |
| 1607 | 1639 | g.perm.Admin = g.perm.RdAddr = 1; |
| 1608 | 1640 | configure_receive(zName, &content, origConfigRcvMask); |
| 1609 | - nCardSent++; | |
| 1641 | + nCardRcvd++; | |
| 1642 | + nArtifactRcvd++; | |
| 1610 | 1643 | blob_reset(&content); |
| 1611 | 1644 | blob_seek(xfer.pIn, 1, BLOB_SEEK_CUR); |
| 1612 | 1645 | }else |
| 1613 | 1646 | |
| 1614 | 1647 | |
| @@ -1655,12 +1688,12 @@ | ||
| 1655 | 1688 | ** to the next cycle. |
| 1656 | 1689 | */ |
| 1657 | 1690 | if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){ |
| 1658 | 1691 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1659 | 1692 | defossilize(zMsg); |
| 1660 | - if( pushFlag && zMsg && strglob("pull only *", zMsg) ){ | |
| 1661 | - pushFlag = 0; | |
| 1693 | + if( (syncFlags & SYNC_PUSH) && zMsg && strglob("pull only *", zMsg) ){ | |
| 1694 | + syncFlags &= ~SYNC_PUSH; | |
| 1662 | 1695 | zMsg = 0; |
| 1663 | 1696 | } |
| 1664 | 1697 | fossil_print("\rServer says: %s\n", zMsg); |
| 1665 | 1698 | }else |
| 1666 | 1699 | |
| @@ -1683,11 +1716,11 @@ | ||
| 1683 | 1716 | ** is returned in the reply before the error card, so second and |
| 1684 | 1717 | ** subsequent messages should be OK. Nevertheless, we need to ignore |
| 1685 | 1718 | ** the error card on the first message of a clone. |
| 1686 | 1719 | */ |
| 1687 | 1720 | if( blob_eq(&xfer.aToken[0],"error") && xfer.nToken==2 ){ |
| 1688 | - if( !cloneFlag || nCycle>0 ){ | |
| 1721 | + if( (syncFlags & SYNC_CLONE)==0 || nCycle>0 ){ | |
| 1689 | 1722 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1690 | 1723 | defossilize(zMsg); |
| 1691 | 1724 | if( fossil_strcmp(zMsg, "login failed")==0 ){ |
| 1692 | 1725 | if( nCycle<2 ){ |
| 1693 | 1726 | if( !g.dontKeepUrl ) db_unset("last-sync-pw", 0); |
| @@ -1727,14 +1760,16 @@ | ||
| 1727 | 1760 | && (configRcvMask & CONFIGSET_OLDFORMAT)!=0 |
| 1728 | 1761 | ){ |
| 1729 | 1762 | configure_finalize_receive(); |
| 1730 | 1763 | } |
| 1731 | 1764 | origConfigRcvMask = 0; |
| 1732 | - if( nCardRcvd>0 ){ | |
| 1765 | + if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){ | |
| 1733 | 1766 | fossil_print(zValueFormat, "Received:", |
| 1734 | 1767 | blob_size(&recv), nCardRcvd, |
| 1735 | 1768 | xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile); |
| 1769 | + }else{ | |
| 1770 | + fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd); | |
| 1736 | 1771 | } |
| 1737 | 1772 | blob_reset(&recv); |
| 1738 | 1773 | nCycle++; |
| 1739 | 1774 | |
| 1740 | 1775 | /* If we received one or more files on the previous exchange but |
| @@ -1743,11 +1778,11 @@ | ||
| 1743 | 1778 | nFileRecv = xfer.nFileRcvd + xfer.nDeltaRcvd + xfer.nDanglingFile; |
| 1744 | 1779 | if( (nFileRecv>0 || newPhantom) && db_exists("SELECT 1 FROM phantom") ){ |
| 1745 | 1780 | go = 1; |
| 1746 | 1781 | mxPhantomReq = nFileRecv*2; |
| 1747 | 1782 | if( mxPhantomReq<200 ) mxPhantomReq = 200; |
| 1748 | - }else if( cloneFlag && nFileRecv>0 ){ | |
| 1783 | + }else if( (syncFlags & SYNC_CLONE)!=0 && nFileRecv>0 ){ | |
| 1749 | 1784 | go = 1; |
| 1750 | 1785 | } |
| 1751 | 1786 | nCardRcvd = 0; |
| 1752 | 1787 | xfer.nFileRcvd = 0; |
| 1753 | 1788 | xfer.nDeltaRcvd = 0; |
| @@ -1759,25 +1794,27 @@ | ||
| 1759 | 1794 | if( xfer.nFileSent+xfer.nDeltaSent>0 ){ |
| 1760 | 1795 | go = 1; |
| 1761 | 1796 | } |
| 1762 | 1797 | |
| 1763 | 1798 | /* If this is a clone, the go at least two rounds */ |
| 1764 | - if( cloneFlag && nCycle==1 ) go = 1; | |
| 1799 | + if( (syncFlags & SYNC_CLONE)!=0 && nCycle==1 ) go = 1; | |
| 1765 | 1800 | |
| 1766 | 1801 | /* Stop the cycle if the server sends a "clone_seqno 0" card and |
| 1767 | 1802 | ** we have gone at least two rounds. Always go at least two rounds |
| 1768 | 1803 | ** on a clone in order to be sure to retrieve the configuration |
| 1769 | 1804 | ** information which is only sent on the second round. |
| 1770 | 1805 | */ |
| 1771 | 1806 | if( cloneSeqno<=0 && nCycle>1 ) go = 0; |
| 1772 | 1807 | }; |
| 1773 | 1808 | transport_stats(&nSent, &nRcvd, 1); |
| 1774 | - fossil_print("Total network traffic: %lld bytes sent, %lld bytes received\n", | |
| 1775 | - nSent, nRcvd); | |
| 1809 | + if( (syncFlags & SYNC_VERBOSE)==0 ) fossil_print("\n"); | |
| 1810 | + fossil_print( | |
| 1811 | + "%s finished with %lld bytes sent, %lld bytes received\n", | |
| 1812 | + zOpType, nSent, nRcvd); | |
| 1776 | 1813 | transport_close(); |
| 1777 | 1814 | transport_global_shutdown(); |
| 1778 | 1815 | db_multi_exec("DROP TABLE onremote"); |
| 1779 | 1816 | manifest_crosslink_end(); |
| 1780 | 1817 | content_enable_dephantomize(1); |
| 1781 | 1818 | db_end_transaction(0); |
| 1782 | 1819 | return nErr; |
| 1783 | 1820 | } |
| 1784 | 1821 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -1266,11 +1266,23 @@ | |
| 1266 | /* |
| 1267 | ** Format strings for progress reporting. |
| 1268 | */ |
| 1269 | static const char zLabelFormat[] = "%-10s %10s %10s %10s %10s\n"; |
| 1270 | static const char zValueFormat[] = "\r%-10s %10d %10d %10d %10d\n"; |
| 1271 | |
| 1272 | |
| 1273 | /* |
| 1274 | ** Sync to the host identified in g.urlName and g.urlPath. This |
| 1275 | ** routine is called by the client. |
| 1276 | ** |
| @@ -1277,16 +1289,13 @@ | |
| 1277 | ** Records are pushed to the server if pushFlag is true. Records |
| 1278 | ** are pulled if pullFlag is true. A full sync occurs if both are |
| 1279 | ** true. |
| 1280 | */ |
| 1281 | int client_sync( |
| 1282 | int pushFlag, /* True to do a push (or a sync) */ |
| 1283 | int pullFlag, /* True to do a pull (or a sync) */ |
| 1284 | int cloneFlag, /* True if this is a clone */ |
| 1285 | int privateFlag, /* True to exchange private branches */ |
| 1286 | int configRcvMask, /* Receive these configuration items */ |
| 1287 | int configSendMask /* Send these configuration items */ |
| 1288 | ){ |
| 1289 | int go = 1; /* Loop until zero */ |
| 1290 | int nCardSent = 0; /* Number of cards sent */ |
| 1291 | int nCardRcvd = 0; /* Number of cards received */ |
| 1292 | int nCycle = 0; /* Number of round trips to the server */ |
| @@ -1304,27 +1313,30 @@ | |
| 1304 | int lastPctDone = -1; /* Last displayed pctDone */ |
| 1305 | double rArrivalTime; /* Time at which a message arrived */ |
| 1306 | const char *zSCode = db_get("server-code", "x"); |
| 1307 | const char *zPCode = db_get("project-code", 0); |
| 1308 | int nErr = 0; /* Number of errors */ |
| 1309 | |
| 1310 | if( db_get_boolean("dont-push", 0) ) pushFlag = 0; |
| 1311 | if( pushFlag + pullFlag + cloneFlag == 0 |
| 1312 | && configRcvMask==0 && configSendMask==0 ) return 0; |
| 1313 | |
| 1314 | transport_stats(0, 0, 1); |
| 1315 | socket_global_init(); |
| 1316 | memset(&xfer, 0, sizeof(xfer)); |
| 1317 | xfer.pIn = &recv; |
| 1318 | xfer.pOut = &send; |
| 1319 | xfer.mxSend = db_get_int("max-upload", 250000); |
| 1320 | if( privateFlag ){ |
| 1321 | g.perm.Private = 1; |
| 1322 | xfer.syncPrivate = 1; |
| 1323 | } |
| 1324 | |
| 1325 | assert( pushFlag | pullFlag | cloneFlag | configRcvMask | configSendMask ); |
| 1326 | db_begin_transaction(); |
| 1327 | db_record_repository_filename(0); |
| 1328 | db_multi_exec( |
| 1329 | "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);" |
| 1330 | ); |
| @@ -1335,33 +1347,39 @@ | |
| 1335 | blob_zero(&xfer.line); |
| 1336 | origConfigRcvMask = 0; |
| 1337 | |
| 1338 | |
| 1339 | /* Send the send-private pragma if we are trying to sync private data */ |
| 1340 | if( privateFlag ) blob_append(&send, "pragma send-private\n", -1); |
| 1341 | |
| 1342 | /* |
| 1343 | ** Always begin with a clone, pull, or push message |
| 1344 | */ |
| 1345 | if( cloneFlag ){ |
| 1346 | blob_appendf(&send, "clone 3 %d\n", cloneSeqno); |
| 1347 | pushFlag = 0; |
| 1348 | pullFlag = 0; |
| 1349 | nCardSent++; |
| 1350 | /* TBD: Request all transferable configuration values */ |
| 1351 | content_enable_dephantomize(0); |
| 1352 | }else if( pullFlag ){ |
| 1353 | blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); |
| 1354 | nCardSent++; |
| 1355 | } |
| 1356 | if( pushFlag ){ |
| 1357 | blob_appendf(&send, "push %s %s\n", zSCode, zPCode); |
| 1358 | nCardSent++; |
| 1359 | } |
| 1360 | manifest_crosslink_begin(); |
| 1361 | transport_global_startup(); |
| 1362 | fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas"); |
| 1363 | |
| 1364 | while( go ){ |
| 1365 | int newPhantom = 0; |
| 1366 | char *zRandomness; |
| 1367 | |
| @@ -1374,25 +1392,28 @@ | |
| 1374 | } |
| 1375 | |
| 1376 | /* Generate gimme cards for phantoms and leaf cards |
| 1377 | ** for all leaves. |
| 1378 | */ |
| 1379 | if( pullFlag || (cloneFlag && cloneSeqno==1) ){ |
| 1380 | request_phantoms(&xfer, mxPhantomReq); |
| 1381 | } |
| 1382 | if( pushFlag ){ |
| 1383 | send_unsent(&xfer); |
| 1384 | nCardSent += send_unclustered(&xfer); |
| 1385 | if( privateFlag ) send_private(&xfer); |
| 1386 | } |
| 1387 | |
| 1388 | /* Send configuration parameter requests. On a clone, delay sending |
| 1389 | ** this until the second cycle since the login card might fail on |
| 1390 | ** the first cycle. |
| 1391 | */ |
| 1392 | if( configRcvMask && (cloneFlag==0 || nCycle>0) ){ |
| 1393 | const char *zName; |
| 1394 | zName = configure_first_name(configRcvMask); |
| 1395 | while( zName ){ |
| 1396 | blob_appendf(&send, "reqconfig %s\n", zName); |
| 1397 | zName = configure_next_name(configRcvMask); |
| 1398 | nCardSent++; |
| @@ -1407,10 +1428,11 @@ | |
| 1407 | configRcvMask = 0; |
| 1408 | } |
| 1409 | |
| 1410 | /* Send configuration parameters being pushed */ |
| 1411 | if( configSendMask ){ |
| 1412 | if( configSendMask & CONFIGSET_OLDFORMAT ){ |
| 1413 | const char *zName; |
| 1414 | zName = configure_first_name(configSendMask); |
| 1415 | while( zName ){ |
| 1416 | send_legacy_config_card(&xfer, zName); |
| @@ -1430,42 +1452,50 @@ | |
| 1430 | zRandomness = db_text(0, "SELECT hex(randomblob(20))"); |
| 1431 | blob_appendf(&send, "# %s\n", zRandomness); |
| 1432 | free(zRandomness); |
| 1433 | |
| 1434 | /* Exchange messages with the server */ |
| 1435 | fossil_print(zValueFormat, "Sent:", |
| 1436 | blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent, |
| 1437 | xfer.nFileSent, xfer.nDeltaSent); |
| 1438 | nCardSent = 0; |
| 1439 | nCardRcvd = 0; |
| 1440 | xfer.nFileSent = 0; |
| 1441 | xfer.nDeltaSent = 0; |
| 1442 | xfer.nGimmeSent = 0; |
| 1443 | xfer.nIGotSent = 0; |
| 1444 | if( !g.cgiOutput && !g.fQuiet ){ |
| 1445 | fossil_print("waiting for server..."); |
| 1446 | } |
| 1447 | fflush(stdout); |
| 1448 | if( http_exchange(&send, &recv, cloneFlag==0 || nCycle>0) ){ |
| 1449 | nErr++; |
| 1450 | break; |
| 1451 | } |
| 1452 | lastPctDone = -1; |
| 1453 | blob_reset(&send); |
| 1454 | rArrivalTime = db_double(0.0, "SELECT julianday('now')"); |
| 1455 | |
| 1456 | /* Send the send-private pragma if we are trying to sync private data */ |
| 1457 | if( privateFlag ) blob_append(&send, "pragma send-private\n", -1); |
| 1458 | |
| 1459 | /* Begin constructing the next message (which might never be |
| 1460 | ** sent) by beginning with the pull or push cards |
| 1461 | */ |
| 1462 | if( pullFlag ){ |
| 1463 | blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); |
| 1464 | nCardSent++; |
| 1465 | } |
| 1466 | if( pushFlag ){ |
| 1467 | blob_appendf(&send, "push %s %s\n", zSCode, zPCode); |
| 1468 | nCardSent++; |
| 1469 | } |
| 1470 | go = 0; |
| 1471 | |
| @@ -1493,11 +1523,11 @@ | |
| 1493 | nCardRcvd++; |
| 1494 | continue; |
| 1495 | } |
| 1496 | xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken)); |
| 1497 | nCardRcvd++; |
| 1498 | if( !g.cgiOutput && !g.fQuiet && recv.nUsed>0 ){ |
| 1499 | pctDone = (recv.iCursor*100)/recv.nUsed; |
| 1500 | if( pctDone!=lastPctDone ){ |
| 1501 | fossil_print("\rprocessed: %d%% ", pctDone); |
| 1502 | lastPctDone = pctDone; |
| 1503 | fflush(stdout); |
| @@ -1508,20 +1538,22 @@ | |
| 1508 | ** file UUID DELTASRC SIZE \n CONTENT |
| 1509 | ** |
| 1510 | ** Receive a file transmitted from the server. |
| 1511 | */ |
| 1512 | if( blob_eq(&xfer.aToken[0],"file") ){ |
| 1513 | xfer_accept_file(&xfer, cloneFlag); |
| 1514 | }else |
| 1515 | |
| 1516 | /* cfile UUID USIZE CSIZE \n CONTENT |
| 1517 | ** cfile UUID DELTASRC USIZE CSIZE \n CONTENT |
| 1518 | ** |
| 1519 | ** Receive a compressed file transmitted from the server. |
| 1520 | */ |
| 1521 | if( blob_eq(&xfer.aToken[0],"cfile") ){ |
| 1522 | xfer_accept_compressed_file(&xfer); |
| 1523 | }else |
| 1524 | |
| 1525 | /* gimme UUID |
| 1526 | ** |
| 1527 | ** Server is requesting a file. If the file is a manifest, assume |
| @@ -1530,11 +1562,11 @@ | |
| 1530 | */ |
| 1531 | if( blob_eq(&xfer.aToken[0], "gimme") |
| 1532 | && xfer.nToken==2 |
| 1533 | && blob_is_uuid(&xfer.aToken[1]) |
| 1534 | ){ |
| 1535 | if( pushFlag ){ |
| 1536 | int rid = rid_from_uuid(&xfer.aToken[1], 0, 0); |
| 1537 | if( rid ) send_file(&xfer, rid, &xfer.aToken[1], 0); |
| 1538 | } |
| 1539 | }else |
| 1540 | |
| @@ -1559,11 +1591,11 @@ | |
| 1559 | rid = rid_from_uuid(&xfer.aToken[1], 0, 0); |
| 1560 | if( rid>0 ){ |
| 1561 | if( !isPriv ) content_make_public(rid); |
| 1562 | }else if( isPriv && !g.perm.Private ){ |
| 1563 | /* ignore private files */ |
| 1564 | }else if( pullFlag || cloneFlag ){ |
| 1565 | rid = content_new(blob_str(&xfer.aToken[1]), isPriv); |
| 1566 | if( rid ) newPhantom = 1; |
| 1567 | } |
| 1568 | remote_has(rid); |
| 1569 | }else |
| @@ -1574,11 +1606,11 @@ | |
| 1574 | ** Should only happen in response to a clone. This message tells |
| 1575 | ** the client what product to use for the new database. |
| 1576 | */ |
| 1577 | if( blob_eq(&xfer.aToken[0],"push") |
| 1578 | && xfer.nToken==3 |
| 1579 | && cloneFlag |
| 1580 | && blob_is_uuid(&xfer.aToken[1]) |
| 1581 | && blob_is_uuid(&xfer.aToken[2]) |
| 1582 | ){ |
| 1583 | if( blob_eq_str(&xfer.aToken[1], zSCode, -1) ){ |
| 1584 | fossil_fatal("server loop"); |
| @@ -1604,11 +1636,12 @@ | |
| 1604 | Blob content; |
| 1605 | blob_zero(&content); |
| 1606 | blob_extract(xfer.pIn, size, &content); |
| 1607 | g.perm.Admin = g.perm.RdAddr = 1; |
| 1608 | configure_receive(zName, &content, origConfigRcvMask); |
| 1609 | nCardSent++; |
| 1610 | blob_reset(&content); |
| 1611 | blob_seek(xfer.pIn, 1, BLOB_SEEK_CUR); |
| 1612 | }else |
| 1613 | |
| 1614 | |
| @@ -1655,12 +1688,12 @@ | |
| 1655 | ** to the next cycle. |
| 1656 | */ |
| 1657 | if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){ |
| 1658 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1659 | defossilize(zMsg); |
| 1660 | if( pushFlag && zMsg && strglob("pull only *", zMsg) ){ |
| 1661 | pushFlag = 0; |
| 1662 | zMsg = 0; |
| 1663 | } |
| 1664 | fossil_print("\rServer says: %s\n", zMsg); |
| 1665 | }else |
| 1666 | |
| @@ -1683,11 +1716,11 @@ | |
| 1683 | ** is returned in the reply before the error card, so second and |
| 1684 | ** subsequent messages should be OK. Nevertheless, we need to ignore |
| 1685 | ** the error card on the first message of a clone. |
| 1686 | */ |
| 1687 | if( blob_eq(&xfer.aToken[0],"error") && xfer.nToken==2 ){ |
| 1688 | if( !cloneFlag || nCycle>0 ){ |
| 1689 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1690 | defossilize(zMsg); |
| 1691 | if( fossil_strcmp(zMsg, "login failed")==0 ){ |
| 1692 | if( nCycle<2 ){ |
| 1693 | if( !g.dontKeepUrl ) db_unset("last-sync-pw", 0); |
| @@ -1727,14 +1760,16 @@ | |
| 1727 | && (configRcvMask & CONFIGSET_OLDFORMAT)!=0 |
| 1728 | ){ |
| 1729 | configure_finalize_receive(); |
| 1730 | } |
| 1731 | origConfigRcvMask = 0; |
| 1732 | if( nCardRcvd>0 ){ |
| 1733 | fossil_print(zValueFormat, "Received:", |
| 1734 | blob_size(&recv), nCardRcvd, |
| 1735 | xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile); |
| 1736 | } |
| 1737 | blob_reset(&recv); |
| 1738 | nCycle++; |
| 1739 | |
| 1740 | /* If we received one or more files on the previous exchange but |
| @@ -1743,11 +1778,11 @@ | |
| 1743 | nFileRecv = xfer.nFileRcvd + xfer.nDeltaRcvd + xfer.nDanglingFile; |
| 1744 | if( (nFileRecv>0 || newPhantom) && db_exists("SELECT 1 FROM phantom") ){ |
| 1745 | go = 1; |
| 1746 | mxPhantomReq = nFileRecv*2; |
| 1747 | if( mxPhantomReq<200 ) mxPhantomReq = 200; |
| 1748 | }else if( cloneFlag && nFileRecv>0 ){ |
| 1749 | go = 1; |
| 1750 | } |
| 1751 | nCardRcvd = 0; |
| 1752 | xfer.nFileRcvd = 0; |
| 1753 | xfer.nDeltaRcvd = 0; |
| @@ -1759,25 +1794,27 @@ | |
| 1759 | if( xfer.nFileSent+xfer.nDeltaSent>0 ){ |
| 1760 | go = 1; |
| 1761 | } |
| 1762 | |
| 1763 | /* If this is a clone, the go at least two rounds */ |
| 1764 | if( cloneFlag && nCycle==1 ) go = 1; |
| 1765 | |
| 1766 | /* Stop the cycle if the server sends a "clone_seqno 0" card and |
| 1767 | ** we have gone at least two rounds. Always go at least two rounds |
| 1768 | ** on a clone in order to be sure to retrieve the configuration |
| 1769 | ** information which is only sent on the second round. |
| 1770 | */ |
| 1771 | if( cloneSeqno<=0 && nCycle>1 ) go = 0; |
| 1772 | }; |
| 1773 | transport_stats(&nSent, &nRcvd, 1); |
| 1774 | fossil_print("Total network traffic: %lld bytes sent, %lld bytes received\n", |
| 1775 | nSent, nRcvd); |
| 1776 | transport_close(); |
| 1777 | transport_global_shutdown(); |
| 1778 | db_multi_exec("DROP TABLE onremote"); |
| 1779 | manifest_crosslink_end(); |
| 1780 | content_enable_dephantomize(1); |
| 1781 | db_end_transaction(0); |
| 1782 | return nErr; |
| 1783 | } |
| 1784 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -1266,11 +1266,23 @@ | |
| 1266 | /* |
| 1267 | ** Format strings for progress reporting. |
| 1268 | */ |
| 1269 | static const char zLabelFormat[] = "%-10s %10s %10s %10s %10s\n"; |
| 1270 | static const char zValueFormat[] = "\r%-10s %10d %10d %10d %10d\n"; |
| 1271 | static const char zBriefFormat[] = |
| 1272 | "Round-trips: %d Artifacts sent: %d received: %d\r"; |
| 1273 | |
| 1274 | #if INTERFACE |
| 1275 | /* |
| 1276 | ** Flag options for controlling client_sync() |
| 1277 | */ |
| 1278 | #define SYNC_PUSH 0x0001 |
| 1279 | #define SYNC_PULL 0x0002 |
| 1280 | #define SYNC_CLONE 0x0004 |
| 1281 | #define SYNC_PRIVATE 0x0008 |
| 1282 | #define SYNC_VERBOSE 0x0010 |
| 1283 | #endif |
| 1284 | |
| 1285 | /* |
| 1286 | ** Sync to the host identified in g.urlName and g.urlPath. This |
| 1287 | ** routine is called by the client. |
| 1288 | ** |
| @@ -1277,16 +1289,13 @@ | |
| 1289 | ** Records are pushed to the server if pushFlag is true. Records |
| 1290 | ** are pulled if pullFlag is true. A full sync occurs if both are |
| 1291 | ** true. |
| 1292 | */ |
| 1293 | int client_sync( |
| 1294 | unsigned syncFlags, /* Mask of SYNC_* flags */ |
| 1295 | unsigned configRcvMask, /* Receive these configuration items */ |
| 1296 | unsigned configSendMask /* Send these configuration items */ |
| 1297 | ){ |
| 1298 | int go = 1; /* Loop until zero */ |
| 1299 | int nCardSent = 0; /* Number of cards sent */ |
| 1300 | int nCardRcvd = 0; /* Number of cards received */ |
| 1301 | int nCycle = 0; /* Number of round trips to the server */ |
| @@ -1304,27 +1313,30 @@ | |
| 1313 | int lastPctDone = -1; /* Last displayed pctDone */ |
| 1314 | double rArrivalTime; /* Time at which a message arrived */ |
| 1315 | const char *zSCode = db_get("server-code", "x"); |
| 1316 | const char *zPCode = db_get("project-code", 0); |
| 1317 | int nErr = 0; /* Number of errors */ |
| 1318 | int nRoundtrip= 0; /* Number of HTTP requests */ |
| 1319 | int nArtifactSent = 0; /* Total artifacts sent */ |
| 1320 | int nArtifactRcvd = 0; /* Total artifacts received */ |
| 1321 | const char *zOpType = 0;/* Push, Pull, Sync, Clone */ |
| 1322 | |
| 1323 | if( db_get_boolean("dont-push", 0) ) syncFlags &= ~SYNC_PUSH; |
| 1324 | if( (syncFlags & (SYNC_PUSH|SYNC_PULL|SYNC_CLONE))==0 |
| 1325 | && configRcvMask==0 && configSendMask==0 ) return 0; |
| 1326 | |
| 1327 | transport_stats(0, 0, 1); |
| 1328 | socket_global_init(); |
| 1329 | memset(&xfer, 0, sizeof(xfer)); |
| 1330 | xfer.pIn = &recv; |
| 1331 | xfer.pOut = &send; |
| 1332 | xfer.mxSend = db_get_int("max-upload", 250000); |
| 1333 | if( syncFlags & SYNC_PRIVATE ){ |
| 1334 | g.perm.Private = 1; |
| 1335 | xfer.syncPrivate = 1; |
| 1336 | } |
| 1337 | |
| 1338 | db_begin_transaction(); |
| 1339 | db_record_repository_filename(0); |
| 1340 | db_multi_exec( |
| 1341 | "CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);" |
| 1342 | ); |
| @@ -1335,33 +1347,39 @@ | |
| 1347 | blob_zero(&xfer.line); |
| 1348 | origConfigRcvMask = 0; |
| 1349 | |
| 1350 | |
| 1351 | /* Send the send-private pragma if we are trying to sync private data */ |
| 1352 | if( syncFlags & SYNC_PRIVATE ){ |
| 1353 | blob_append(&send, "pragma send-private\n", -1); |
| 1354 | } |
| 1355 | |
| 1356 | /* |
| 1357 | ** Always begin with a clone, pull, or push message |
| 1358 | */ |
| 1359 | if( syncFlags & SYNC_CLONE ){ |
| 1360 | blob_appendf(&send, "clone 3 %d\n", cloneSeqno); |
| 1361 | syncFlags &= ~(SYNC_PUSH|SYNC_PULL); |
| 1362 | nCardSent++; |
| 1363 | /* TBD: Request all transferable configuration values */ |
| 1364 | content_enable_dephantomize(0); |
| 1365 | zOpType = "Clone"; |
| 1366 | }else if( syncFlags & SYNC_PULL ){ |
| 1367 | blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); |
| 1368 | nCardSent++; |
| 1369 | zOpType = "Pull"; |
| 1370 | } |
| 1371 | if( syncFlags & SYNC_PUSH ){ |
| 1372 | blob_appendf(&send, "push %s %s\n", zSCode, zPCode); |
| 1373 | nCardSent++; |
| 1374 | if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push"; |
| 1375 | } |
| 1376 | manifest_crosslink_begin(); |
| 1377 | transport_global_startup(); |
| 1378 | if( syncFlags & SYNC_VERBOSE ){ |
| 1379 | fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas"); |
| 1380 | } |
| 1381 | |
| 1382 | while( go ){ |
| 1383 | int newPhantom = 0; |
| 1384 | char *zRandomness; |
| 1385 | |
| @@ -1374,25 +1392,28 @@ | |
| 1392 | } |
| 1393 | |
| 1394 | /* Generate gimme cards for phantoms and leaf cards |
| 1395 | ** for all leaves. |
| 1396 | */ |
| 1397 | if( (syncFlags & SYNC_PULL)!=0 |
| 1398 | || ((syncFlags & SYNC_CLONE)!=0 && cloneSeqno==1) |
| 1399 | ){ |
| 1400 | request_phantoms(&xfer, mxPhantomReq); |
| 1401 | } |
| 1402 | if( syncFlags & SYNC_PUSH ){ |
| 1403 | send_unsent(&xfer); |
| 1404 | nCardSent += send_unclustered(&xfer); |
| 1405 | if( syncFlags & SYNC_PRIVATE ) send_private(&xfer); |
| 1406 | } |
| 1407 | |
| 1408 | /* Send configuration parameter requests. On a clone, delay sending |
| 1409 | ** this until the second cycle since the login card might fail on |
| 1410 | ** the first cycle. |
| 1411 | */ |
| 1412 | if( configRcvMask && ((syncFlags & SYNC_CLONE)==0 || nCycle>0) ){ |
| 1413 | const char *zName; |
| 1414 | if( zOpType==0 ) zOpType = "Pull"; |
| 1415 | zName = configure_first_name(configRcvMask); |
| 1416 | while( zName ){ |
| 1417 | blob_appendf(&send, "reqconfig %s\n", zName); |
| 1418 | zName = configure_next_name(configRcvMask); |
| 1419 | nCardSent++; |
| @@ -1407,10 +1428,11 @@ | |
| 1428 | configRcvMask = 0; |
| 1429 | } |
| 1430 | |
| 1431 | /* Send configuration parameters being pushed */ |
| 1432 | if( configSendMask ){ |
| 1433 | if( zOpType==0 ) zOpType = "Push"; |
| 1434 | if( configSendMask & CONFIGSET_OLDFORMAT ){ |
| 1435 | const char *zName; |
| 1436 | zName = configure_first_name(configSendMask); |
| 1437 | while( zName ){ |
| 1438 | send_legacy_config_card(&xfer, zName); |
| @@ -1430,42 +1452,50 @@ | |
| 1452 | zRandomness = db_text(0, "SELECT hex(randomblob(20))"); |
| 1453 | blob_appendf(&send, "# %s\n", zRandomness); |
| 1454 | free(zRandomness); |
| 1455 | |
| 1456 | /* Exchange messages with the server */ |
| 1457 | if( syncFlags & SYNC_VERBOSE ){ |
| 1458 | fossil_print(zValueFormat, "Sent:", |
| 1459 | blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent, |
| 1460 | xfer.nFileSent, xfer.nDeltaSent); |
| 1461 | }else{ |
| 1462 | nRoundtrip++; |
| 1463 | nArtifactSent += xfer.nFileSent + xfer.nDeltaSent; |
| 1464 | fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd); |
| 1465 | } |
| 1466 | nCardSent = 0; |
| 1467 | nCardRcvd = 0; |
| 1468 | xfer.nFileSent = 0; |
| 1469 | xfer.nDeltaSent = 0; |
| 1470 | xfer.nGimmeSent = 0; |
| 1471 | xfer.nIGotSent = 0; |
| 1472 | if( syncFlags & SYNC_VERBOSE ){ |
| 1473 | fossil_print("waiting for server..."); |
| 1474 | } |
| 1475 | fflush(stdout); |
| 1476 | if( http_exchange(&send, &recv, (syncFlags & SYNC_CLONE)==0 || nCycle>0) ){ |
| 1477 | nErr++; |
| 1478 | break; |
| 1479 | } |
| 1480 | lastPctDone = -1; |
| 1481 | blob_reset(&send); |
| 1482 | rArrivalTime = db_double(0.0, "SELECT julianday('now')"); |
| 1483 | |
| 1484 | /* Send the send-private pragma if we are trying to sync private data */ |
| 1485 | if( syncFlags & SYNC_PRIVATE ){ |
| 1486 | blob_append(&send, "pragma send-private\n", -1); |
| 1487 | } |
| 1488 | |
| 1489 | /* Begin constructing the next message (which might never be |
| 1490 | ** sent) by beginning with the pull or push cards |
| 1491 | */ |
| 1492 | if( syncFlags & SYNC_PULL ){ |
| 1493 | blob_appendf(&send, "pull %s %s\n", zSCode, zPCode); |
| 1494 | nCardSent++; |
| 1495 | } |
| 1496 | if( syncFlags & SYNC_PUSH ){ |
| 1497 | blob_appendf(&send, "push %s %s\n", zSCode, zPCode); |
| 1498 | nCardSent++; |
| 1499 | } |
| 1500 | go = 0; |
| 1501 | |
| @@ -1493,11 +1523,11 @@ | |
| 1523 | nCardRcvd++; |
| 1524 | continue; |
| 1525 | } |
| 1526 | xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken)); |
| 1527 | nCardRcvd++; |
| 1528 | if( (syncFlags & SYNC_VERBOSE)!=0 && recv.nUsed>0 ){ |
| 1529 | pctDone = (recv.iCursor*100)/recv.nUsed; |
| 1530 | if( pctDone!=lastPctDone ){ |
| 1531 | fossil_print("\rprocessed: %d%% ", pctDone); |
| 1532 | lastPctDone = pctDone; |
| 1533 | fflush(stdout); |
| @@ -1508,20 +1538,22 @@ | |
| 1538 | ** file UUID DELTASRC SIZE \n CONTENT |
| 1539 | ** |
| 1540 | ** Receive a file transmitted from the server. |
| 1541 | */ |
| 1542 | if( blob_eq(&xfer.aToken[0],"file") ){ |
| 1543 | xfer_accept_file(&xfer, (syncFlags & SYNC_CLONE)!=0); |
| 1544 | nArtifactRcvd++; |
| 1545 | }else |
| 1546 | |
| 1547 | /* cfile UUID USIZE CSIZE \n CONTENT |
| 1548 | ** cfile UUID DELTASRC USIZE CSIZE \n CONTENT |
| 1549 | ** |
| 1550 | ** Receive a compressed file transmitted from the server. |
| 1551 | */ |
| 1552 | if( blob_eq(&xfer.aToken[0],"cfile") ){ |
| 1553 | xfer_accept_compressed_file(&xfer); |
| 1554 | nArtifactRcvd++; |
| 1555 | }else |
| 1556 | |
| 1557 | /* gimme UUID |
| 1558 | ** |
| 1559 | ** Server is requesting a file. If the file is a manifest, assume |
| @@ -1530,11 +1562,11 @@ | |
| 1562 | */ |
| 1563 | if( blob_eq(&xfer.aToken[0], "gimme") |
| 1564 | && xfer.nToken==2 |
| 1565 | && blob_is_uuid(&xfer.aToken[1]) |
| 1566 | ){ |
| 1567 | if( syncFlags & SYNC_PUSH ){ |
| 1568 | int rid = rid_from_uuid(&xfer.aToken[1], 0, 0); |
| 1569 | if( rid ) send_file(&xfer, rid, &xfer.aToken[1], 0); |
| 1570 | } |
| 1571 | }else |
| 1572 | |
| @@ -1559,11 +1591,11 @@ | |
| 1591 | rid = rid_from_uuid(&xfer.aToken[1], 0, 0); |
| 1592 | if( rid>0 ){ |
| 1593 | if( !isPriv ) content_make_public(rid); |
| 1594 | }else if( isPriv && !g.perm.Private ){ |
| 1595 | /* ignore private files */ |
| 1596 | }else if( (syncFlags & (SYNC_PULL|SYNC_CLONE))!=0 ){ |
| 1597 | rid = content_new(blob_str(&xfer.aToken[1]), isPriv); |
| 1598 | if( rid ) newPhantom = 1; |
| 1599 | } |
| 1600 | remote_has(rid); |
| 1601 | }else |
| @@ -1574,11 +1606,11 @@ | |
| 1606 | ** Should only happen in response to a clone. This message tells |
| 1607 | ** the client what product to use for the new database. |
| 1608 | */ |
| 1609 | if( blob_eq(&xfer.aToken[0],"push") |
| 1610 | && xfer.nToken==3 |
| 1611 | && (syncFlags & SYNC_CLONE)!=0 |
| 1612 | && blob_is_uuid(&xfer.aToken[1]) |
| 1613 | && blob_is_uuid(&xfer.aToken[2]) |
| 1614 | ){ |
| 1615 | if( blob_eq_str(&xfer.aToken[1], zSCode, -1) ){ |
| 1616 | fossil_fatal("server loop"); |
| @@ -1604,11 +1636,12 @@ | |
| 1636 | Blob content; |
| 1637 | blob_zero(&content); |
| 1638 | blob_extract(xfer.pIn, size, &content); |
| 1639 | g.perm.Admin = g.perm.RdAddr = 1; |
| 1640 | configure_receive(zName, &content, origConfigRcvMask); |
| 1641 | nCardRcvd++; |
| 1642 | nArtifactRcvd++; |
| 1643 | blob_reset(&content); |
| 1644 | blob_seek(xfer.pIn, 1, BLOB_SEEK_CUR); |
| 1645 | }else |
| 1646 | |
| 1647 | |
| @@ -1655,12 +1688,12 @@ | |
| 1688 | ** to the next cycle. |
| 1689 | */ |
| 1690 | if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){ |
| 1691 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1692 | defossilize(zMsg); |
| 1693 | if( (syncFlags & SYNC_PUSH) && zMsg && strglob("pull only *", zMsg) ){ |
| 1694 | syncFlags &= ~SYNC_PUSH; |
| 1695 | zMsg = 0; |
| 1696 | } |
| 1697 | fossil_print("\rServer says: %s\n", zMsg); |
| 1698 | }else |
| 1699 | |
| @@ -1683,11 +1716,11 @@ | |
| 1716 | ** is returned in the reply before the error card, so second and |
| 1717 | ** subsequent messages should be OK. Nevertheless, we need to ignore |
| 1718 | ** the error card on the first message of a clone. |
| 1719 | */ |
| 1720 | if( blob_eq(&xfer.aToken[0],"error") && xfer.nToken==2 ){ |
| 1721 | if( (syncFlags & SYNC_CLONE)==0 || nCycle>0 ){ |
| 1722 | char *zMsg = blob_terminate(&xfer.aToken[1]); |
| 1723 | defossilize(zMsg); |
| 1724 | if( fossil_strcmp(zMsg, "login failed")==0 ){ |
| 1725 | if( nCycle<2 ){ |
| 1726 | if( !g.dontKeepUrl ) db_unset("last-sync-pw", 0); |
| @@ -1727,14 +1760,16 @@ | |
| 1760 | && (configRcvMask & CONFIGSET_OLDFORMAT)!=0 |
| 1761 | ){ |
| 1762 | configure_finalize_receive(); |
| 1763 | } |
| 1764 | origConfigRcvMask = 0; |
| 1765 | if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){ |
| 1766 | fossil_print(zValueFormat, "Received:", |
| 1767 | blob_size(&recv), nCardRcvd, |
| 1768 | xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile); |
| 1769 | }else{ |
| 1770 | fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd); |
| 1771 | } |
| 1772 | blob_reset(&recv); |
| 1773 | nCycle++; |
| 1774 | |
| 1775 | /* If we received one or more files on the previous exchange but |
| @@ -1743,11 +1778,11 @@ | |
| 1778 | nFileRecv = xfer.nFileRcvd + xfer.nDeltaRcvd + xfer.nDanglingFile; |
| 1779 | if( (nFileRecv>0 || newPhantom) && db_exists("SELECT 1 FROM phantom") ){ |
| 1780 | go = 1; |
| 1781 | mxPhantomReq = nFileRecv*2; |
| 1782 | if( mxPhantomReq<200 ) mxPhantomReq = 200; |
| 1783 | }else if( (syncFlags & SYNC_CLONE)!=0 && nFileRecv>0 ){ |
| 1784 | go = 1; |
| 1785 | } |
| 1786 | nCardRcvd = 0; |
| 1787 | xfer.nFileRcvd = 0; |
| 1788 | xfer.nDeltaRcvd = 0; |
| @@ -1759,25 +1794,27 @@ | |
| 1794 | if( xfer.nFileSent+xfer.nDeltaSent>0 ){ |
| 1795 | go = 1; |
| 1796 | } |
| 1797 | |
| 1798 | /* If this is a clone, the go at least two rounds */ |
| 1799 | if( (syncFlags & SYNC_CLONE)!=0 && nCycle==1 ) go = 1; |
| 1800 | |
| 1801 | /* Stop the cycle if the server sends a "clone_seqno 0" card and |
| 1802 | ** we have gone at least two rounds. Always go at least two rounds |
| 1803 | ** on a clone in order to be sure to retrieve the configuration |
| 1804 | ** information which is only sent on the second round. |
| 1805 | */ |
| 1806 | if( cloneSeqno<=0 && nCycle>1 ) go = 0; |
| 1807 | }; |
| 1808 | transport_stats(&nSent, &nRcvd, 1); |
| 1809 | if( (syncFlags & SYNC_VERBOSE)==0 ) fossil_print("\n"); |
| 1810 | fossil_print( |
| 1811 | "%s finished with %lld bytes sent, %lld bytes received\n", |
| 1812 | zOpType, nSent, nRcvd); |
| 1813 | transport_close(); |
| 1814 | transport_global_shutdown(); |
| 1815 | db_multi_exec("DROP TABLE onremote"); |
| 1816 | manifest_crosslink_end(); |
| 1817 | content_enable_dephantomize(1); |
| 1818 | db_end_transaction(0); |
| 1819 | return nErr; |
| 1820 | } |
| 1821 |