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.

drh 2012-11-20 14:28 trunk merge
Commit 15708574fe27eb0500ade91c21c5c29d86034c2f
+4 -2
--- src/attach.c
+++ src/attach.c
@@ -71,10 +71,11 @@
7171
const char *zFilename = db_column_text(&q, 3);
7272
const char *zComment = db_column_text(&q, 4);
7373
const char *zUser = db_column_text(&q, 5);
7474
const char *zUuid = db_column_text(&q, 6);
7575
int attachid = db_column_int(&q, 7);
76
+ const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous";
7677
int i;
7778
char *zUrlTail;
7879
for(i=0; zFilename[i]; i++){
7980
if( zFilename[i]=='/' && zFilename[i+1]!=0 ){
8081
zFilename = &zFilename[i+1];
@@ -115,11 +116,11 @@
115116
@ Deleted
116117
}else {
117118
@ Added
118119
}
119120
}
120
- @ by %h(zUser) on
121
+ @ by %h(zDispUser) on
121122
hyperlink_to_date(zDate, ".");
122123
free(zUrlTail);
123124
}
124125
db_finalize(&q);
125126
@ </ol>
@@ -557,17 +558,18 @@
557558
const char *zDate = db_column_text(&q, 0);
558559
const char *zFile = db_column_text(&q, 1);
559560
const char *zUser = db_column_text(&q, 2);
560561
const char *zUuid = db_column_text(&q, 3);
561562
const char *zSrc = db_column_text(&q, 4);
563
+ const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous";
562564
if( cnt==0 ){
563565
@ %s(zHeader)
564566
}
565567
cnt++;
566568
@ <li>
567569
@ %z(href("%R/artifact/%s",zSrc))%h(zFile)</a>
568
- @ added by %h(zUser) on
570
+ @ added by %h(zDispUser) on
569571
hyperlink_to_date(zDate, ".");
570572
@ [%z(href("%R/ainfo/%s",zUuid))details</a>]
571573
@ </li>
572574
}
573575
if( cnt ){
574576
--- 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 @@
7171
const char *zFilename = db_column_text(&q, 3);
7272
const char *zComment = db_column_text(&q, 4);
7373
const char *zUser = db_column_text(&q, 5);
7474
const char *zUuid = db_column_text(&q, 6);
7575
int attachid = db_column_int(&q, 7);
76
+ const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous";
7677
int i;
7778
char *zUrlTail;
7879
for(i=0; zFilename[i]; i++){
7980
if( zFilename[i]=='/' && zFilename[i+1]!=0 ){
8081
zFilename = &zFilename[i+1];
@@ -115,11 +116,11 @@
115116
@ Deleted
116117
}else {
117118
@ Added
118119
}
119120
}
120
- @ by %h(zUser) on
121
+ @ by %h(zDispUser) on
121122
hyperlink_to_date(zDate, ".");
122123
free(zUrlTail);
123124
}
124125
db_finalize(&q);
125126
@ </ol>
@@ -557,17 +558,18 @@
557558
const char *zDate = db_column_text(&q, 0);
558559
const char *zFile = db_column_text(&q, 1);
559560
const char *zUser = db_column_text(&q, 2);
560561
const char *zUuid = db_column_text(&q, 3);
561562
const char *zSrc = db_column_text(&q, 4);
563
+ const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous";
562564
if( cnt==0 ){
563565
@ %s(zHeader)
564566
}
565567
cnt++;
566568
@ <li>
567569
@ %z(href("%R/artifact/%s",zSrc))%h(zFile)</a>
568
- @ added by %h(zUser) on
570
+ @ added by %h(zDispUser) on
569571
hyperlink_to_date(zDate, ".");
570572
@ [%z(href("%R/ainfo/%s",zUuid))details</a>]
571573
@ </li>
572574
}
573575
if( cnt ){
574576
--- 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 @@
176176
177177
/* Commit */
178178
db_end_transaction(0);
179179
180180
/* Do an autosync push, if requested */
181
- if( !isPrivate ) autosync(AUTOSYNC_PUSH);
181
+ if( !isPrivate ) autosync(SYNC_PUSH);
182182
}
183183
184184
/*
185185
** Prepare a query that will list branches.
186186
**
187187
--- 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 @@
176176
177177
/* Commit */
178178
db_end_transaction(0);
179179
180180
/* Do an autosync push, if requested */
181
- if( !isPrivate ) autosync(AUTOSYNC_PUSH);
181
+ if( !isPrivate ) autosync(SYNC_PUSH);
182182
}
183183
184184
/*
185185
** Prepare a query that will list branches.
186186
**
187187
--- 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 @@
11081108
11091109
/*
11101110
** Autosync if autosync is enabled and this is not a private check-in.
11111111
*/
11121112
if( !g.markPrivate ){
1113
- if( autosync(AUTOSYNC_PULL) ){
1113
+ if( autosync(SYNC_PULL) ){
11141114
blob_zero(&ans);
11151115
prompt_user("continue in spite of sync failure (y/N)? ", &ans);
11161116
cReply = blob_str(&ans)[0];
11171117
if( cReply!='y' && cReply!='Y' ){
11181118
fossil_exit(1);
@@ -1459,11 +1459,11 @@
14591459
exit(1);
14601460
}
14611461
db_end_transaction(0);
14621462
14631463
if( !g.markPrivate ){
1464
- autosync(AUTOSYNC_PUSH);
1464
+ autosync(SYNC_PUSH);
14651465
}
14661466
if( count_nonbranch_children(vid)>1 ){
14671467
fossil_print("**** warning: a fork has occurred *****\n");
14681468
}
14691469
}
14701470
--- 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 @@
11081108
11091109
/*
11101110
** Autosync if autosync is enabled and this is not a private check-in.
11111111
*/
11121112
if( !g.markPrivate ){
1113
- if( autosync(AUTOSYNC_PULL) ){
1113
+ if( autosync(SYNC_PULL) ){
11141114
blob_zero(&ans);
11151115
prompt_user("continue in spite of sync failure (y/N)? ", &ans);
11161116
cReply = blob_str(&ans)[0];
11171117
if( cReply!='y' && cReply!='Y' ){
11181118
fossil_exit(1);
@@ -1459,11 +1459,11 @@
14591459
exit(1);
14601460
}
14611461
db_end_transaction(0);
14621462
14631463
if( !g.markPrivate ){
1464
- autosync(AUTOSYNC_PUSH);
1464
+ autosync(SYNC_PUSH);
14651465
}
14661466
if( count_nonbranch_children(vid)>1 ){
14671467
fossil_print("**** warning: a fork has occurred *****\n");
14681468
}
14691469
}
14701470
--- 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 @@
9999
** See also: init
100100
*/
101101
void clone_cmd(void){
102102
char *zPassword;
103103
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 */
105105
int nErr = 0;
106
- int bPrivate; /* Also clone private branches */
106
+ int bPrivate = 0; /* Also clone private branches */
107107
108
- bPrivate = find_option("private",0,0)!=0;
108
+ if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE;
109109
url_proxy_options();
110110
if( g.argc < 4 ){
111111
usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY");
112112
}
113113
db_open_config(0);
@@ -162,11 +162,11 @@
162162
" VALUES('server-code', lower(hex(randomblob(20))), now());"
163163
);
164164
url_enable_proxy(0);
165165
url_get_password_if_needed();
166166
g.xlinkClusterOnly = 1;
167
- nErr = client_sync(0,0,1,bPrivate,CONFIGSET_ALL,0);
167
+ nErr = client_sync(SYNC_CLONE | bPrivate,CONFIGSET_ALL,0);
168168
g.xlinkClusterOnly = 0;
169169
verify_cancel();
170170
db_end_transaction(0);
171171
db_close(1);
172172
if( nErr ){
173173
--- 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 @@
9999
** See also: init
100100
*/
101101
void clone_cmd(void){
102102
char *zPassword;
103103
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 */
105105
int nErr = 0;
106
- int bPrivate; /* Also clone private branches */
106
+ int bPrivate = 0; /* Also clone private branches */
107107
108
- bPrivate = find_option("private",0,0)!=0;
108
+ if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE;
109109
url_proxy_options();
110110
if( g.argc < 4 ){
111111
usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY");
112112
}
113113
db_open_config(0);
@@ -162,11 +162,11 @@
162162
" VALUES('server-code', lower(hex(randomblob(20))), now());"
163163
);
164164
url_enable_proxy(0);
165165
url_get_password_if_needed();
166166
g.xlinkClusterOnly = 1;
167
- nErr = client_sync(0,0,1,bPrivate,CONFIGSET_ALL,0);
167
+ nErr = client_sync(SYNC_CLONE | bPrivate,CONFIGSET_ALL,0);
168168
g.xlinkClusterOnly = 0;
169169
verify_cancel();
170170
db_end_transaction(0);
171171
db_close(1);
172172
if( nErr ){
173173
--- 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 @@
907907
user_select();
908908
url_enable_proxy("via proxy: ");
909909
if( legacyFlag ) mask |= CONFIGSET_OLDFORMAT;
910910
if( overwriteFlag ) mask |= CONFIGSET_OVERWRITE;
911911
if( strncmp(zMethod, "push", n)==0 ){
912
- client_sync(0,0,0,0,0,mask);
912
+ client_sync(0,0,(unsigned)mask);
913913
}else if( strncmp(zMethod, "pull", n)==0 ){
914
- client_sync(0,0,0,0,mask,0);
914
+ client_sync(0,(unsigned)mask,0);
915915
}else{
916
- client_sync(0,0,0,0,mask,mask);
916
+ client_sync(0,(unsigned)mask,(unsigned)mask);
917917
}
918918
}else
919919
if( strncmp(zMethod, "reset", n)==0 ){
920920
int mask, i;
921921
char *zBackup;
922922
--- 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 @@
907907
user_select();
908908
url_enable_proxy("via proxy: ");
909909
if( legacyFlag ) mask |= CONFIGSET_OLDFORMAT;
910910
if( overwriteFlag ) mask |= CONFIGSET_OVERWRITE;
911911
if( strncmp(zMethod, "push", n)==0 ){
912
- client_sync(0,0,0,0,0,mask);
912
+ client_sync(0,0,(unsigned)mask);
913913
}else if( strncmp(zMethod, "pull", n)==0 ){
914
- client_sync(0,0,0,0,mask,0);
914
+ client_sync(0,(unsigned)mask,0);
915915
}else{
916
- client_sync(0,0,0,0,mask,mask);
916
+ client_sync(0,(unsigned)mask,(unsigned)mask);
917917
}
918918
}else
919919
if( strncmp(zMethod, "reset", n)==0 ){
920920
int mask, i;
921921
char *zBackup;
922922
--- 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 @@
907907
user_select();
908908
url_enable_proxy("via proxy: ");
909909
if( legacyFlag ) mask |= CONFIGSET_OLDFORMAT;
910910
if( overwriteFlag ) mask |= CONFIGSET_OVERWRITE;
911911
if( strncmp(zMethod, "push", n)==0 ){
912
- client_sync(0,0,0,0,0,mask);
912
+ client_sync(0,0,(unsigned)mask);
913913
}else if( strncmp(zMethod, "pull", n)==0 ){
914
- client_sync(0,0,0,0,mask,0);
914
+ client_sync(0,(unsigned)mask,0);
915915
}else{
916
- client_sync(0,0,0,0,mask,mask);
916
+ client_sync(0,(unsigned)mask,(unsigned)mask);
917917
}
918918
}else
919919
if( strncmp(zMethod, "reset", n)==0 ){
920920
int mask, i;
921921
char *zBackup;
922922
--- 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
--- src/json_branch.c
+++ src/json_branch.c
@@ -305,11 +305,11 @@
305305
/* Commit */
306306
db_end_transaction(0);
307307
308308
#if 0 /* Do an autosync push, if requested */
309309
/* arugable for JSON mode? */
310
- if( !g.isHTTP && !isPrivate ) autosync(AUTOSYNC_PUSH);
310
+ if( !g.isHTTP && !isPrivate ) autosync(SYNC_PUSH);
311311
#endif
312312
return 0;
313313
}
314314
315315
316316
--- 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
--- src/json_branch.c
+++ src/json_branch.c
@@ -305,11 +305,11 @@
305305
/* Commit */
306306
db_end_transaction(0);
307307
308308
#if 0 /* Do an autosync push, if requested */
309309
/* arugable for JSON mode? */
310
- if( !g.isHTTP && !isPrivate ) autosync(AUTOSYNC_PUSH);
310
+ if( !g.isHTTP && !isPrivate ) autosync(SYNC_PUSH);
311311
#endif
312312
return 0;
313313
}
314314
315315
316316
--- 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 @@
1919
*/
2020
#include "config.h"
2121
#include "sync.h"
2222
#include <assert.h>
2323
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
-
3324
/*
3425
** If the repository is configured for autosyncing, then do an
3526
** autosync. This will be a pull if the argument is true or a push
3627
** if the argument is false.
3728
**
@@ -44,16 +35,16 @@
4435
int rc;
4536
int configSync = 0; /* configuration changes transferred */
4637
if( g.fNoSync ){
4738
return 0;
4839
}
49
- if( flags==AUTOSYNC_PUSH && db_get_boolean("dont-push",0) ){
40
+ if( flags==SYNC_PUSH && db_get_boolean("dont-push",0) ){
5041
return 0;
5142
}
5243
zAutosync = db_get("autosync", 0);
5344
if( zAutosync ){
54
- if( (flags & AUTOSYNC_PUSH)!=0 && memcmp(zAutosync,"pull",4)==0 ){
45
+ if( (flags & SYNC_PUSH)!=0 && memcmp(zAutosync,"pull",4)==0 ){
5546
return 0; /* Do not auto-push when autosync=pullonly */
5647
}
5748
if( is_false(zAutosync) ){
5849
return 0; /* Autosync is completely off */
5950
}
@@ -79,13 +70,14 @@
7970
** autosync, or something?
8071
*/
8172
configSync = CONFIGSET_SHUN;
8273
}
8374
#endif
75
+ if( find_option("verbose","v",0)!=0 ) flags |= SYNC_VERBOSE;
8476
fossil_print("Autosync: %s\n", g.urlCanonical);
8577
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);
8779
if( rc ) fossil_warning("Autosync failed");
8880
return rc;
8981
}
9082
9183
/*
@@ -92,17 +84,22 @@
9284
** This routine processes the command-line argument for push, pull,
9385
** and sync. If a command-line argument is given, that is the URL
9486
** of a server to sync against. If no argument is given, use the
9587
** most recently synced URL. Remember the current URL for next time.
9688
*/
97
-static void process_sync_args(int *pConfigSync, int *pPrivate){
89
+static void process_sync_args(unsigned *pConfigFlags, unsigned *pSyncFlags){
9890
const char *zUrl = 0;
9991
const char *zPw = 0;
100
- int configSync = 0;
92
+ unsigned configSync = 0;
10193
int urlOptional = find_option("autourl",0,0)!=0;
10294
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
+ }
104101
url_proxy_options();
105102
db_find_and_open_repository(0, 0);
106103
db_open_config(0);
107104
if( g.argc==2 ){
108105
zUrl = db_get("last-sync-url", 0);
@@ -127,14 +124,20 @@
127124
db_set("last-sync-url", g.urlCanonical, 0);
128125
if( g.urlPasswd ) db_set("last-sync-pw", obscure(g.urlPasswd), 0);
129126
}
130127
user_select();
131128
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
+ }
133136
}
134137
url_enable_proxy("via proxy: ");
135
- *pConfigSync = configSync;
138
+ *pConfigFlags |= configSync;
136139
}
137140
138141
/*
139142
** COMMAND: pull
140143
**
@@ -156,14 +159,14 @@
156159
** remote repository.
157160
**
158161
** See also: clone, push, sync, remote-url
159162
*/
160163
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);
165168
}
166169
167170
/*
168171
** COMMAND: push
169172
**
@@ -185,17 +188,17 @@
185188
** remote repository.
186189
**
187190
** See also: clone, pull, sync, remote-url
188191
*/
189192
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);
193196
if( db_get_boolean("dont-push",0) ){
194197
fossil_fatal("pushing is prohibited: the 'dont-push' option is set");
195198
}
196
- client_sync(1,0,0,bPrivate,0,0);
199
+ client_sync(syncFlags, 0, 0);
197200
}
198201
199202
200203
/*
201204
** COMMAND: sync
@@ -223,17 +226,16 @@
223226
** remote repository.
224227
**
225228
** See also: clone, push, pull, remote-url
226229
*/
227230
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 ){
235237
fossil_warning("pull only: the 'dont-push' option is set");
236238
}
237239
}
238240
239241
/*
240242
--- 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 @@
1919
*/
2020
#include "config.h"
2121
#include "sync.h"
2222
#include <assert.h>
2323
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
-
3324
/*
3425
** If the repository is configured for autosyncing, then do an
3526
** autosync. This will be a pull if the argument is true or a push
3627
** if the argument is false.
3728
**
@@ -44,16 +35,16 @@
4435
int rc;
4536
int configSync = 0; /* configuration changes transferred */
4637
if( g.fNoSync ){
4738
return 0;
4839
}
49
- if( flags==AUTOSYNC_PUSH && db_get_boolean("dont-push",0) ){
40
+ if( flags==SYNC_PUSH && db_get_boolean("dont-push",0) ){
5041
return 0;
5142
}
5243
zAutosync = db_get("autosync", 0);
5344
if( zAutosync ){
54
- if( (flags & AUTOSYNC_PUSH)!=0 && memcmp(zAutosync,"pull",4)==0 ){
45
+ if( (flags & SYNC_PUSH)!=0 && memcmp(zAutosync,"pull",4)==0 ){
5546
return 0; /* Do not auto-push when autosync=pullonly */
5647
}
5748
if( is_false(zAutosync) ){
5849
return 0; /* Autosync is completely off */
5950
}
@@ -79,13 +70,14 @@
7970
** autosync, or something?
8071
*/
8172
configSync = CONFIGSET_SHUN;
8273
}
8374
#endif
75
+ if( find_option("verbose","v",0)!=0 ) flags |= SYNC_VERBOSE;
8476
fossil_print("Autosync: %s\n", g.urlCanonical);
8577
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);
8779
if( rc ) fossil_warning("Autosync failed");
8880
return rc;
8981
}
9082
9183
/*
@@ -92,17 +84,22 @@
9284
** This routine processes the command-line argument for push, pull,
9385
** and sync. If a command-line argument is given, that is the URL
9486
** of a server to sync against. If no argument is given, use the
9587
** most recently synced URL. Remember the current URL for next time.
9688
*/
97
-static void process_sync_args(int *pConfigSync, int *pPrivate){
89
+static void process_sync_args(unsigned *pConfigFlags, unsigned *pSyncFlags){
9890
const char *zUrl = 0;
9991
const char *zPw = 0;
100
- int configSync = 0;
92
+ unsigned configSync = 0;
10193
int urlOptional = find_option("autourl",0,0)!=0;
10294
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
+ }
104101
url_proxy_options();
105102
db_find_and_open_repository(0, 0);
106103
db_open_config(0);
107104
if( g.argc==2 ){
108105
zUrl = db_get("last-sync-url", 0);
@@ -127,14 +124,20 @@
127124
db_set("last-sync-url", g.urlCanonical, 0);
128125
if( g.urlPasswd ) db_set("last-sync-pw", obscure(g.urlPasswd), 0);
129126
}
130127
user_select();
131128
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
+ }
133136
}
134137
url_enable_proxy("via proxy: ");
135
- *pConfigSync = configSync;
138
+ *pConfigFlags |= configSync;
136139
}
137140
138141
/*
139142
** COMMAND: pull
140143
**
@@ -156,14 +159,14 @@
156159
** remote repository.
157160
**
158161
** See also: clone, push, sync, remote-url
159162
*/
160163
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);
165168
}
166169
167170
/*
168171
** COMMAND: push
169172
**
@@ -185,17 +188,17 @@
185188
** remote repository.
186189
**
187190
** See also: clone, pull, sync, remote-url
188191
*/
189192
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);
193196
if( db_get_boolean("dont-push",0) ){
194197
fossil_fatal("pushing is prohibited: the 'dont-push' option is set");
195198
}
196
- client_sync(1,0,0,bPrivate,0,0);
199
+ client_sync(syncFlags, 0, 0);
197200
}
198201
199202
200203
/*
201204
** COMMAND: sync
@@ -223,17 +226,16 @@
223226
** remote repository.
224227
**
225228
** See also: clone, push, pull, remote-url
226229
*/
227230
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 ){
235237
fossil_warning("pull only: the 'dont-push' option is set");
236238
}
237239
}
238240
239241
/*
240242
--- 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 @@
1919
*/
2020
#include "config.h"
2121
#include "sync.h"
2222
#include <assert.h>
2323
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
-
3324
/*
3425
** If the repository is configured for autosyncing, then do an
3526
** autosync. This will be a pull if the argument is true or a push
3627
** if the argument is false.
3728
**
@@ -44,16 +35,16 @@
4435
int rc;
4536
int configSync = 0; /* configuration changes transferred */
4637
if( g.fNoSync ){
4738
return 0;
4839
}
49
- if( flags==AUTOSYNC_PUSH && db_get_boolean("dont-push",0) ){
40
+ if( flags==SYNC_PUSH && db_get_boolean("dont-push",0) ){
5041
return 0;
5142
}
5243
zAutosync = db_get("autosync", 0);
5344
if( zAutosync ){
54
- if( (flags & AUTOSYNC_PUSH)!=0 && memcmp(zAutosync,"pull",4)==0 ){
45
+ if( (flags & SYNC_PUSH)!=0 && memcmp(zAutosync,"pull",4)==0 ){
5546
return 0; /* Do not auto-push when autosync=pullonly */
5647
}
5748
if( is_false(zAutosync) ){
5849
return 0; /* Autosync is completely off */
5950
}
@@ -79,13 +70,14 @@
7970
** autosync, or something?
8071
*/
8172
configSync = CONFIGSET_SHUN;
8273
}
8374
#endif
75
+ if( find_option("verbose","v",0)!=0 ) flags |= SYNC_VERBOSE;
8476
fossil_print("Autosync: %s\n", g.urlCanonical);
8577
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);
8779
if( rc ) fossil_warning("Autosync failed");
8880
return rc;
8981
}
9082
9183
/*
@@ -92,17 +84,22 @@
9284
** This routine processes the command-line argument for push, pull,
9385
** and sync. If a command-line argument is given, that is the URL
9486
** of a server to sync against. If no argument is given, use the
9587
** most recently synced URL. Remember the current URL for next time.
9688
*/
97
-static void process_sync_args(int *pConfigSync, int *pPrivate){
89
+static void process_sync_args(unsigned *pConfigFlags, unsigned *pSyncFlags){
9890
const char *zUrl = 0;
9991
const char *zPw = 0;
100
- int configSync = 0;
92
+ unsigned configSync = 0;
10193
int urlOptional = find_option("autourl",0,0)!=0;
10294
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
+ }
104101
url_proxy_options();
105102
db_find_and_open_repository(0, 0);
106103
db_open_config(0);
107104
if( g.argc==2 ){
108105
zUrl = db_get("last-sync-url", 0);
@@ -127,14 +124,20 @@
127124
db_set("last-sync-url", g.urlCanonical, 0);
128125
if( g.urlPasswd ) db_set("last-sync-pw", obscure(g.urlPasswd), 0);
129126
}
130127
user_select();
131128
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
+ }
133136
}
134137
url_enable_proxy("via proxy: ");
135
- *pConfigSync = configSync;
138
+ *pConfigFlags |= configSync;
136139
}
137140
138141
/*
139142
** COMMAND: pull
140143
**
@@ -156,14 +159,14 @@
156159
** remote repository.
157160
**
158161
** See also: clone, push, sync, remote-url
159162
*/
160163
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);
165168
}
166169
167170
/*
168171
** COMMAND: push
169172
**
@@ -185,17 +188,17 @@
185188
** remote repository.
186189
**
187190
** See also: clone, pull, sync, remote-url
188191
*/
189192
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);
193196
if( db_get_boolean("dont-push",0) ){
194197
fossil_fatal("pushing is prohibited: the 'dont-push' option is set");
195198
}
196
- client_sync(1,0,0,bPrivate,0,0);
199
+ client_sync(syncFlags, 0, 0);
197200
}
198201
199202
200203
/*
201204
** COMMAND: sync
@@ -223,17 +226,16 @@
223226
** remote repository.
224227
**
225228
** See also: clone, push, pull, remote-url
226229
*/
227230
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 ){
235237
fossil_warning("pull only: the 'dont-push' option is set");
236238
}
237239
}
238240
239241
/*
240242
--- 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 @@
8585
** Generate a hyperlink to a user. This will link to a timeline showing
8686
** events by that user. If the date+time is specified, then the timeline
8787
** is centered on that date+time.
8888
*/
8989
void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){
90
+ if( zU==0 || zU[0]==0 ) zU = "anonymous";
9091
if( zSuf==0 ) zSuf = "";
9192
if( g.perm.Hyperlink ){
9293
if( zD && zD[0] ){
9394
@ %z(href("%R/timeline?c=%T&u=%T",zD,zU))%h(zU)</a>%s(zSuf)
9495
}else{
@@ -237,10 +238,11 @@
237238
const char *zDate = db_column_text(pQuery, 2);
238239
const char *zType = db_column_text(pQuery, 7);
239240
const char *zUser = db_column_text(pQuery, 4);
240241
const char *zTagList = db_column_text(pQuery, 8);
241242
int tagid = db_column_int(pQuery, 9);
243
+ const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous";
242244
const char *zBr = 0; /* Branch */
243245
int commentColumn = 3; /* Column containing comment text */
244246
int modPending; /* Pending moderation */
245247
char zTime[8];
246248
@@ -372,15 +374,15 @@
372374
373375
/* Generate the "user: USERNAME" at the end of the comment, together
374376
** with a hyperlink to another timeline for that user.
375377
*/
376378
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")
380382
}else{
381
- @ (user: %h(zUser)%s(zTagList?",":"\051")
383
+ @ (user: %h(zDispUser)%s(zTagList?",":"\051")
382384
}
383385
384386
/* Generate a "detail" link for tags. */
385387
if( (zType[0]=='g' || zType[0]=='w' || zType[0]=='t') && g.perm.Hyperlink ){
386388
@ [%z(href("%R/info/%S",zUuid))details</a>]
387389
--- 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 @@
8585
** Generate a hyperlink to a user. This will link to a timeline showing
8686
** events by that user. If the date+time is specified, then the timeline
8787
** is centered on that date+time.
8888
*/
8989
void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){
90
+ if( zU==0 || zU[0]==0 ) zU = "anonymous";
9091
if( zSuf==0 ) zSuf = "";
9192
if( g.perm.Hyperlink ){
9293
if( zD && zD[0] ){
9394
@ %z(href("%R/timeline?c=%T&u=%T",zD,zU))%h(zU)</a>%s(zSuf)
9495
}else{
@@ -237,10 +238,11 @@
237238
const char *zDate = db_column_text(pQuery, 2);
238239
const char *zType = db_column_text(pQuery, 7);
239240
const char *zUser = db_column_text(pQuery, 4);
240241
const char *zTagList = db_column_text(pQuery, 8);
241242
int tagid = db_column_int(pQuery, 9);
243
+ const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous";
242244
const char *zBr = 0; /* Branch */
243245
int commentColumn = 3; /* Column containing comment text */
244246
int modPending; /* Pending moderation */
245247
char zTime[8];
246248
@@ -372,15 +374,15 @@
372374
373375
/* Generate the "user: USERNAME" at the end of the comment, together
374376
** with a hyperlink to another timeline for that user.
375377
*/
376378
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")
380382
}else{
381
- @ (user: %h(zUser)%s(zTagList?",":"\051")
383
+ @ (user: %h(zDispUser)%s(zTagList?",":"\051")
382384
}
383385
384386
/* Generate a "detail" link for tags. */
385387
if( (zType[0]=='g' || zType[0]=='w' || zType[0]=='t') && g.perm.Hyperlink ){
386388
@ [%z(href("%R/info/%S",zUuid))details</a>]
387389
--- 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 @@
8585
** Generate a hyperlink to a user. This will link to a timeline showing
8686
** events by that user. If the date+time is specified, then the timeline
8787
** is centered on that date+time.
8888
*/
8989
void hyperlink_to_user(const char *zU, const char *zD, const char *zSuf){
90
+ if( zU==0 || zU[0]==0 ) zU = "anonymous";
9091
if( zSuf==0 ) zSuf = "";
9192
if( g.perm.Hyperlink ){
9293
if( zD && zD[0] ){
9394
@ %z(href("%R/timeline?c=%T&u=%T",zD,zU))%h(zU)</a>%s(zSuf)
9495
}else{
@@ -237,10 +238,11 @@
237238
const char *zDate = db_column_text(pQuery, 2);
238239
const char *zType = db_column_text(pQuery, 7);
239240
const char *zUser = db_column_text(pQuery, 4);
240241
const char *zTagList = db_column_text(pQuery, 8);
241242
int tagid = db_column_int(pQuery, 9);
243
+ const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous";
242244
const char *zBr = 0; /* Branch */
243245
int commentColumn = 3; /* Column containing comment text */
244246
int modPending; /* Pending moderation */
245247
char zTime[8];
246248
@@ -372,15 +374,15 @@
372374
373375
/* Generate the "user: USERNAME" at the end of the comment, together
374376
** with a hyperlink to another timeline for that user.
375377
*/
376378
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")
380382
}else{
381
- @ (user: %h(zUser)%s(zTagList?",":"\051")
383
+ @ (user: %h(zDispUser)%s(zTagList?",":"\051")
382384
}
383385
384386
/* Generate a "detail" link for tags. */
385387
if( (zType[0]=='g' || zType[0]=='w' || zType[0]=='t') && g.perm.Hyperlink ){
386388
@ [%z(href("%R/info/%S",zUuid))details</a>]
387389
--- 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 @@
123123
db_must_be_within_tree();
124124
vid = db_lget_int("checkout", 0);
125125
if( vid==0 ){
126126
fossil_fatal("cannot find current version");
127127
}
128
- if( !nochangeFlag && !internalUpdate ) autosync(AUTOSYNC_PULL);
128
+ if( !nochangeFlag && !internalUpdate ){
129
+ autosync(SYNC_PULL + SYNC_VERBOSE*verboseFlag);
130
+ }
129131
130132
/* Create any empty directories now, as well as after the update,
131133
** so changes in settings are reflected now */
132134
if( !nochangeFlag ) ensure_empty_dirs_created();
133135
134136
--- 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 @@
123123
db_must_be_within_tree();
124124
vid = db_lget_int("checkout", 0);
125125
if( vid==0 ){
126126
fossil_fatal("cannot find current version");
127127
}
128
- if( !nochangeFlag && !internalUpdate ) autosync(AUTOSYNC_PULL);
128
+ if( !nochangeFlag && !internalUpdate ){
129
+ autosync(SYNC_PULL + SYNC_VERBOSE*verboseFlag);
130
+ }
129131
130132
/* Create any empty directories now, as well as after the update,
131133
** so changes in settings are reflected now */
132134
if( !nochangeFlag ) ensure_empty_dirs_created();
133135
134136
--- 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 @@
123123
db_must_be_within_tree();
124124
vid = db_lget_int("checkout", 0);
125125
if( vid==0 ){
126126
fossil_fatal("cannot find current version");
127127
}
128
- if( !nochangeFlag && !internalUpdate ) autosync(AUTOSYNC_PULL);
128
+ if( !nochangeFlag && !internalUpdate ){
129
+ autosync(SYNC_PULL + SYNC_VERBOSE*verboseFlag);
130
+ }
129131
130132
/* Create any empty directories now, as well as after the update,
131133
** so changes in settings are reflected now */
132134
if( !nochangeFlag ) ensure_empty_dirs_created();
133135
134136
--- 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 @@
12661266
/*
12671267
** Format strings for progress reporting.
12681268
*/
12691269
static const char zLabelFormat[] = "%-10s %10s %10s %10s %10s\n";
12701270
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";
12711273
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
12721284
12731285
/*
12741286
** Sync to the host identified in g.urlName and g.urlPath. This
12751287
** routine is called by the client.
12761288
**
@@ -1277,16 +1289,13 @@
12771289
** Records are pushed to the server if pushFlag is true. Records
12781290
** are pulled if pullFlag is true. A full sync occurs if both are
12791291
** true.
12801292
*/
12811293
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 */
12881297
){
12891298
int go = 1; /* Loop until zero */
12901299
int nCardSent = 0; /* Number of cards sent */
12911300
int nCardRcvd = 0; /* Number of cards received */
12921301
int nCycle = 0; /* Number of round trips to the server */
@@ -1304,27 +1313,30 @@
13041313
int lastPctDone = -1; /* Last displayed pctDone */
13051314
double rArrivalTime; /* Time at which a message arrived */
13061315
const char *zSCode = db_get("server-code", "x");
13071316
const char *zPCode = db_get("project-code", 0);
13081317
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 */
13091322
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
13121325
&& configRcvMask==0 && configSendMask==0 ) return 0;
13131326
13141327
transport_stats(0, 0, 1);
13151328
socket_global_init();
13161329
memset(&xfer, 0, sizeof(xfer));
13171330
xfer.pIn = &recv;
13181331
xfer.pOut = &send;
13191332
xfer.mxSend = db_get_int("max-upload", 250000);
1320
- if( privateFlag ){
1333
+ if( syncFlags & SYNC_PRIVATE ){
13211334
g.perm.Private = 1;
13221335
xfer.syncPrivate = 1;
13231336
}
13241337
1325
- assert( pushFlag | pullFlag | cloneFlag | configRcvMask | configSendMask );
13261338
db_begin_transaction();
13271339
db_record_repository_filename(0);
13281340
db_multi_exec(
13291341
"CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
13301342
);
@@ -1335,33 +1347,39 @@
13351347
blob_zero(&xfer.line);
13361348
origConfigRcvMask = 0;
13371349
13381350
13391351
/* 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
+ }
13411355
13421356
/*
13431357
** Always begin with a clone, pull, or push message
13441358
*/
1345
- if( cloneFlag ){
1359
+ if( syncFlags & SYNC_CLONE ){
13461360
blob_appendf(&send, "clone 3 %d\n", cloneSeqno);
1347
- pushFlag = 0;
1348
- pullFlag = 0;
1361
+ syncFlags &= ~(SYNC_PUSH|SYNC_PULL);
13491362
nCardSent++;
13501363
/* TBD: Request all transferable configuration values */
13511364
content_enable_dephantomize(0);
1352
- }else if( pullFlag ){
1365
+ zOpType = "Clone";
1366
+ }else if( syncFlags & SYNC_PULL ){
13531367
blob_appendf(&send, "pull %s %s\n", zSCode, zPCode);
13541368
nCardSent++;
1369
+ zOpType = "Pull";
13551370
}
1356
- if( pushFlag ){
1371
+ if( syncFlags & SYNC_PUSH ){
13571372
blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
13581373
nCardSent++;
1374
+ if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push";
13591375
}
13601376
manifest_crosslink_begin();
13611377
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
+ }
13631381
13641382
while( go ){
13651383
int newPhantom = 0;
13661384
char *zRandomness;
13671385
@@ -1374,25 +1392,28 @@
13741392
}
13751393
13761394
/* Generate gimme cards for phantoms and leaf cards
13771395
** for all leaves.
13781396
*/
1379
- if( pullFlag || (cloneFlag && cloneSeqno==1) ){
1397
+ if( (syncFlags & SYNC_PULL)!=0
1398
+ || ((syncFlags & SYNC_CLONE)!=0 && cloneSeqno==1)
1399
+ ){
13801400
request_phantoms(&xfer, mxPhantomReq);
13811401
}
1382
- if( pushFlag ){
1402
+ if( syncFlags & SYNC_PUSH ){
13831403
send_unsent(&xfer);
13841404
nCardSent += send_unclustered(&xfer);
1385
- if( privateFlag ) send_private(&xfer);
1405
+ if( syncFlags & SYNC_PRIVATE ) send_private(&xfer);
13861406
}
13871407
13881408
/* Send configuration parameter requests. On a clone, delay sending
13891409
** this until the second cycle since the login card might fail on
13901410
** the first cycle.
13911411
*/
1392
- if( configRcvMask && (cloneFlag==0 || nCycle>0) ){
1412
+ if( configRcvMask && ((syncFlags & SYNC_CLONE)==0 || nCycle>0) ){
13931413
const char *zName;
1414
+ if( zOpType==0 ) zOpType = "Pull";
13941415
zName = configure_first_name(configRcvMask);
13951416
while( zName ){
13961417
blob_appendf(&send, "reqconfig %s\n", zName);
13971418
zName = configure_next_name(configRcvMask);
13981419
nCardSent++;
@@ -1407,10 +1428,11 @@
14071428
configRcvMask = 0;
14081429
}
14091430
14101431
/* Send configuration parameters being pushed */
14111432
if( configSendMask ){
1433
+ if( zOpType==0 ) zOpType = "Push";
14121434
if( configSendMask & CONFIGSET_OLDFORMAT ){
14131435
const char *zName;
14141436
zName = configure_first_name(configSendMask);
14151437
while( zName ){
14161438
send_legacy_config_card(&xfer, zName);
@@ -1430,42 +1452,50 @@
14301452
zRandomness = db_text(0, "SELECT hex(randomblob(20))");
14311453
blob_appendf(&send, "# %s\n", zRandomness);
14321454
free(zRandomness);
14331455
14341456
/* 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
+ }
14381466
nCardSent = 0;
14391467
nCardRcvd = 0;
14401468
xfer.nFileSent = 0;
14411469
xfer.nDeltaSent = 0;
14421470
xfer.nGimmeSent = 0;
14431471
xfer.nIGotSent = 0;
1444
- if( !g.cgiOutput && !g.fQuiet ){
1472
+ if( syncFlags & SYNC_VERBOSE ){
14451473
fossil_print("waiting for server...");
14461474
}
14471475
fflush(stdout);
1448
- if( http_exchange(&send, &recv, cloneFlag==0 || nCycle>0) ){
1476
+ if( http_exchange(&send, &recv, (syncFlags & SYNC_CLONE)==0 || nCycle>0) ){
14491477
nErr++;
14501478
break;
14511479
}
14521480
lastPctDone = -1;
14531481
blob_reset(&send);
14541482
rArrivalTime = db_double(0.0, "SELECT julianday('now')");
14551483
14561484
/* 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
+ }
14581488
14591489
/* Begin constructing the next message (which might never be
14601490
** sent) by beginning with the pull or push cards
14611491
*/
1462
- if( pullFlag ){
1492
+ if( syncFlags & SYNC_PULL ){
14631493
blob_appendf(&send, "pull %s %s\n", zSCode, zPCode);
14641494
nCardSent++;
14651495
}
1466
- if( pushFlag ){
1496
+ if( syncFlags & SYNC_PUSH ){
14671497
blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
14681498
nCardSent++;
14691499
}
14701500
go = 0;
14711501
@@ -1493,11 +1523,11 @@
14931523
nCardRcvd++;
14941524
continue;
14951525
}
14961526
xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken));
14971527
nCardRcvd++;
1498
- if( !g.cgiOutput && !g.fQuiet && recv.nUsed>0 ){
1528
+ if( (syncFlags & SYNC_VERBOSE)!=0 && recv.nUsed>0 ){
14991529
pctDone = (recv.iCursor*100)/recv.nUsed;
15001530
if( pctDone!=lastPctDone ){
15011531
fossil_print("\rprocessed: %d%% ", pctDone);
15021532
lastPctDone = pctDone;
15031533
fflush(stdout);
@@ -1508,20 +1538,22 @@
15081538
** file UUID DELTASRC SIZE \n CONTENT
15091539
**
15101540
** Receive a file transmitted from the server.
15111541
*/
15121542
if( blob_eq(&xfer.aToken[0],"file") ){
1513
- xfer_accept_file(&xfer, cloneFlag);
1543
+ xfer_accept_file(&xfer, (syncFlags & SYNC_CLONE)!=0);
1544
+ nArtifactRcvd++;
15141545
}else
15151546
15161547
/* cfile UUID USIZE CSIZE \n CONTENT
15171548
** cfile UUID DELTASRC USIZE CSIZE \n CONTENT
15181549
**
15191550
** Receive a compressed file transmitted from the server.
15201551
*/
15211552
if( blob_eq(&xfer.aToken[0],"cfile") ){
15221553
xfer_accept_compressed_file(&xfer);
1554
+ nArtifactRcvd++;
15231555
}else
15241556
15251557
/* gimme UUID
15261558
**
15271559
** Server is requesting a file. If the file is a manifest, assume
@@ -1530,11 +1562,11 @@
15301562
*/
15311563
if( blob_eq(&xfer.aToken[0], "gimme")
15321564
&& xfer.nToken==2
15331565
&& blob_is_uuid(&xfer.aToken[1])
15341566
){
1535
- if( pushFlag ){
1567
+ if( syncFlags & SYNC_PUSH ){
15361568
int rid = rid_from_uuid(&xfer.aToken[1], 0, 0);
15371569
if( rid ) send_file(&xfer, rid, &xfer.aToken[1], 0);
15381570
}
15391571
}else
15401572
@@ -1559,11 +1591,11 @@
15591591
rid = rid_from_uuid(&xfer.aToken[1], 0, 0);
15601592
if( rid>0 ){
15611593
if( !isPriv ) content_make_public(rid);
15621594
}else if( isPriv && !g.perm.Private ){
15631595
/* ignore private files */
1564
- }else if( pullFlag || cloneFlag ){
1596
+ }else if( (syncFlags & (SYNC_PULL|SYNC_CLONE))!=0 ){
15651597
rid = content_new(blob_str(&xfer.aToken[1]), isPriv);
15661598
if( rid ) newPhantom = 1;
15671599
}
15681600
remote_has(rid);
15691601
}else
@@ -1574,11 +1606,11 @@
15741606
** Should only happen in response to a clone. This message tells
15751607
** the client what product to use for the new database.
15761608
*/
15771609
if( blob_eq(&xfer.aToken[0],"push")
15781610
&& xfer.nToken==3
1579
- && cloneFlag
1611
+ && (syncFlags & SYNC_CLONE)!=0
15801612
&& blob_is_uuid(&xfer.aToken[1])
15811613
&& blob_is_uuid(&xfer.aToken[2])
15821614
){
15831615
if( blob_eq_str(&xfer.aToken[1], zSCode, -1) ){
15841616
fossil_fatal("server loop");
@@ -1604,11 +1636,12 @@
16041636
Blob content;
16051637
blob_zero(&content);
16061638
blob_extract(xfer.pIn, size, &content);
16071639
g.perm.Admin = g.perm.RdAddr = 1;
16081640
configure_receive(zName, &content, origConfigRcvMask);
1609
- nCardSent++;
1641
+ nCardRcvd++;
1642
+ nArtifactRcvd++;
16101643
blob_reset(&content);
16111644
blob_seek(xfer.pIn, 1, BLOB_SEEK_CUR);
16121645
}else
16131646
16141647
@@ -1655,12 +1688,12 @@
16551688
** to the next cycle.
16561689
*/
16571690
if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){
16581691
char *zMsg = blob_terminate(&xfer.aToken[1]);
16591692
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;
16621695
zMsg = 0;
16631696
}
16641697
fossil_print("\rServer says: %s\n", zMsg);
16651698
}else
16661699
@@ -1683,11 +1716,11 @@
16831716
** is returned in the reply before the error card, so second and
16841717
** subsequent messages should be OK. Nevertheless, we need to ignore
16851718
** the error card on the first message of a clone.
16861719
*/
16871720
if( blob_eq(&xfer.aToken[0],"error") && xfer.nToken==2 ){
1688
- if( !cloneFlag || nCycle>0 ){
1721
+ if( (syncFlags & SYNC_CLONE)==0 || nCycle>0 ){
16891722
char *zMsg = blob_terminate(&xfer.aToken[1]);
16901723
defossilize(zMsg);
16911724
if( fossil_strcmp(zMsg, "login failed")==0 ){
16921725
if( nCycle<2 ){
16931726
if( !g.dontKeepUrl ) db_unset("last-sync-pw", 0);
@@ -1727,14 +1760,16 @@
17271760
&& (configRcvMask & CONFIGSET_OLDFORMAT)!=0
17281761
){
17291762
configure_finalize_receive();
17301763
}
17311764
origConfigRcvMask = 0;
1732
- if( nCardRcvd>0 ){
1765
+ if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){
17331766
fossil_print(zValueFormat, "Received:",
17341767
blob_size(&recv), nCardRcvd,
17351768
xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile);
1769
+ }else{
1770
+ fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd);
17361771
}
17371772
blob_reset(&recv);
17381773
nCycle++;
17391774
17401775
/* If we received one or more files on the previous exchange but
@@ -1743,11 +1778,11 @@
17431778
nFileRecv = xfer.nFileRcvd + xfer.nDeltaRcvd + xfer.nDanglingFile;
17441779
if( (nFileRecv>0 || newPhantom) && db_exists("SELECT 1 FROM phantom") ){
17451780
go = 1;
17461781
mxPhantomReq = nFileRecv*2;
17471782
if( mxPhantomReq<200 ) mxPhantomReq = 200;
1748
- }else if( cloneFlag && nFileRecv>0 ){
1783
+ }else if( (syncFlags & SYNC_CLONE)!=0 && nFileRecv>0 ){
17491784
go = 1;
17501785
}
17511786
nCardRcvd = 0;
17521787
xfer.nFileRcvd = 0;
17531788
xfer.nDeltaRcvd = 0;
@@ -1759,25 +1794,27 @@
17591794
if( xfer.nFileSent+xfer.nDeltaSent>0 ){
17601795
go = 1;
17611796
}
17621797
17631798
/* 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;
17651800
17661801
/* Stop the cycle if the server sends a "clone_seqno 0" card and
17671802
** we have gone at least two rounds. Always go at least two rounds
17681803
** on a clone in order to be sure to retrieve the configuration
17691804
** information which is only sent on the second round.
17701805
*/
17711806
if( cloneSeqno<=0 && nCycle>1 ) go = 0;
17721807
};
17731808
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);
17761813
transport_close();
17771814
transport_global_shutdown();
17781815
db_multi_exec("DROP TABLE onremote");
17791816
manifest_crosslink_end();
17801817
content_enable_dephantomize(1);
17811818
db_end_transaction(0);
17821819
return nErr;
17831820
}
17841821
--- 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 @@
12661266
/*
12671267
** Format strings for progress reporting.
12681268
*/
12691269
static const char zLabelFormat[] = "%-10s %10s %10s %10s %10s\n";
12701270
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";
12711273
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
12721284
12731285
/*
12741286
** Sync to the host identified in g.urlName and g.urlPath. This
12751287
** routine is called by the client.
12761288
**
@@ -1277,16 +1289,13 @@
12771289
** Records are pushed to the server if pushFlag is true. Records
12781290
** are pulled if pullFlag is true. A full sync occurs if both are
12791291
** true.
12801292
*/
12811293
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 */
12881297
){
12891298
int go = 1; /* Loop until zero */
12901299
int nCardSent = 0; /* Number of cards sent */
12911300
int nCardRcvd = 0; /* Number of cards received */
12921301
int nCycle = 0; /* Number of round trips to the server */
@@ -1304,27 +1313,30 @@
13041313
int lastPctDone = -1; /* Last displayed pctDone */
13051314
double rArrivalTime; /* Time at which a message arrived */
13061315
const char *zSCode = db_get("server-code", "x");
13071316
const char *zPCode = db_get("project-code", 0);
13081317
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 */
13091322
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
13121325
&& configRcvMask==0 && configSendMask==0 ) return 0;
13131326
13141327
transport_stats(0, 0, 1);
13151328
socket_global_init();
13161329
memset(&xfer, 0, sizeof(xfer));
13171330
xfer.pIn = &recv;
13181331
xfer.pOut = &send;
13191332
xfer.mxSend = db_get_int("max-upload", 250000);
1320
- if( privateFlag ){
1333
+ if( syncFlags & SYNC_PRIVATE ){
13211334
g.perm.Private = 1;
13221335
xfer.syncPrivate = 1;
13231336
}
13241337
1325
- assert( pushFlag | pullFlag | cloneFlag | configRcvMask | configSendMask );
13261338
db_begin_transaction();
13271339
db_record_repository_filename(0);
13281340
db_multi_exec(
13291341
"CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
13301342
);
@@ -1335,33 +1347,39 @@
13351347
blob_zero(&xfer.line);
13361348
origConfigRcvMask = 0;
13371349
13381350
13391351
/* 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
+ }
13411355
13421356
/*
13431357
** Always begin with a clone, pull, or push message
13441358
*/
1345
- if( cloneFlag ){
1359
+ if( syncFlags & SYNC_CLONE ){
13461360
blob_appendf(&send, "clone 3 %d\n", cloneSeqno);
1347
- pushFlag = 0;
1348
- pullFlag = 0;
1361
+ syncFlags &= ~(SYNC_PUSH|SYNC_PULL);
13491362
nCardSent++;
13501363
/* TBD: Request all transferable configuration values */
13511364
content_enable_dephantomize(0);
1352
- }else if( pullFlag ){
1365
+ zOpType = "Clone";
1366
+ }else if( syncFlags & SYNC_PULL ){
13531367
blob_appendf(&send, "pull %s %s\n", zSCode, zPCode);
13541368
nCardSent++;
1369
+ zOpType = "Pull";
13551370
}
1356
- if( pushFlag ){
1371
+ if( syncFlags & SYNC_PUSH ){
13571372
blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
13581373
nCardSent++;
1374
+ if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push";
13591375
}
13601376
manifest_crosslink_begin();
13611377
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
+ }
13631381
13641382
while( go ){
13651383
int newPhantom = 0;
13661384
char *zRandomness;
13671385
@@ -1374,25 +1392,28 @@
13741392
}
13751393
13761394
/* Generate gimme cards for phantoms and leaf cards
13771395
** for all leaves.
13781396
*/
1379
- if( pullFlag || (cloneFlag && cloneSeqno==1) ){
1397
+ if( (syncFlags & SYNC_PULL)!=0
1398
+ || ((syncFlags & SYNC_CLONE)!=0 && cloneSeqno==1)
1399
+ ){
13801400
request_phantoms(&xfer, mxPhantomReq);
13811401
}
1382
- if( pushFlag ){
1402
+ if( syncFlags & SYNC_PUSH ){
13831403
send_unsent(&xfer);
13841404
nCardSent += send_unclustered(&xfer);
1385
- if( privateFlag ) send_private(&xfer);
1405
+ if( syncFlags & SYNC_PRIVATE ) send_private(&xfer);
13861406
}
13871407
13881408
/* Send configuration parameter requests. On a clone, delay sending
13891409
** this until the second cycle since the login card might fail on
13901410
** the first cycle.
13911411
*/
1392
- if( configRcvMask && (cloneFlag==0 || nCycle>0) ){
1412
+ if( configRcvMask && ((syncFlags & SYNC_CLONE)==0 || nCycle>0) ){
13931413
const char *zName;
1414
+ if( zOpType==0 ) zOpType = "Pull";
13941415
zName = configure_first_name(configRcvMask);
13951416
while( zName ){
13961417
blob_appendf(&send, "reqconfig %s\n", zName);
13971418
zName = configure_next_name(configRcvMask);
13981419
nCardSent++;
@@ -1407,10 +1428,11 @@
14071428
configRcvMask = 0;
14081429
}
14091430
14101431
/* Send configuration parameters being pushed */
14111432
if( configSendMask ){
1433
+ if( zOpType==0 ) zOpType = "Push";
14121434
if( configSendMask & CONFIGSET_OLDFORMAT ){
14131435
const char *zName;
14141436
zName = configure_first_name(configSendMask);
14151437
while( zName ){
14161438
send_legacy_config_card(&xfer, zName);
@@ -1430,42 +1452,50 @@
14301452
zRandomness = db_text(0, "SELECT hex(randomblob(20))");
14311453
blob_appendf(&send, "# %s\n", zRandomness);
14321454
free(zRandomness);
14331455
14341456
/* 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
+ }
14381466
nCardSent = 0;
14391467
nCardRcvd = 0;
14401468
xfer.nFileSent = 0;
14411469
xfer.nDeltaSent = 0;
14421470
xfer.nGimmeSent = 0;
14431471
xfer.nIGotSent = 0;
1444
- if( !g.cgiOutput && !g.fQuiet ){
1472
+ if( syncFlags & SYNC_VERBOSE ){
14451473
fossil_print("waiting for server...");
14461474
}
14471475
fflush(stdout);
1448
- if( http_exchange(&send, &recv, cloneFlag==0 || nCycle>0) ){
1476
+ if( http_exchange(&send, &recv, (syncFlags & SYNC_CLONE)==0 || nCycle>0) ){
14491477
nErr++;
14501478
break;
14511479
}
14521480
lastPctDone = -1;
14531481
blob_reset(&send);
14541482
rArrivalTime = db_double(0.0, "SELECT julianday('now')");
14551483
14561484
/* 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
+ }
14581488
14591489
/* Begin constructing the next message (which might never be
14601490
** sent) by beginning with the pull or push cards
14611491
*/
1462
- if( pullFlag ){
1492
+ if( syncFlags & SYNC_PULL ){
14631493
blob_appendf(&send, "pull %s %s\n", zSCode, zPCode);
14641494
nCardSent++;
14651495
}
1466
- if( pushFlag ){
1496
+ if( syncFlags & SYNC_PUSH ){
14671497
blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
14681498
nCardSent++;
14691499
}
14701500
go = 0;
14711501
@@ -1493,11 +1523,11 @@
14931523
nCardRcvd++;
14941524
continue;
14951525
}
14961526
xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken));
14971527
nCardRcvd++;
1498
- if( !g.cgiOutput && !g.fQuiet && recv.nUsed>0 ){
1528
+ if( (syncFlags & SYNC_VERBOSE)!=0 && recv.nUsed>0 ){
14991529
pctDone = (recv.iCursor*100)/recv.nUsed;
15001530
if( pctDone!=lastPctDone ){
15011531
fossil_print("\rprocessed: %d%% ", pctDone);
15021532
lastPctDone = pctDone;
15031533
fflush(stdout);
@@ -1508,20 +1538,22 @@
15081538
** file UUID DELTASRC SIZE \n CONTENT
15091539
**
15101540
** Receive a file transmitted from the server.
15111541
*/
15121542
if( blob_eq(&xfer.aToken[0],"file") ){
1513
- xfer_accept_file(&xfer, cloneFlag);
1543
+ xfer_accept_file(&xfer, (syncFlags & SYNC_CLONE)!=0);
1544
+ nArtifactRcvd++;
15141545
}else
15151546
15161547
/* cfile UUID USIZE CSIZE \n CONTENT
15171548
** cfile UUID DELTASRC USIZE CSIZE \n CONTENT
15181549
**
15191550
** Receive a compressed file transmitted from the server.
15201551
*/
15211552
if( blob_eq(&xfer.aToken[0],"cfile") ){
15221553
xfer_accept_compressed_file(&xfer);
1554
+ nArtifactRcvd++;
15231555
}else
15241556
15251557
/* gimme UUID
15261558
**
15271559
** Server is requesting a file. If the file is a manifest, assume
@@ -1530,11 +1562,11 @@
15301562
*/
15311563
if( blob_eq(&xfer.aToken[0], "gimme")
15321564
&& xfer.nToken==2
15331565
&& blob_is_uuid(&xfer.aToken[1])
15341566
){
1535
- if( pushFlag ){
1567
+ if( syncFlags & SYNC_PUSH ){
15361568
int rid = rid_from_uuid(&xfer.aToken[1], 0, 0);
15371569
if( rid ) send_file(&xfer, rid, &xfer.aToken[1], 0);
15381570
}
15391571
}else
15401572
@@ -1559,11 +1591,11 @@
15591591
rid = rid_from_uuid(&xfer.aToken[1], 0, 0);
15601592
if( rid>0 ){
15611593
if( !isPriv ) content_make_public(rid);
15621594
}else if( isPriv && !g.perm.Private ){
15631595
/* ignore private files */
1564
- }else if( pullFlag || cloneFlag ){
1596
+ }else if( (syncFlags & (SYNC_PULL|SYNC_CLONE))!=0 ){
15651597
rid = content_new(blob_str(&xfer.aToken[1]), isPriv);
15661598
if( rid ) newPhantom = 1;
15671599
}
15681600
remote_has(rid);
15691601
}else
@@ -1574,11 +1606,11 @@
15741606
** Should only happen in response to a clone. This message tells
15751607
** the client what product to use for the new database.
15761608
*/
15771609
if( blob_eq(&xfer.aToken[0],"push")
15781610
&& xfer.nToken==3
1579
- && cloneFlag
1611
+ && (syncFlags & SYNC_CLONE)!=0
15801612
&& blob_is_uuid(&xfer.aToken[1])
15811613
&& blob_is_uuid(&xfer.aToken[2])
15821614
){
15831615
if( blob_eq_str(&xfer.aToken[1], zSCode, -1) ){
15841616
fossil_fatal("server loop");
@@ -1604,11 +1636,12 @@
16041636
Blob content;
16051637
blob_zero(&content);
16061638
blob_extract(xfer.pIn, size, &content);
16071639
g.perm.Admin = g.perm.RdAddr = 1;
16081640
configure_receive(zName, &content, origConfigRcvMask);
1609
- nCardSent++;
1641
+ nCardRcvd++;
1642
+ nArtifactRcvd++;
16101643
blob_reset(&content);
16111644
blob_seek(xfer.pIn, 1, BLOB_SEEK_CUR);
16121645
}else
16131646
16141647
@@ -1655,12 +1688,12 @@
16551688
** to the next cycle.
16561689
*/
16571690
if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){
16581691
char *zMsg = blob_terminate(&xfer.aToken[1]);
16591692
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;
16621695
zMsg = 0;
16631696
}
16641697
fossil_print("\rServer says: %s\n", zMsg);
16651698
}else
16661699
@@ -1683,11 +1716,11 @@
16831716
** is returned in the reply before the error card, so second and
16841717
** subsequent messages should be OK. Nevertheless, we need to ignore
16851718
** the error card on the first message of a clone.
16861719
*/
16871720
if( blob_eq(&xfer.aToken[0],"error") && xfer.nToken==2 ){
1688
- if( !cloneFlag || nCycle>0 ){
1721
+ if( (syncFlags & SYNC_CLONE)==0 || nCycle>0 ){
16891722
char *zMsg = blob_terminate(&xfer.aToken[1]);
16901723
defossilize(zMsg);
16911724
if( fossil_strcmp(zMsg, "login failed")==0 ){
16921725
if( nCycle<2 ){
16931726
if( !g.dontKeepUrl ) db_unset("last-sync-pw", 0);
@@ -1727,14 +1760,16 @@
17271760
&& (configRcvMask & CONFIGSET_OLDFORMAT)!=0
17281761
){
17291762
configure_finalize_receive();
17301763
}
17311764
origConfigRcvMask = 0;
1732
- if( nCardRcvd>0 ){
1765
+ if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){
17331766
fossil_print(zValueFormat, "Received:",
17341767
blob_size(&recv), nCardRcvd,
17351768
xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile);
1769
+ }else{
1770
+ fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd);
17361771
}
17371772
blob_reset(&recv);
17381773
nCycle++;
17391774
17401775
/* If we received one or more files on the previous exchange but
@@ -1743,11 +1778,11 @@
17431778
nFileRecv = xfer.nFileRcvd + xfer.nDeltaRcvd + xfer.nDanglingFile;
17441779
if( (nFileRecv>0 || newPhantom) && db_exists("SELECT 1 FROM phantom") ){
17451780
go = 1;
17461781
mxPhantomReq = nFileRecv*2;
17471782
if( mxPhantomReq<200 ) mxPhantomReq = 200;
1748
- }else if( cloneFlag && nFileRecv>0 ){
1783
+ }else if( (syncFlags & SYNC_CLONE)!=0 && nFileRecv>0 ){
17491784
go = 1;
17501785
}
17511786
nCardRcvd = 0;
17521787
xfer.nFileRcvd = 0;
17531788
xfer.nDeltaRcvd = 0;
@@ -1759,25 +1794,27 @@
17591794
if( xfer.nFileSent+xfer.nDeltaSent>0 ){
17601795
go = 1;
17611796
}
17621797
17631798
/* 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;
17651800
17661801
/* Stop the cycle if the server sends a "clone_seqno 0" card and
17671802
** we have gone at least two rounds. Always go at least two rounds
17681803
** on a clone in order to be sure to retrieve the configuration
17691804
** information which is only sent on the second round.
17701805
*/
17711806
if( cloneSeqno<=0 && nCycle>1 ) go = 0;
17721807
};
17731808
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);
17761813
transport_close();
17771814
transport_global_shutdown();
17781815
db_multi_exec("DROP TABLE onremote");
17791816
manifest_crosslink_end();
17801817
content_enable_dephantomize(1);
17811818
db_end_transaction(0);
17821819
return nErr;
17831820
}
17841821
--- 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 @@
12661266
/*
12671267
** Format strings for progress reporting.
12681268
*/
12691269
static const char zLabelFormat[] = "%-10s %10s %10s %10s %10s\n";
12701270
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";
12711273
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
12721284
12731285
/*
12741286
** Sync to the host identified in g.urlName and g.urlPath. This
12751287
** routine is called by the client.
12761288
**
@@ -1277,16 +1289,13 @@
12771289
** Records are pushed to the server if pushFlag is true. Records
12781290
** are pulled if pullFlag is true. A full sync occurs if both are
12791291
** true.
12801292
*/
12811293
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 */
12881297
){
12891298
int go = 1; /* Loop until zero */
12901299
int nCardSent = 0; /* Number of cards sent */
12911300
int nCardRcvd = 0; /* Number of cards received */
12921301
int nCycle = 0; /* Number of round trips to the server */
@@ -1304,27 +1313,30 @@
13041313
int lastPctDone = -1; /* Last displayed pctDone */
13051314
double rArrivalTime; /* Time at which a message arrived */
13061315
const char *zSCode = db_get("server-code", "x");
13071316
const char *zPCode = db_get("project-code", 0);
13081317
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 */
13091322
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
13121325
&& configRcvMask==0 && configSendMask==0 ) return 0;
13131326
13141327
transport_stats(0, 0, 1);
13151328
socket_global_init();
13161329
memset(&xfer, 0, sizeof(xfer));
13171330
xfer.pIn = &recv;
13181331
xfer.pOut = &send;
13191332
xfer.mxSend = db_get_int("max-upload", 250000);
1320
- if( privateFlag ){
1333
+ if( syncFlags & SYNC_PRIVATE ){
13211334
g.perm.Private = 1;
13221335
xfer.syncPrivate = 1;
13231336
}
13241337
1325
- assert( pushFlag | pullFlag | cloneFlag | configRcvMask | configSendMask );
13261338
db_begin_transaction();
13271339
db_record_repository_filename(0);
13281340
db_multi_exec(
13291341
"CREATE TEMP TABLE onremote(rid INTEGER PRIMARY KEY);"
13301342
);
@@ -1335,33 +1347,39 @@
13351347
blob_zero(&xfer.line);
13361348
origConfigRcvMask = 0;
13371349
13381350
13391351
/* 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
+ }
13411355
13421356
/*
13431357
** Always begin with a clone, pull, or push message
13441358
*/
1345
- if( cloneFlag ){
1359
+ if( syncFlags & SYNC_CLONE ){
13461360
blob_appendf(&send, "clone 3 %d\n", cloneSeqno);
1347
- pushFlag = 0;
1348
- pullFlag = 0;
1361
+ syncFlags &= ~(SYNC_PUSH|SYNC_PULL);
13491362
nCardSent++;
13501363
/* TBD: Request all transferable configuration values */
13511364
content_enable_dephantomize(0);
1352
- }else if( pullFlag ){
1365
+ zOpType = "Clone";
1366
+ }else if( syncFlags & SYNC_PULL ){
13531367
blob_appendf(&send, "pull %s %s\n", zSCode, zPCode);
13541368
nCardSent++;
1369
+ zOpType = "Pull";
13551370
}
1356
- if( pushFlag ){
1371
+ if( syncFlags & SYNC_PUSH ){
13571372
blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
13581373
nCardSent++;
1374
+ if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push";
13591375
}
13601376
manifest_crosslink_begin();
13611377
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
+ }
13631381
13641382
while( go ){
13651383
int newPhantom = 0;
13661384
char *zRandomness;
13671385
@@ -1374,25 +1392,28 @@
13741392
}
13751393
13761394
/* Generate gimme cards for phantoms and leaf cards
13771395
** for all leaves.
13781396
*/
1379
- if( pullFlag || (cloneFlag && cloneSeqno==1) ){
1397
+ if( (syncFlags & SYNC_PULL)!=0
1398
+ || ((syncFlags & SYNC_CLONE)!=0 && cloneSeqno==1)
1399
+ ){
13801400
request_phantoms(&xfer, mxPhantomReq);
13811401
}
1382
- if( pushFlag ){
1402
+ if( syncFlags & SYNC_PUSH ){
13831403
send_unsent(&xfer);
13841404
nCardSent += send_unclustered(&xfer);
1385
- if( privateFlag ) send_private(&xfer);
1405
+ if( syncFlags & SYNC_PRIVATE ) send_private(&xfer);
13861406
}
13871407
13881408
/* Send configuration parameter requests. On a clone, delay sending
13891409
** this until the second cycle since the login card might fail on
13901410
** the first cycle.
13911411
*/
1392
- if( configRcvMask && (cloneFlag==0 || nCycle>0) ){
1412
+ if( configRcvMask && ((syncFlags & SYNC_CLONE)==0 || nCycle>0) ){
13931413
const char *zName;
1414
+ if( zOpType==0 ) zOpType = "Pull";
13941415
zName = configure_first_name(configRcvMask);
13951416
while( zName ){
13961417
blob_appendf(&send, "reqconfig %s\n", zName);
13971418
zName = configure_next_name(configRcvMask);
13981419
nCardSent++;
@@ -1407,10 +1428,11 @@
14071428
configRcvMask = 0;
14081429
}
14091430
14101431
/* Send configuration parameters being pushed */
14111432
if( configSendMask ){
1433
+ if( zOpType==0 ) zOpType = "Push";
14121434
if( configSendMask & CONFIGSET_OLDFORMAT ){
14131435
const char *zName;
14141436
zName = configure_first_name(configSendMask);
14151437
while( zName ){
14161438
send_legacy_config_card(&xfer, zName);
@@ -1430,42 +1452,50 @@
14301452
zRandomness = db_text(0, "SELECT hex(randomblob(20))");
14311453
blob_appendf(&send, "# %s\n", zRandomness);
14321454
free(zRandomness);
14331455
14341456
/* 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
+ }
14381466
nCardSent = 0;
14391467
nCardRcvd = 0;
14401468
xfer.nFileSent = 0;
14411469
xfer.nDeltaSent = 0;
14421470
xfer.nGimmeSent = 0;
14431471
xfer.nIGotSent = 0;
1444
- if( !g.cgiOutput && !g.fQuiet ){
1472
+ if( syncFlags & SYNC_VERBOSE ){
14451473
fossil_print("waiting for server...");
14461474
}
14471475
fflush(stdout);
1448
- if( http_exchange(&send, &recv, cloneFlag==0 || nCycle>0) ){
1476
+ if( http_exchange(&send, &recv, (syncFlags & SYNC_CLONE)==0 || nCycle>0) ){
14491477
nErr++;
14501478
break;
14511479
}
14521480
lastPctDone = -1;
14531481
blob_reset(&send);
14541482
rArrivalTime = db_double(0.0, "SELECT julianday('now')");
14551483
14561484
/* 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
+ }
14581488
14591489
/* Begin constructing the next message (which might never be
14601490
** sent) by beginning with the pull or push cards
14611491
*/
1462
- if( pullFlag ){
1492
+ if( syncFlags & SYNC_PULL ){
14631493
blob_appendf(&send, "pull %s %s\n", zSCode, zPCode);
14641494
nCardSent++;
14651495
}
1466
- if( pushFlag ){
1496
+ if( syncFlags & SYNC_PUSH ){
14671497
blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
14681498
nCardSent++;
14691499
}
14701500
go = 0;
14711501
@@ -1493,11 +1523,11 @@
14931523
nCardRcvd++;
14941524
continue;
14951525
}
14961526
xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken));
14971527
nCardRcvd++;
1498
- if( !g.cgiOutput && !g.fQuiet && recv.nUsed>0 ){
1528
+ if( (syncFlags & SYNC_VERBOSE)!=0 && recv.nUsed>0 ){
14991529
pctDone = (recv.iCursor*100)/recv.nUsed;
15001530
if( pctDone!=lastPctDone ){
15011531
fossil_print("\rprocessed: %d%% ", pctDone);
15021532
lastPctDone = pctDone;
15031533
fflush(stdout);
@@ -1508,20 +1538,22 @@
15081538
** file UUID DELTASRC SIZE \n CONTENT
15091539
**
15101540
** Receive a file transmitted from the server.
15111541
*/
15121542
if( blob_eq(&xfer.aToken[0],"file") ){
1513
- xfer_accept_file(&xfer, cloneFlag);
1543
+ xfer_accept_file(&xfer, (syncFlags & SYNC_CLONE)!=0);
1544
+ nArtifactRcvd++;
15141545
}else
15151546
15161547
/* cfile UUID USIZE CSIZE \n CONTENT
15171548
** cfile UUID DELTASRC USIZE CSIZE \n CONTENT
15181549
**
15191550
** Receive a compressed file transmitted from the server.
15201551
*/
15211552
if( blob_eq(&xfer.aToken[0],"cfile") ){
15221553
xfer_accept_compressed_file(&xfer);
1554
+ nArtifactRcvd++;
15231555
}else
15241556
15251557
/* gimme UUID
15261558
**
15271559
** Server is requesting a file. If the file is a manifest, assume
@@ -1530,11 +1562,11 @@
15301562
*/
15311563
if( blob_eq(&xfer.aToken[0], "gimme")
15321564
&& xfer.nToken==2
15331565
&& blob_is_uuid(&xfer.aToken[1])
15341566
){
1535
- if( pushFlag ){
1567
+ if( syncFlags & SYNC_PUSH ){
15361568
int rid = rid_from_uuid(&xfer.aToken[1], 0, 0);
15371569
if( rid ) send_file(&xfer, rid, &xfer.aToken[1], 0);
15381570
}
15391571
}else
15401572
@@ -1559,11 +1591,11 @@
15591591
rid = rid_from_uuid(&xfer.aToken[1], 0, 0);
15601592
if( rid>0 ){
15611593
if( !isPriv ) content_make_public(rid);
15621594
}else if( isPriv && !g.perm.Private ){
15631595
/* ignore private files */
1564
- }else if( pullFlag || cloneFlag ){
1596
+ }else if( (syncFlags & (SYNC_PULL|SYNC_CLONE))!=0 ){
15651597
rid = content_new(blob_str(&xfer.aToken[1]), isPriv);
15661598
if( rid ) newPhantom = 1;
15671599
}
15681600
remote_has(rid);
15691601
}else
@@ -1574,11 +1606,11 @@
15741606
** Should only happen in response to a clone. This message tells
15751607
** the client what product to use for the new database.
15761608
*/
15771609
if( blob_eq(&xfer.aToken[0],"push")
15781610
&& xfer.nToken==3
1579
- && cloneFlag
1611
+ && (syncFlags & SYNC_CLONE)!=0
15801612
&& blob_is_uuid(&xfer.aToken[1])
15811613
&& blob_is_uuid(&xfer.aToken[2])
15821614
){
15831615
if( blob_eq_str(&xfer.aToken[1], zSCode, -1) ){
15841616
fossil_fatal("server loop");
@@ -1604,11 +1636,12 @@
16041636
Blob content;
16051637
blob_zero(&content);
16061638
blob_extract(xfer.pIn, size, &content);
16071639
g.perm.Admin = g.perm.RdAddr = 1;
16081640
configure_receive(zName, &content, origConfigRcvMask);
1609
- nCardSent++;
1641
+ nCardRcvd++;
1642
+ nArtifactRcvd++;
16101643
blob_reset(&content);
16111644
blob_seek(xfer.pIn, 1, BLOB_SEEK_CUR);
16121645
}else
16131646
16141647
@@ -1655,12 +1688,12 @@
16551688
** to the next cycle.
16561689
*/
16571690
if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){
16581691
char *zMsg = blob_terminate(&xfer.aToken[1]);
16591692
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;
16621695
zMsg = 0;
16631696
}
16641697
fossil_print("\rServer says: %s\n", zMsg);
16651698
}else
16661699
@@ -1683,11 +1716,11 @@
16831716
** is returned in the reply before the error card, so second and
16841717
** subsequent messages should be OK. Nevertheless, we need to ignore
16851718
** the error card on the first message of a clone.
16861719
*/
16871720
if( blob_eq(&xfer.aToken[0],"error") && xfer.nToken==2 ){
1688
- if( !cloneFlag || nCycle>0 ){
1721
+ if( (syncFlags & SYNC_CLONE)==0 || nCycle>0 ){
16891722
char *zMsg = blob_terminate(&xfer.aToken[1]);
16901723
defossilize(zMsg);
16911724
if( fossil_strcmp(zMsg, "login failed")==0 ){
16921725
if( nCycle<2 ){
16931726
if( !g.dontKeepUrl ) db_unset("last-sync-pw", 0);
@@ -1727,14 +1760,16 @@
17271760
&& (configRcvMask & CONFIGSET_OLDFORMAT)!=0
17281761
){
17291762
configure_finalize_receive();
17301763
}
17311764
origConfigRcvMask = 0;
1732
- if( nCardRcvd>0 ){
1765
+ if( nCardRcvd>0 && (syncFlags & SYNC_VERBOSE) ){
17331766
fossil_print(zValueFormat, "Received:",
17341767
blob_size(&recv), nCardRcvd,
17351768
xfer.nFileRcvd, xfer.nDeltaRcvd + xfer.nDanglingFile);
1769
+ }else{
1770
+ fossil_print(zBriefFormat, nRoundtrip, nArtifactSent, nArtifactRcvd);
17361771
}
17371772
blob_reset(&recv);
17381773
nCycle++;
17391774
17401775
/* If we received one or more files on the previous exchange but
@@ -1743,11 +1778,11 @@
17431778
nFileRecv = xfer.nFileRcvd + xfer.nDeltaRcvd + xfer.nDanglingFile;
17441779
if( (nFileRecv>0 || newPhantom) && db_exists("SELECT 1 FROM phantom") ){
17451780
go = 1;
17461781
mxPhantomReq = nFileRecv*2;
17471782
if( mxPhantomReq<200 ) mxPhantomReq = 200;
1748
- }else if( cloneFlag && nFileRecv>0 ){
1783
+ }else if( (syncFlags & SYNC_CLONE)!=0 && nFileRecv>0 ){
17491784
go = 1;
17501785
}
17511786
nCardRcvd = 0;
17521787
xfer.nFileRcvd = 0;
17531788
xfer.nDeltaRcvd = 0;
@@ -1759,25 +1794,27 @@
17591794
if( xfer.nFileSent+xfer.nDeltaSent>0 ){
17601795
go = 1;
17611796
}
17621797
17631798
/* 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;
17651800
17661801
/* Stop the cycle if the server sends a "clone_seqno 0" card and
17671802
** we have gone at least two rounds. Always go at least two rounds
17681803
** on a clone in order to be sure to retrieve the configuration
17691804
** information which is only sent on the second round.
17701805
*/
17711806
if( cloneSeqno<=0 && nCycle>1 ) go = 0;
17721807
};
17731808
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);
17761813
transport_close();
17771814
transport_global_shutdown();
17781815
db_multi_exec("DROP TABLE onremote");
17791816
manifest_crosslink_end();
17801817
content_enable_dephantomize(1);
17811818
db_end_transaction(0);
17821819
return nErr;
17831820
}
17841821
--- 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

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button