Fossil SCM

Add the x-fossil-xfer-login header check in one additional place. With the help of the included debug output, the login problem seems to be caused by CGI (only) instances not reading the inbound HTTP headers. My attempts to make it do have, so far, only triggered HTTP 500 responses.

stephan 2025-07-23 17:39 xfer-login-card
Commit 6c900645ea5765e26067f0032a312ed6941f1b843d324edf2eae54d04cff8052
+3 -1
--- src/cgi.c
+++ src/cgi.c
@@ -2125,10 +2125,12 @@
21252125
int i;
21262126
const char *zScheme = "http";
21272127
char zLine[2000]; /* A single line of input. */
21282128
g.fullHttpReply = 1;
21292129
g.zReqType = "HTTP";
2130
+
2131
+ /*cgi_setenv("JUST_TESTING1", "cgi_handle_http_request()");*/
21302132
if( cgi_fgets(zLine, sizeof(zLine))==0 ){
21312133
malformed_request("missing header");
21322134
}
21332135
blob_append(&g.httpHeader, zLine, -1);
21342136
cgi_trace(zLine);
@@ -2160,11 +2162,10 @@
21602162
}
21612163
if( zIpAddr ){
21622164
cgi_setenv("REMOTE_ADDR", zIpAddr);
21632165
g.zIpAddr = fossil_strdup(zIpAddr);
21642166
}
2165
-
21662167
21672168
/* Get all the optional fields that follow the first line.
21682169
*/
21692170
while( cgi_fgets(zLine,sizeof(zLine)) ){
21702171
char *zFieldName;
@@ -2222,10 +2223,11 @@
22222223
if( sscanf(zVal,"bytes=%d-%d",&x1,&x2)==2 && x1>=0 && x1<=x2 ){
22232224
rangeStart = x1;
22242225
rangeEnd = x2+1;
22252226
}
22262227
}else if( fossil_strcmp(zFieldName, "x-fossil-xfer-login:")==0 ){
2228
+ /*cgi_setenv("FOSSIL_LCH_cgi_handle_http_request", zVal);*/
22272229
g.syncInfo.zLoginCard = fossil_strdup(zVal);
22282230
g.syncInfo.bLoginCardHeader = 1;
22292231
}
22302232
}
22312233
cgi_setenv("REQUEST_SCHEME",zScheme);
22322234
--- src/cgi.c
+++ src/cgi.c
@@ -2125,10 +2125,12 @@
2125 int i;
2126 const char *zScheme = "http";
2127 char zLine[2000]; /* A single line of input. */
2128 g.fullHttpReply = 1;
2129 g.zReqType = "HTTP";
 
 
2130 if( cgi_fgets(zLine, sizeof(zLine))==0 ){
2131 malformed_request("missing header");
2132 }
2133 blob_append(&g.httpHeader, zLine, -1);
2134 cgi_trace(zLine);
@@ -2160,11 +2162,10 @@
2160 }
2161 if( zIpAddr ){
2162 cgi_setenv("REMOTE_ADDR", zIpAddr);
2163 g.zIpAddr = fossil_strdup(zIpAddr);
2164 }
2165
2166
2167 /* Get all the optional fields that follow the first line.
2168 */
2169 while( cgi_fgets(zLine,sizeof(zLine)) ){
2170 char *zFieldName;
@@ -2222,10 +2223,11 @@
2222 if( sscanf(zVal,"bytes=%d-%d",&x1,&x2)==2 && x1>=0 && x1<=x2 ){
2223 rangeStart = x1;
2224 rangeEnd = x2+1;
2225 }
2226 }else if( fossil_strcmp(zFieldName, "x-fossil-xfer-login:")==0 ){
 
2227 g.syncInfo.zLoginCard = fossil_strdup(zVal);
2228 g.syncInfo.bLoginCardHeader = 1;
2229 }
2230 }
2231 cgi_setenv("REQUEST_SCHEME",zScheme);
2232
--- src/cgi.c
+++ src/cgi.c
@@ -2125,10 +2125,12 @@
2125 int i;
2126 const char *zScheme = "http";
2127 char zLine[2000]; /* A single line of input. */
2128 g.fullHttpReply = 1;
2129 g.zReqType = "HTTP";
2130
2131 /*cgi_setenv("JUST_TESTING1", "cgi_handle_http_request()");*/
2132 if( cgi_fgets(zLine, sizeof(zLine))==0 ){
2133 malformed_request("missing header");
2134 }
2135 blob_append(&g.httpHeader, zLine, -1);
2136 cgi_trace(zLine);
@@ -2160,11 +2162,10 @@
2162 }
2163 if( zIpAddr ){
2164 cgi_setenv("REMOTE_ADDR", zIpAddr);
2165 g.zIpAddr = fossil_strdup(zIpAddr);
2166 }
 
2167
2168 /* Get all the optional fields that follow the first line.
2169 */
2170 while( cgi_fgets(zLine,sizeof(zLine)) ){
2171 char *zFieldName;
@@ -2222,10 +2223,11 @@
2223 if( sscanf(zVal,"bytes=%d-%d",&x1,&x2)==2 && x1>=0 && x1<=x2 ){
2224 rangeStart = x1;
2225 rangeEnd = x2+1;
2226 }
2227 }else if( fossil_strcmp(zFieldName, "x-fossil-xfer-login:")==0 ){
2228 /*cgi_setenv("FOSSIL_LCH_cgi_handle_http_request", zVal);*/
2229 g.syncInfo.zLoginCard = fossil_strdup(zVal);
2230 g.syncInfo.bLoginCardHeader = 1;
2231 }
2232 }
2233 cgi_setenv("REQUEST_SCHEME",zScheme);
2234
+4
--- src/http.c
+++ src/http.c
@@ -660,10 +660,14 @@
660660
if( mHttpFlags & HTTP_NOCOMPRESS ) isCompressed = 0;
661661
}else if( fossil_strnicmp(&zLine[14], "application/x-fossil", -1)!=0 ){
662662
isError = 1;
663663
}
664664
}
665
+ }else if( fossil_strnicmp(zLine, "x-fossil-xfer-login: ", 21)==0 ){
666
+ /*cgi_setenv("FOSSIL_LCH_http_exchange", &zLine[21]);*/
667
+ g.syncInfo.zLoginCard = fossil_strdup(&zLine[21]);
668
+ g.syncInfo.bLoginCardHeader = 1;
665669
}
666670
}
667671
if( iHttpVersion<0 ){
668672
/* We got nothing back from the server. If using the ssh: protocol,
669673
** this might mean we need to add or remove the PATH=... argument
670674
--- src/http.c
+++ src/http.c
@@ -660,10 +660,14 @@
660 if( mHttpFlags & HTTP_NOCOMPRESS ) isCompressed = 0;
661 }else if( fossil_strnicmp(&zLine[14], "application/x-fossil", -1)!=0 ){
662 isError = 1;
663 }
664 }
 
 
 
 
665 }
666 }
667 if( iHttpVersion<0 ){
668 /* We got nothing back from the server. If using the ssh: protocol,
669 ** this might mean we need to add or remove the PATH=... argument
670
--- src/http.c
+++ src/http.c
@@ -660,10 +660,14 @@
660 if( mHttpFlags & HTTP_NOCOMPRESS ) isCompressed = 0;
661 }else if( fossil_strnicmp(&zLine[14], "application/x-fossil", -1)!=0 ){
662 isError = 1;
663 }
664 }
665 }else if( fossil_strnicmp(zLine, "x-fossil-xfer-login: ", 21)==0 ){
666 /*cgi_setenv("FOSSIL_LCH_http_exchange", &zLine[21]);*/
667 g.syncInfo.zLoginCard = fossil_strdup(&zLine[21]);
668 g.syncInfo.bLoginCardHeader = 1;
669 }
670 }
671 if( iHttpVersion<0 ){
672 /* We got nothing back from the server. If using the ssh: protocol,
673 ** this might mean we need to add or remove the PATH=... argument
674
+5 -5
--- src/main.c
+++ src/main.c
@@ -1810,22 +1810,22 @@
18101810
}
18111811
18121812
18131813
/* Restrictions on the URI for security:
18141814
**
1815
- ** 1. Reject characters that are not ASCII alphanumerics,
1815
+ ** 1. Reject characters that are not ASCII alphanumerics,
18161816
** "-", "_", ".", "/", or unicode (above ASCII).
18171817
** In other words: No ASCII punctuation or control characters
18181818
** other than "-", "_", "." and "/".
1819
- ** 2. Exception to rule 1: Allow /X:/ where X is any ASCII
1819
+ ** 2. Exception to rule 1: Allow /X:/ where X is any ASCII
18201820
** alphabetic character at the beginning of the name on windows.
18211821
** 3. "-" may not occur immediately after "/"
18221822
** 4. "." may not be adjacent to another "." or to "/"
18231823
**
18241824
** Any character does not satisfy these constraints a Not Found
18251825
** error is returned.
1826
- */
1826
+ */
18271827
szFile = 0;
18281828
for(j=nBase+1, k=0; zRepo[j] && k<i-1; j++, k++){
18291829
char c = zRepo[j];
18301830
if( c>='a' && c<='z' ) continue;
18311831
if( c>='A' && c<='Z' ) continue;
@@ -3526,11 +3526,11 @@
35263526
** "fossil ui --nobrowser" on the remote system and to set up a
35273527
** tunnel from the local machine to the remote. */
35283528
FILE *sshIn;
35293529
Blob ssh;
35303530
int bRunning = 0; /* True when fossil starts up on the remote */
3531
- int isRetry; /* True if on the second attempt */
3531
+ int isRetry; /* True if on the second attempt */
35323532
char zLine[1000];
35333533
35343534
blob_init(&ssh, 0, 0);
35353535
for(isRetry=0; isRetry<2 && !bRunning; isRetry++){
35363536
blob_reset(&ssh);
@@ -3565,11 +3565,11 @@
35653565
if( fCreate ) blob_appendf(&ssh, " --create");
35663566
blob_appendf(&ssh, " %$", g.argv[2]);
35673567
if( isRetry ){
35683568
fossil_print("First attempt to run \"fossil\" on %s failed\n"
35693569
"Retry: ", zRemote);
3570
- }
3570
+ }
35713571
fossil_print("%s\n", blob_str(&ssh));
35723572
sshIn = popen(blob_str(&ssh), "r");
35733573
if( sshIn==0 ){
35743574
fossil_fatal("unable to %s", blob_str(&ssh));
35753575
}
35763576
--- src/main.c
+++ src/main.c
@@ -1810,22 +1810,22 @@
1810 }
1811
1812
1813 /* Restrictions on the URI for security:
1814 **
1815 ** 1. Reject characters that are not ASCII alphanumerics,
1816 ** "-", "_", ".", "/", or unicode (above ASCII).
1817 ** In other words: No ASCII punctuation or control characters
1818 ** other than "-", "_", "." and "/".
1819 ** 2. Exception to rule 1: Allow /X:/ where X is any ASCII
1820 ** alphabetic character at the beginning of the name on windows.
1821 ** 3. "-" may not occur immediately after "/"
1822 ** 4. "." may not be adjacent to another "." or to "/"
1823 **
1824 ** Any character does not satisfy these constraints a Not Found
1825 ** error is returned.
1826 */
1827 szFile = 0;
1828 for(j=nBase+1, k=0; zRepo[j] && k<i-1; j++, k++){
1829 char c = zRepo[j];
1830 if( c>='a' && c<='z' ) continue;
1831 if( c>='A' && c<='Z' ) continue;
@@ -3526,11 +3526,11 @@
3526 ** "fossil ui --nobrowser" on the remote system and to set up a
3527 ** tunnel from the local machine to the remote. */
3528 FILE *sshIn;
3529 Blob ssh;
3530 int bRunning = 0; /* True when fossil starts up on the remote */
3531 int isRetry; /* True if on the second attempt */
3532 char zLine[1000];
3533
3534 blob_init(&ssh, 0, 0);
3535 for(isRetry=0; isRetry<2 && !bRunning; isRetry++){
3536 blob_reset(&ssh);
@@ -3565,11 +3565,11 @@
3565 if( fCreate ) blob_appendf(&ssh, " --create");
3566 blob_appendf(&ssh, " %$", g.argv[2]);
3567 if( isRetry ){
3568 fossil_print("First attempt to run \"fossil\" on %s failed\n"
3569 "Retry: ", zRemote);
3570 }
3571 fossil_print("%s\n", blob_str(&ssh));
3572 sshIn = popen(blob_str(&ssh), "r");
3573 if( sshIn==0 ){
3574 fossil_fatal("unable to %s", blob_str(&ssh));
3575 }
3576
--- src/main.c
+++ src/main.c
@@ -1810,22 +1810,22 @@
1810 }
1811
1812
1813 /* Restrictions on the URI for security:
1814 **
1815 ** 1. Reject characters that are not ASCII alphanumerics,
1816 ** "-", "_", ".", "/", or unicode (above ASCII).
1817 ** In other words: No ASCII punctuation or control characters
1818 ** other than "-", "_", "." and "/".
1819 ** 2. Exception to rule 1: Allow /X:/ where X is any ASCII
1820 ** alphabetic character at the beginning of the name on windows.
1821 ** 3. "-" may not occur immediately after "/"
1822 ** 4. "." may not be adjacent to another "." or to "/"
1823 **
1824 ** Any character does not satisfy these constraints a Not Found
1825 ** error is returned.
1826 */
1827 szFile = 0;
1828 for(j=nBase+1, k=0; zRepo[j] && k<i-1; j++, k++){
1829 char c = zRepo[j];
1830 if( c>='a' && c<='z' ) continue;
1831 if( c>='A' && c<='Z' ) continue;
@@ -3526,11 +3526,11 @@
3526 ** "fossil ui --nobrowser" on the remote system and to set up a
3527 ** tunnel from the local machine to the remote. */
3528 FILE *sshIn;
3529 Blob ssh;
3530 int bRunning = 0; /* True when fossil starts up on the remote */
3531 int isRetry; /* True if on the second attempt */
3532 char zLine[1000];
3533
3534 blob_init(&ssh, 0, 0);
3535 for(isRetry=0; isRetry<2 && !bRunning; isRetry++){
3536 blob_reset(&ssh);
@@ -3565,11 +3565,11 @@
3565 if( fCreate ) blob_appendf(&ssh, " --create");
3566 blob_appendf(&ssh, " %$", g.argv[2]);
3567 if( isRetry ){
3568 fossil_print("First attempt to run \"fossil\" on %s failed\n"
3569 "Retry: ", zRemote);
3570 }
3571 fossil_print("%s\n", blob_str(&ssh));
3572 sshIn = popen(blob_str(&ssh), "r");
3573 if( sshIn==0 ){
3574 fossil_fatal("unable to %s", blob_str(&ssh));
3575 }
3576
+5 -10
--- src/xfer.c
+++ src/xfer.c
@@ -879,15 +879,13 @@
879879
zCap = db_column_text(&q, 1);
880880
login_set_capabilities(zCap, 0);
881881
g.userUid = db_column_int(&q, 2);
882882
g.zLogin = mprintf("%b", pLogin);
883883
g.zNonce = mprintf("%b", pNonce);
884
- if( g.perm.Debug ){
885
- @ message g.zLogin=%F(g.zLogin)\szCap=%F(zCap)
886
- }
887884
}
888885
}
886
+ @ message login\src=%d(rc)\sas\s%F(g.zLogin)
889887
db_finalize(&q);
890888
return rc;
891889
}
892890
893891
/*
@@ -1321,19 +1319,20 @@
13211319
pzUuidList = &zUuidList;
13221320
pnUuidList = &nUuidList;
13231321
}
13241322
if( g.syncInfo.zLoginCard ){
13251323
/* Login card received via HTTP header X-Fossil-Xfer-Login */
1324
+ assert( g.syncInfo.bLoginCardHeader && "Set via HTTP header parser" );
1325
+ @ message got\slogin\scard\sheader:\s%F(g.syncInfo.zLoginCard)
13261326
blob_zero(&xfer.line);
13271327
blob_append(&xfer.line, g.syncInfo.zLoginCard, -1);
13281328
xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken,
13291329
count(xfer.aToken));
13301330
fossil_free( g.syncInfo.zLoginCard );
13311331
g.syncInfo.zLoginCard = 0;
13321332
if( xfer.nToken==4
13331333
&& blob_eq(&xfer.aToken[0], "login") ){
1334
- @ message got\slogin\scard\sheader
13351334
goto handle_login_card;
13361335
}
13371336
}
13381337
while( blob_line(xfer.pIn, &xfer.line) ){
13391338
if( blob_buffer(&xfer.line)[0]=='#' ) continue;
@@ -1683,11 +1682,10 @@
16831682
server_private_xfer_not_authorized();
16841683
}else{
16851684
xfer.nextIsPrivate = 1;
16861685
}
16871686
}else
1688
-
16891687
16901688
/* pragma NAME VALUE...
16911689
**
16921690
** The client issues pragmas to try to influence the behavior of the
16931691
** server. These are requests only. Unknown pragmas are silently
@@ -2382,11 +2380,11 @@
23822380
** messages unique so that that the login-card nonce will always
23832381
** be unique.
23842382
*/
23852383
zRandomness = db_text(0, "SELECT hex(randomblob(20))");
23862384
blob_appendf(&send, "# %s\n", zRandomness);
2387
- free(zRandomness);
2385
+ fossil_free(zRandomness);
23882386
23892387
if( (syncFlags & SYNC_VERBOSE)!=0
23902388
&& (syncFlags & SYNC_XVERBOSE)==0
23912389
){
23922390
fossil_print("waiting for server...");
@@ -2759,13 +2757,10 @@
27592757
27602758
/* message MESSAGE
27612759
**
27622760
** A message is received from the server. Print it.
27632761
** Similar to "error" but does not stop processing.
2764
- **
2765
- ** If the "login failed" message is seen, clear the sync password prior
2766
- ** to the next cycle.
27672762
*/
27682763
if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){
27692764
char *zMsg = blob_terminate(&xfer.aToken[1]);
27702765
defossilize(zMsg);
27712766
if( (syncFlags & SYNC_PUSH) && zMsg
@@ -2999,11 +2994,11 @@
29992994
}else{
30002995
manifest_crosslink_end(MC_PERMIT_HOOKS);
30012996
content_enable_dephantomize(1);
30022997
}
30032998
db_end_transaction(0);
3004
- };
2999
+ }; /* while(go) */
30053000
transport_stats(&nSent, &nRcvd, 1);
30063001
if( pnRcvd ) *pnRcvd = nArtifactRcvd;
30073002
if( (rSkew*24.0*3600.0) > 10.0 ){
30083003
fossil_warning("*** time skew *** server is fast by %s",
30093004
db_timespan_name(rSkew));
30103005
--- src/xfer.c
+++ src/xfer.c
@@ -879,15 +879,13 @@
879 zCap = db_column_text(&q, 1);
880 login_set_capabilities(zCap, 0);
881 g.userUid = db_column_int(&q, 2);
882 g.zLogin = mprintf("%b", pLogin);
883 g.zNonce = mprintf("%b", pNonce);
884 if( g.perm.Debug ){
885 @ message g.zLogin=%F(g.zLogin)\szCap=%F(zCap)
886 }
887 }
888 }
 
889 db_finalize(&q);
890 return rc;
891 }
892
893 /*
@@ -1321,19 +1319,20 @@
1321 pzUuidList = &zUuidList;
1322 pnUuidList = &nUuidList;
1323 }
1324 if( g.syncInfo.zLoginCard ){
1325 /* Login card received via HTTP header X-Fossil-Xfer-Login */
 
 
1326 blob_zero(&xfer.line);
1327 blob_append(&xfer.line, g.syncInfo.zLoginCard, -1);
1328 xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken,
1329 count(xfer.aToken));
1330 fossil_free( g.syncInfo.zLoginCard );
1331 g.syncInfo.zLoginCard = 0;
1332 if( xfer.nToken==4
1333 && blob_eq(&xfer.aToken[0], "login") ){
1334 @ message got\slogin\scard\sheader
1335 goto handle_login_card;
1336 }
1337 }
1338 while( blob_line(xfer.pIn, &xfer.line) ){
1339 if( blob_buffer(&xfer.line)[0]=='#' ) continue;
@@ -1683,11 +1682,10 @@
1683 server_private_xfer_not_authorized();
1684 }else{
1685 xfer.nextIsPrivate = 1;
1686 }
1687 }else
1688
1689
1690 /* pragma NAME VALUE...
1691 **
1692 ** The client issues pragmas to try to influence the behavior of the
1693 ** server. These are requests only. Unknown pragmas are silently
@@ -2382,11 +2380,11 @@
2382 ** messages unique so that that the login-card nonce will always
2383 ** be unique.
2384 */
2385 zRandomness = db_text(0, "SELECT hex(randomblob(20))");
2386 blob_appendf(&send, "# %s\n", zRandomness);
2387 free(zRandomness);
2388
2389 if( (syncFlags & SYNC_VERBOSE)!=0
2390 && (syncFlags & SYNC_XVERBOSE)==0
2391 ){
2392 fossil_print("waiting for server...");
@@ -2759,13 +2757,10 @@
2759
2760 /* message MESSAGE
2761 **
2762 ** A message is received from the server. Print it.
2763 ** Similar to "error" but does not stop processing.
2764 **
2765 ** If the "login failed" message is seen, clear the sync password prior
2766 ** to the next cycle.
2767 */
2768 if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){
2769 char *zMsg = blob_terminate(&xfer.aToken[1]);
2770 defossilize(zMsg);
2771 if( (syncFlags & SYNC_PUSH) && zMsg
@@ -2999,11 +2994,11 @@
2999 }else{
3000 manifest_crosslink_end(MC_PERMIT_HOOKS);
3001 content_enable_dephantomize(1);
3002 }
3003 db_end_transaction(0);
3004 };
3005 transport_stats(&nSent, &nRcvd, 1);
3006 if( pnRcvd ) *pnRcvd = nArtifactRcvd;
3007 if( (rSkew*24.0*3600.0) > 10.0 ){
3008 fossil_warning("*** time skew *** server is fast by %s",
3009 db_timespan_name(rSkew));
3010
--- src/xfer.c
+++ src/xfer.c
@@ -879,15 +879,13 @@
879 zCap = db_column_text(&q, 1);
880 login_set_capabilities(zCap, 0);
881 g.userUid = db_column_int(&q, 2);
882 g.zLogin = mprintf("%b", pLogin);
883 g.zNonce = mprintf("%b", pNonce);
 
 
 
884 }
885 }
886 @ message login\src=%d(rc)\sas\s%F(g.zLogin)
887 db_finalize(&q);
888 return rc;
889 }
890
891 /*
@@ -1321,19 +1319,20 @@
1319 pzUuidList = &zUuidList;
1320 pnUuidList = &nUuidList;
1321 }
1322 if( g.syncInfo.zLoginCard ){
1323 /* Login card received via HTTP header X-Fossil-Xfer-Login */
1324 assert( g.syncInfo.bLoginCardHeader && "Set via HTTP header parser" );
1325 @ message got\slogin\scard\sheader:\s%F(g.syncInfo.zLoginCard)
1326 blob_zero(&xfer.line);
1327 blob_append(&xfer.line, g.syncInfo.zLoginCard, -1);
1328 xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken,
1329 count(xfer.aToken));
1330 fossil_free( g.syncInfo.zLoginCard );
1331 g.syncInfo.zLoginCard = 0;
1332 if( xfer.nToken==4
1333 && blob_eq(&xfer.aToken[0], "login") ){
 
1334 goto handle_login_card;
1335 }
1336 }
1337 while( blob_line(xfer.pIn, &xfer.line) ){
1338 if( blob_buffer(&xfer.line)[0]=='#' ) continue;
@@ -1683,11 +1682,10 @@
1682 server_private_xfer_not_authorized();
1683 }else{
1684 xfer.nextIsPrivate = 1;
1685 }
1686 }else
 
1687
1688 /* pragma NAME VALUE...
1689 **
1690 ** The client issues pragmas to try to influence the behavior of the
1691 ** server. These are requests only. Unknown pragmas are silently
@@ -2382,11 +2380,11 @@
2380 ** messages unique so that that the login-card nonce will always
2381 ** be unique.
2382 */
2383 zRandomness = db_text(0, "SELECT hex(randomblob(20))");
2384 blob_appendf(&send, "# %s\n", zRandomness);
2385 fossil_free(zRandomness);
2386
2387 if( (syncFlags & SYNC_VERBOSE)!=0
2388 && (syncFlags & SYNC_XVERBOSE)==0
2389 ){
2390 fossil_print("waiting for server...");
@@ -2759,13 +2757,10 @@
2757
2758 /* message MESSAGE
2759 **
2760 ** A message is received from the server. Print it.
2761 ** Similar to "error" but does not stop processing.
 
 
 
2762 */
2763 if( blob_eq(&xfer.aToken[0],"message") && xfer.nToken==2 ){
2764 char *zMsg = blob_terminate(&xfer.aToken[1]);
2765 defossilize(zMsg);
2766 if( (syncFlags & SYNC_PUSH) && zMsg
@@ -2999,11 +2994,11 @@
2994 }else{
2995 manifest_crosslink_end(MC_PERMIT_HOOKS);
2996 content_enable_dephantomize(1);
2997 }
2998 db_end_transaction(0);
2999 }; /* while(go) */
3000 transport_stats(&nSent, &nRcvd, 1);
3001 if( pnRcvd ) *pnRcvd = nArtifactRcvd;
3002 if( (rSkew*24.0*3600.0) > 10.0 ){
3003 fossil_warning("*** time skew *** server is fast by %s",
3004 db_timespan_name(rSkew));
3005

Keyboard Shortcuts

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