Fossil SCM

Only add the PATH= prefix on the fossil command sent over SSH for ssh: syncs if a prior attempt to contact the remote failed to find the Fossil executable.

drh 2024-02-06 11:22 trunk merge
Commit cbf27ece6cf90c126909e33cf063ead6dae68d873b8e1f0f8b76957a7d2baf03
+44 -2
--- src/http.c
+++ src/http.c
@@ -304,10 +304,21 @@
304304
305305
if( g.zHttpCmd!=0 ){
306306
/* Handle the --transport-command option for "fossil sync" and similar */
307307
return http_exchange_external(pSend,pReply,mHttpFlags,zAltMimetype);
308308
}
309
+
310
+ /* Activate the PATH= auxiliary argument to the ssh command if that
311
+ ** is called for.
312
+ */
313
+ if( g.url.isSsh && (g.url.flags & URL_SSH_RETRY)==0 ){
314
+ char *z = mprintf("use-path-for-ssh:%s", g.url.hostname);
315
+ if( db_get_boolean(z/*works-like:"x"*/, 0) ){
316
+ g.url.flags |= URL_SSH_PATH;
317
+ }
318
+ fossil_free(z);
319
+ }
309320
310321
if( transport_open(&g.url) ){
311322
fossil_warning("%s", transport_errmsg(&g.url));
312323
return 1;
313324
}
@@ -484,12 +495,43 @@
484495
}
485496
}
486497
}
487498
}
488499
if( iLength<0 ){
489
- fossil_warning("server did not reply");
490
- goto write_err;
500
+ /* We got nothing back from the server. If using the ssh: protocol,
501
+ ** this might mean we need to add or remove the PATH=... argument
502
+ ** to the SSH command being sent. If that is the case, retry the
503
+ ** request after adding or removing the PATH= argument.
504
+ */
505
+ if( g.url.isSsh /* This is an SSH: sync */
506
+ && (g.url.flags & URL_SSH_EXE)==0 /* Does not have ?fossil=.... */
507
+ && (g.url.flags & URL_SSH_RETRY)==0 /* Not retried already */
508
+ ){
509
+ /* Retry after flipping the SSH_PATH setting */
510
+ transport_close(&g.url);
511
+ if( g.fSshTrace ){
512
+ printf("Retry after %s the PATH= argument to the SSH command\n",
513
+ (g.url.flags & URL_SSH_PATH)!=0 ? "removing" : "adding");
514
+ }
515
+ g.url.flags ^= URL_SSH_PATH|URL_SSH_RETRY;
516
+ rc = http_exchange(pSend,pReply,mHttpFlags,0,zAltMimetype);
517
+ if( rc==0 && (g.url.flags & URL_REMEMBER)!=0 ){
518
+ char *z = mprintf("use-path-for-ssh:%s", g.url.hostname);
519
+ if( (g.url.flags & URL_SSH_PATH) ){
520
+ db_set(z/*works-like:"x"*/, "1", 1);
521
+ }else{
522
+ db_unset(z/*works-like:"x"*/, 1);
523
+ }
524
+ fossil_free(z);
525
+ }
526
+ return rc;
527
+ }else{
528
+ /* The problem could not be corrected by retrying. Report the
529
+ ** the error. */
530
+ fossil_warning("server did not reply");
531
+ goto write_err;
532
+ }
491533
}
492534
if( rc!=200 ){
493535
fossil_warning("\"location:\" missing from %d redirect reply", rc);
494536
goto write_err;
495537
}
496538
--- src/http.c
+++ src/http.c
@@ -304,10 +304,21 @@
304
305 if( g.zHttpCmd!=0 ){
306 /* Handle the --transport-command option for "fossil sync" and similar */
307 return http_exchange_external(pSend,pReply,mHttpFlags,zAltMimetype);
308 }
 
 
 
 
 
 
 
 
 
 
 
309
310 if( transport_open(&g.url) ){
311 fossil_warning("%s", transport_errmsg(&g.url));
312 return 1;
313 }
@@ -484,12 +495,43 @@
484 }
485 }
486 }
487 }
488 if( iLength<0 ){
489 fossil_warning("server did not reply");
490 goto write_err;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
491 }
492 if( rc!=200 ){
493 fossil_warning("\"location:\" missing from %d redirect reply", rc);
494 goto write_err;
495 }
496
--- src/http.c
+++ src/http.c
@@ -304,10 +304,21 @@
304
305 if( g.zHttpCmd!=0 ){
306 /* Handle the --transport-command option for "fossil sync" and similar */
307 return http_exchange_external(pSend,pReply,mHttpFlags,zAltMimetype);
308 }
309
310 /* Activate the PATH= auxiliary argument to the ssh command if that
311 ** is called for.
312 */
313 if( g.url.isSsh && (g.url.flags & URL_SSH_RETRY)==0 ){
314 char *z = mprintf("use-path-for-ssh:%s", g.url.hostname);
315 if( db_get_boolean(z/*works-like:"x"*/, 0) ){
316 g.url.flags |= URL_SSH_PATH;
317 }
318 fossil_free(z);
319 }
320
321 if( transport_open(&g.url) ){
322 fossil_warning("%s", transport_errmsg(&g.url));
323 return 1;
324 }
@@ -484,12 +495,43 @@
495 }
496 }
497 }
498 }
499 if( iLength<0 ){
500 /* We got nothing back from the server. If using the ssh: protocol,
501 ** this might mean we need to add or remove the PATH=... argument
502 ** to the SSH command being sent. If that is the case, retry the
503 ** request after adding or removing the PATH= argument.
504 */
505 if( g.url.isSsh /* This is an SSH: sync */
506 && (g.url.flags & URL_SSH_EXE)==0 /* Does not have ?fossil=.... */
507 && (g.url.flags & URL_SSH_RETRY)==0 /* Not retried already */
508 ){
509 /* Retry after flipping the SSH_PATH setting */
510 transport_close(&g.url);
511 if( g.fSshTrace ){
512 printf("Retry after %s the PATH= argument to the SSH command\n",
513 (g.url.flags & URL_SSH_PATH)!=0 ? "removing" : "adding");
514 }
515 g.url.flags ^= URL_SSH_PATH|URL_SSH_RETRY;
516 rc = http_exchange(pSend,pReply,mHttpFlags,0,zAltMimetype);
517 if( rc==0 && (g.url.flags & URL_REMEMBER)!=0 ){
518 char *z = mprintf("use-path-for-ssh:%s", g.url.hostname);
519 if( (g.url.flags & URL_SSH_PATH) ){
520 db_set(z/*works-like:"x"*/, "1", 1);
521 }else{
522 db_unset(z/*works-like:"x"*/, 1);
523 }
524 fossil_free(z);
525 }
526 return rc;
527 }else{
528 /* The problem could not be corrected by retrying. Report the
529 ** the error. */
530 fossil_warning("server did not reply");
531 goto write_err;
532 }
533 }
534 if( rc!=200 ){
535 fossil_warning("\"location:\" missing from %d redirect reply", rc);
536 goto write_err;
537 }
538
--- src/http_transport.c
+++ src/http_transport.c
@@ -131,15 +131,22 @@
131131
blob_append_escaped_arg(&zCmd, zHost, 0);
132132
fossil_free(zHost);
133133
}else{
134134
blob_append_escaped_arg(&zCmd, pUrlData->name, 0);
135135
}
136
- if( !is_safe_fossil_command(pUrlData->fossil) ){
136
+ if( (pUrlData->flags & URL_SSH_EXE)!=0
137
+ && !is_safe_fossil_command(pUrlData->fossil)
138
+ ){
137139
fossil_fatal("the ssh:// URL is asking to run an unsafe command [%s] on "
138140
"the server.", pUrlData->fossil);
139141
}
140
- blob_append_escaped_arg(&zCmd, "PATH=$HOME/bin:$PATH", 1);
142
+ if( (pUrlData->flags & URL_SSH_EXE)==0
143
+ && (pUrlData->flags & URL_SSH_PATH)!=0
144
+ ){
145
+ blob_append_escaped_arg(&zCmd,
146
+ "PATH=bin:/usr/local/bin:/opt/homebrew/bin:$PATH", 1);
147
+ }
141148
blob_append_escaped_arg(&zCmd, pUrlData->fossil, 1);
142149
blob_append(&zCmd, " test-http", 10);
143150
if( pUrlData->path && pUrlData->path[0] ){
144151
blob_append_escaped_arg(&zCmd, pUrlData->path, 1);
145152
}else{
@@ -313,11 +320,11 @@
313320
** Read N bytes of content directly from the wire and write into
314321
** the buffer.
315322
*/
316323
static int transport_fetch(UrlData *pUrlData, char *zBuf, int N){
317324
int got;
318
- if( sshIn ){
325
+ if( pUrlData->isSsh ){
319326
int x;
320327
int wanted = N;
321328
got = 0;
322329
while( wanted>0 ){
323330
x = read(sshIn, &zBuf[got], wanted);
324331
--- src/http_transport.c
+++ src/http_transport.c
@@ -131,15 +131,22 @@
131 blob_append_escaped_arg(&zCmd, zHost, 0);
132 fossil_free(zHost);
133 }else{
134 blob_append_escaped_arg(&zCmd, pUrlData->name, 0);
135 }
136 if( !is_safe_fossil_command(pUrlData->fossil) ){
 
 
137 fossil_fatal("the ssh:// URL is asking to run an unsafe command [%s] on "
138 "the server.", pUrlData->fossil);
139 }
140 blob_append_escaped_arg(&zCmd, "PATH=$HOME/bin:$PATH", 1);
 
 
 
 
 
141 blob_append_escaped_arg(&zCmd, pUrlData->fossil, 1);
142 blob_append(&zCmd, " test-http", 10);
143 if( pUrlData->path && pUrlData->path[0] ){
144 blob_append_escaped_arg(&zCmd, pUrlData->path, 1);
145 }else{
@@ -313,11 +320,11 @@
313 ** Read N bytes of content directly from the wire and write into
314 ** the buffer.
315 */
316 static int transport_fetch(UrlData *pUrlData, char *zBuf, int N){
317 int got;
318 if( sshIn ){
319 int x;
320 int wanted = N;
321 got = 0;
322 while( wanted>0 ){
323 x = read(sshIn, &zBuf[got], wanted);
324
--- src/http_transport.c
+++ src/http_transport.c
@@ -131,15 +131,22 @@
131 blob_append_escaped_arg(&zCmd, zHost, 0);
132 fossil_free(zHost);
133 }else{
134 blob_append_escaped_arg(&zCmd, pUrlData->name, 0);
135 }
136 if( (pUrlData->flags & URL_SSH_EXE)!=0
137 && !is_safe_fossil_command(pUrlData->fossil)
138 ){
139 fossil_fatal("the ssh:// URL is asking to run an unsafe command [%s] on "
140 "the server.", pUrlData->fossil);
141 }
142 if( (pUrlData->flags & URL_SSH_EXE)==0
143 && (pUrlData->flags & URL_SSH_PATH)!=0
144 ){
145 blob_append_escaped_arg(&zCmd,
146 "PATH=bin:/usr/local/bin:/opt/homebrew/bin:$PATH", 1);
147 }
148 blob_append_escaped_arg(&zCmd, pUrlData->fossil, 1);
149 blob_append(&zCmd, " test-http", 10);
150 if( pUrlData->path && pUrlData->path[0] ){
151 blob_append_escaped_arg(&zCmd, pUrlData->path, 1);
152 }else{
@@ -313,11 +320,11 @@
320 ** Read N bytes of content directly from the wire and write into
321 ** the buffer.
322 */
323 static int transport_fetch(UrlData *pUrlData, char *zBuf, int N){
324 int got;
325 if( pUrlData->isSsh ){
326 int x;
327 int wanted = N;
328 got = 0;
329 while( wanted>0 ){
330 x = read(sshIn, &zBuf[got], wanted);
331
--- src/popen.c
+++ src/popen.c
@@ -194,10 +194,11 @@
194194
close(1);
195195
fd = dup(pin[1]);
196196
if( fd!=1 ) fossil_panic("popen() failed to open file descriptor 1");
197197
close(pin[0]);
198198
close(pin[1]);
199
+ close(2); dup(1); /* Redirect stderr into the stdout pipe */
199200
if( bDirect ){
200201
execl(zCmd, zCmd, (char*)0);
201202
}else{
202203
execl("/bin/sh", "/bin/sh", "-c", zCmd, (char*)0);
203204
}
204205
--- src/popen.c
+++ src/popen.c
@@ -194,10 +194,11 @@
194 close(1);
195 fd = dup(pin[1]);
196 if( fd!=1 ) fossil_panic("popen() failed to open file descriptor 1");
197 close(pin[0]);
198 close(pin[1]);
 
199 if( bDirect ){
200 execl(zCmd, zCmd, (char*)0);
201 }else{
202 execl("/bin/sh", "/bin/sh", "-c", zCmd, (char*)0);
203 }
204
--- src/popen.c
+++ src/popen.c
@@ -194,10 +194,11 @@
194 close(1);
195 fd = dup(pin[1]);
196 if( fd!=1 ) fossil_panic("popen() failed to open file descriptor 1");
197 close(pin[0]);
198 close(pin[1]);
199 close(2); dup(1); /* Redirect stderr into the stdout pipe */
200 if( bDirect ){
201 execl(zCmd, zCmd, (char*)0);
202 }else{
203 execl("/bin/sh", "/bin/sh", "-c", zCmd, (char*)0);
204 }
205
+41 -31
--- src/url.c
+++ src/url.c
@@ -33,18 +33,21 @@
3333
3434
#if INTERFACE
3535
/*
3636
** Flags for url_parse()
3737
*/
38
-#define URL_PROMPT_PW 0x001 /* Prompt for password if needed */
39
-#define URL_REMEMBER 0x002 /* Remember the url for later reuse */
40
-#define URL_ASK_REMEMBER_PW 0x004 /* Ask whether to remember prompted pw */
41
-#define URL_REMEMBER_PW 0x008 /* Should remember pw */
42
-#define URL_PROMPTED 0x010 /* Prompted for PW already */
43
-#define URL_OMIT_USER 0x020 /* Omit the user name from URL */
44
-#define URL_USE_CONFIG 0x040 /* Use remembered URLs from CONFIG table */
45
-#define URL_USE_PARENT 0x080 /* Use the URL of the parent project */
38
+#define URL_PROMPT_PW 0x0001 /* Prompt for password if needed */
39
+#define URL_REMEMBER 0x0002 /* Remember the url for later reuse */
40
+#define URL_ASK_REMEMBER_PW 0x0004 /* Ask whether to remember prompted pw */
41
+#define URL_REMEMBER_PW 0x0008 /* Should remember pw */
42
+#define URL_PROMPTED 0x0010 /* Prompted for PW already */
43
+#define URL_OMIT_USER 0x0020 /* Omit the user name from URL */
44
+#define URL_USE_CONFIG 0x0040 /* Use remembered URLs from CONFIG table */
45
+#define URL_USE_PARENT 0x0080 /* Use the URL of the parent project */
46
+#define URL_SSH_PATH 0x0100 /* Include PATH= on SSH syncs */
47
+#define URL_SSH_RETRY 0x0200 /* This a retry of an SSH */
48
+#define URL_SSH_EXE 0x0400 /* ssh: URL contains fossil= query param*/
4649
4750
/*
4851
** The URL related data used with this subsystem.
4952
*/
5053
struct UrlData {
@@ -110,11 +113,11 @@
110113
UrlData *pUrlData
111114
){
112115
int i, j, c;
113116
char *zFile = 0;
114117
115
- pUrlData->pwConfig = 0;
118
+ memset(pUrlData, 0, sizeof(*pUrlData));
116119
if( urlFlags & URL_USE_CONFIG ){
117120
if( zUrl==0 || strcmp(zUrl,"default")==0 ){
118121
const char *zPwConfig = "last-sync-pw";
119122
if( urlFlags & URL_USE_PARENT ){
120123
zUrl = db_get("parent-project-url", 0);
@@ -159,12 +162,10 @@
159162
int iStart;
160163
char *zLogin;
161164
char *zExe;
162165
char cQuerySep = '?';
163166
164
- pUrlData->isFile = 0;
165
- pUrlData->useProxy = 0;
166167
if( zUrl[4]=='s' ){
167168
pUrlData->isHttps = 1;
168169
pUrlData->protocol = "https";
169170
pUrlData->dfltPort = 443;
170171
iStart = 8;
@@ -255,15 +256,17 @@
255256
if( pUrlData->path[i] ){
256257
pUrlData->path[i] = 0;
257258
i++;
258259
}
259260
if( fossil_strcmp(zName,"fossil")==0 ){
261
+ fossil_free(pUrlData->fossil);
260262
pUrlData->fossil = fossil_strdup(zValue);
261263
dehttpize(pUrlData->fossil);
262264
fossil_free(zExe);
263265
zExe = mprintf("%cfossil=%T", cQuerySep, pUrlData->fossil);
264266
cQuerySep = '&';
267
+ urlFlags |= URL_SSH_EXE;
265268
}
266269
}
267270
268271
dehttpize(pUrlData->path);
269272
if( pUrlData->dfltPort==pUrlData->port ){
@@ -453,10 +456,36 @@
453456
** g.url.pwConfig is NULL.
454457
*/
455458
void url_parse(const char *zUrl, unsigned int urlFlags){
456459
url_parse_local(zUrl, urlFlags, &g.url);
457460
}
461
+
462
+/*
463
+** Print the content of g.url
464
+*/
465
+void urlparse_print(int showPw){
466
+ fossil_print("g.url.isFile = %d\n", g.url.isFile);
467
+ fossil_print("g.url.isHttps = %d\n", g.url.isHttps);
468
+ fossil_print("g.url.isSsh = %d\n", g.url.isSsh);
469
+ fossil_print("g.url.protocol = %s\n", g.url.protocol);
470
+ fossil_print("g.url.name = %s\n", g.url.name);
471
+ fossil_print("g.url.port = %d\n", g.url.port);
472
+ fossil_print("g.url.dfltPort = %d\n", g.url.dfltPort);
473
+ fossil_print("g.url.hostname = %s\n", g.url.hostname);
474
+ fossil_print("g.url.path = %s\n", g.url.path);
475
+ fossil_print("g.url.user = %s\n", g.url.user);
476
+ if( showPw || g.url.pwConfig==0 ){
477
+ fossil_print("g.url.passwd = %s\n", g.url.passwd);
478
+ }else{
479
+ fossil_print("g.url.passwd = ************\n");
480
+ }
481
+ fossil_print("g.url.pwConfig = %s\n", g.url.pwConfig);
482
+ fossil_print("g.url.canonical = %s\n", g.url.canonical);
483
+ fossil_print("g.url.fossil = %s\n", g.url.fossil);
484
+ fossil_print("g.url.flags = 0x%04x\n", g.url.flags);
485
+ fossil_print("url_full(g.url) = %z\n", url_full(&g.url));
486
+}
458487
459488
/*
460489
** COMMAND: test-urlparser
461490
**
462491
** Usage: %fossil test-urlparser URL ?options?
@@ -482,30 +511,11 @@
482511
if( g.argc!=3 && g.argc!=4 ){
483512
usage("URL");
484513
}
485514
url_parse(g.argv[2], fg);
486515
for(i=0; i<2; i++){
487
- fossil_print("g.url.isFile = %d\n", g.url.isFile);
488
- fossil_print("g.url.isHttps = %d\n", g.url.isHttps);
489
- fossil_print("g.url.isSsh = %d\n", g.url.isSsh);
490
- fossil_print("g.url.protocol = %s\n", g.url.protocol);
491
- fossil_print("g.url.name = %s\n", g.url.name);
492
- fossil_print("g.url.port = %d\n", g.url.port);
493
- fossil_print("g.url.dfltPort = %d\n", g.url.dfltPort);
494
- fossil_print("g.url.hostname = %s\n", g.url.hostname);
495
- fossil_print("g.url.path = %s\n", g.url.path);
496
- fossil_print("g.url.user = %s\n", g.url.user);
497
- if( showPw || g.url.pwConfig==0 ){
498
- fossil_print("g.url.passwd = %s\n", g.url.passwd);
499
- }else{
500
- fossil_print("g.url.passwd = ************\n");
501
- }
502
- fossil_print("g.url.pwConfig = %s\n", g.url.pwConfig);
503
- fossil_print("g.url.canonical = %s\n", g.url.canonical);
504
- fossil_print("g.url.fossil = %s\n", g.url.fossil);
505
- fossil_print("g.url.flags = 0x%02x\n", g.url.flags);
506
- fossil_print("url_full(g.url) = %z\n", url_full(&g.url));
516
+ urlparse_print(showPw);
507517
if( g.url.isFile || g.url.isSsh ) break;
508518
if( i==0 ){
509519
fossil_print("********\n");
510520
url_enable_proxy("Using proxy: ");
511521
}
512522
--- src/url.c
+++ src/url.c
@@ -33,18 +33,21 @@
33
34 #if INTERFACE
35 /*
36 ** Flags for url_parse()
37 */
38 #define URL_PROMPT_PW 0x001 /* Prompt for password if needed */
39 #define URL_REMEMBER 0x002 /* Remember the url for later reuse */
40 #define URL_ASK_REMEMBER_PW 0x004 /* Ask whether to remember prompted pw */
41 #define URL_REMEMBER_PW 0x008 /* Should remember pw */
42 #define URL_PROMPTED 0x010 /* Prompted for PW already */
43 #define URL_OMIT_USER 0x020 /* Omit the user name from URL */
44 #define URL_USE_CONFIG 0x040 /* Use remembered URLs from CONFIG table */
45 #define URL_USE_PARENT 0x080 /* Use the URL of the parent project */
 
 
 
46
47 /*
48 ** The URL related data used with this subsystem.
49 */
50 struct UrlData {
@@ -110,11 +113,11 @@
110 UrlData *pUrlData
111 ){
112 int i, j, c;
113 char *zFile = 0;
114
115 pUrlData->pwConfig = 0;
116 if( urlFlags & URL_USE_CONFIG ){
117 if( zUrl==0 || strcmp(zUrl,"default")==0 ){
118 const char *zPwConfig = "last-sync-pw";
119 if( urlFlags & URL_USE_PARENT ){
120 zUrl = db_get("parent-project-url", 0);
@@ -159,12 +162,10 @@
159 int iStart;
160 char *zLogin;
161 char *zExe;
162 char cQuerySep = '?';
163
164 pUrlData->isFile = 0;
165 pUrlData->useProxy = 0;
166 if( zUrl[4]=='s' ){
167 pUrlData->isHttps = 1;
168 pUrlData->protocol = "https";
169 pUrlData->dfltPort = 443;
170 iStart = 8;
@@ -255,15 +256,17 @@
255 if( pUrlData->path[i] ){
256 pUrlData->path[i] = 0;
257 i++;
258 }
259 if( fossil_strcmp(zName,"fossil")==0 ){
 
260 pUrlData->fossil = fossil_strdup(zValue);
261 dehttpize(pUrlData->fossil);
262 fossil_free(zExe);
263 zExe = mprintf("%cfossil=%T", cQuerySep, pUrlData->fossil);
264 cQuerySep = '&';
 
265 }
266 }
267
268 dehttpize(pUrlData->path);
269 if( pUrlData->dfltPort==pUrlData->port ){
@@ -453,10 +456,36 @@
453 ** g.url.pwConfig is NULL.
454 */
455 void url_parse(const char *zUrl, unsigned int urlFlags){
456 url_parse_local(zUrl, urlFlags, &g.url);
457 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
458
459 /*
460 ** COMMAND: test-urlparser
461 **
462 ** Usage: %fossil test-urlparser URL ?options?
@@ -482,30 +511,11 @@
482 if( g.argc!=3 && g.argc!=4 ){
483 usage("URL");
484 }
485 url_parse(g.argv[2], fg);
486 for(i=0; i<2; i++){
487 fossil_print("g.url.isFile = %d\n", g.url.isFile);
488 fossil_print("g.url.isHttps = %d\n", g.url.isHttps);
489 fossil_print("g.url.isSsh = %d\n", g.url.isSsh);
490 fossil_print("g.url.protocol = %s\n", g.url.protocol);
491 fossil_print("g.url.name = %s\n", g.url.name);
492 fossil_print("g.url.port = %d\n", g.url.port);
493 fossil_print("g.url.dfltPort = %d\n", g.url.dfltPort);
494 fossil_print("g.url.hostname = %s\n", g.url.hostname);
495 fossil_print("g.url.path = %s\n", g.url.path);
496 fossil_print("g.url.user = %s\n", g.url.user);
497 if( showPw || g.url.pwConfig==0 ){
498 fossil_print("g.url.passwd = %s\n", g.url.passwd);
499 }else{
500 fossil_print("g.url.passwd = ************\n");
501 }
502 fossil_print("g.url.pwConfig = %s\n", g.url.pwConfig);
503 fossil_print("g.url.canonical = %s\n", g.url.canonical);
504 fossil_print("g.url.fossil = %s\n", g.url.fossil);
505 fossil_print("g.url.flags = 0x%02x\n", g.url.flags);
506 fossil_print("url_full(g.url) = %z\n", url_full(&g.url));
507 if( g.url.isFile || g.url.isSsh ) break;
508 if( i==0 ){
509 fossil_print("********\n");
510 url_enable_proxy("Using proxy: ");
511 }
512
--- src/url.c
+++ src/url.c
@@ -33,18 +33,21 @@
33
34 #if INTERFACE
35 /*
36 ** Flags for url_parse()
37 */
38 #define URL_PROMPT_PW 0x0001 /* Prompt for password if needed */
39 #define URL_REMEMBER 0x0002 /* Remember the url for later reuse */
40 #define URL_ASK_REMEMBER_PW 0x0004 /* Ask whether to remember prompted pw */
41 #define URL_REMEMBER_PW 0x0008 /* Should remember pw */
42 #define URL_PROMPTED 0x0010 /* Prompted for PW already */
43 #define URL_OMIT_USER 0x0020 /* Omit the user name from URL */
44 #define URL_USE_CONFIG 0x0040 /* Use remembered URLs from CONFIG table */
45 #define URL_USE_PARENT 0x0080 /* Use the URL of the parent project */
46 #define URL_SSH_PATH 0x0100 /* Include PATH= on SSH syncs */
47 #define URL_SSH_RETRY 0x0200 /* This a retry of an SSH */
48 #define URL_SSH_EXE 0x0400 /* ssh: URL contains fossil= query param*/
49
50 /*
51 ** The URL related data used with this subsystem.
52 */
53 struct UrlData {
@@ -110,11 +113,11 @@
113 UrlData *pUrlData
114 ){
115 int i, j, c;
116 char *zFile = 0;
117
118 memset(pUrlData, 0, sizeof(*pUrlData));
119 if( urlFlags & URL_USE_CONFIG ){
120 if( zUrl==0 || strcmp(zUrl,"default")==0 ){
121 const char *zPwConfig = "last-sync-pw";
122 if( urlFlags & URL_USE_PARENT ){
123 zUrl = db_get("parent-project-url", 0);
@@ -159,12 +162,10 @@
162 int iStart;
163 char *zLogin;
164 char *zExe;
165 char cQuerySep = '?';
166
 
 
167 if( zUrl[4]=='s' ){
168 pUrlData->isHttps = 1;
169 pUrlData->protocol = "https";
170 pUrlData->dfltPort = 443;
171 iStart = 8;
@@ -255,15 +256,17 @@
256 if( pUrlData->path[i] ){
257 pUrlData->path[i] = 0;
258 i++;
259 }
260 if( fossil_strcmp(zName,"fossil")==0 ){
261 fossil_free(pUrlData->fossil);
262 pUrlData->fossil = fossil_strdup(zValue);
263 dehttpize(pUrlData->fossil);
264 fossil_free(zExe);
265 zExe = mprintf("%cfossil=%T", cQuerySep, pUrlData->fossil);
266 cQuerySep = '&';
267 urlFlags |= URL_SSH_EXE;
268 }
269 }
270
271 dehttpize(pUrlData->path);
272 if( pUrlData->dfltPort==pUrlData->port ){
@@ -453,10 +456,36 @@
456 ** g.url.pwConfig is NULL.
457 */
458 void url_parse(const char *zUrl, unsigned int urlFlags){
459 url_parse_local(zUrl, urlFlags, &g.url);
460 }
461
462 /*
463 ** Print the content of g.url
464 */
465 void urlparse_print(int showPw){
466 fossil_print("g.url.isFile = %d\n", g.url.isFile);
467 fossil_print("g.url.isHttps = %d\n", g.url.isHttps);
468 fossil_print("g.url.isSsh = %d\n", g.url.isSsh);
469 fossil_print("g.url.protocol = %s\n", g.url.protocol);
470 fossil_print("g.url.name = %s\n", g.url.name);
471 fossil_print("g.url.port = %d\n", g.url.port);
472 fossil_print("g.url.dfltPort = %d\n", g.url.dfltPort);
473 fossil_print("g.url.hostname = %s\n", g.url.hostname);
474 fossil_print("g.url.path = %s\n", g.url.path);
475 fossil_print("g.url.user = %s\n", g.url.user);
476 if( showPw || g.url.pwConfig==0 ){
477 fossil_print("g.url.passwd = %s\n", g.url.passwd);
478 }else{
479 fossil_print("g.url.passwd = ************\n");
480 }
481 fossil_print("g.url.pwConfig = %s\n", g.url.pwConfig);
482 fossil_print("g.url.canonical = %s\n", g.url.canonical);
483 fossil_print("g.url.fossil = %s\n", g.url.fossil);
484 fossil_print("g.url.flags = 0x%04x\n", g.url.flags);
485 fossil_print("url_full(g.url) = %z\n", url_full(&g.url));
486 }
487
488 /*
489 ** COMMAND: test-urlparser
490 **
491 ** Usage: %fossil test-urlparser URL ?options?
@@ -482,30 +511,11 @@
511 if( g.argc!=3 && g.argc!=4 ){
512 usage("URL");
513 }
514 url_parse(g.argv[2], fg);
515 for(i=0; i<2; i++){
516 urlparse_print(showPw);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
517 if( g.url.isFile || g.url.isSsh ) break;
518 if( i==0 ){
519 fossil_print("********\n");
520 url_enable_proxy("Using proxy: ");
521 }
522

Keyboard Shortcuts

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