Fossil SCM

Merge in fixes for the password embedded in the URL, save password prompting, and new clone --once option.

andybradford 2013-11-12 02:41 trunk merge
Commit ff159bfdd76da13ee669002da9d9d1801a9cd6fd
+4 -1
--- src/clone.c
+++ src/clone.c
@@ -105,10 +105,11 @@
105105
** admin user. This can be overridden using the -A|--admin-user
106106
** parameter.
107107
**
108108
** Options:
109109
** --admin-user|-A USERNAME Make USERNAME the administrator
110
+** --once Don't save url.
110111
** --private Also clone private branches
111112
** --ssl-identity=filename Use the SSL identity if requested by the server
112113
** --ssh-command|-c 'command' Use this SSH command
113114
**
114115
** See also: init
@@ -116,12 +117,14 @@
116117
void clone_cmd(void){
117118
char *zPassword;
118119
const char *zDefaultUser; /* Optional name of the default user */
119120
int nErr = 0;
120121
int bPrivate = 0; /* Also clone private branches */
122
+ int urlFlags = URL_PROMPT_PW | URL_REMEMBER;
121123
122124
if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE;
125
+ if( find_option("once",0,0)!=0) urlFlags &= ~URL_REMEMBER;
123126
clone_ssh_find_options();
124127
url_proxy_options();
125128
if( g.argc < 4 ){
126129
usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY");
127130
}
@@ -130,11 +133,11 @@
130133
fossil_fatal("file already exists: %s", g.argv[3]);
131134
}
132135
133136
zDefaultUser = find_option("admin-user","A",1);
134137
135
- url_parse(g.argv[2], URL_PROMPT_PW|URL_ASK_REMEMBER_PW);
138
+ url_parse(g.argv[2], urlFlags);
136139
if( zDefaultUser==0 && g.urlUser!=0 ) zDefaultUser = g.urlUser;
137140
if( g.urlIsFile ){
138141
file_copy(g.urlName, g.argv[3]);
139142
db_close(1);
140143
db_open_repository(g.argv[3]);
141144
--- src/clone.c
+++ src/clone.c
@@ -105,10 +105,11 @@
105 ** admin user. This can be overridden using the -A|--admin-user
106 ** parameter.
107 **
108 ** Options:
109 ** --admin-user|-A USERNAME Make USERNAME the administrator
 
110 ** --private Also clone private branches
111 ** --ssl-identity=filename Use the SSL identity if requested by the server
112 ** --ssh-command|-c 'command' Use this SSH command
113 **
114 ** See also: init
@@ -116,12 +117,14 @@
116 void clone_cmd(void){
117 char *zPassword;
118 const char *zDefaultUser; /* Optional name of the default user */
119 int nErr = 0;
120 int bPrivate = 0; /* Also clone private branches */
 
121
122 if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE;
 
123 clone_ssh_find_options();
124 url_proxy_options();
125 if( g.argc < 4 ){
126 usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY");
127 }
@@ -130,11 +133,11 @@
130 fossil_fatal("file already exists: %s", g.argv[3]);
131 }
132
133 zDefaultUser = find_option("admin-user","A",1);
134
135 url_parse(g.argv[2], URL_PROMPT_PW|URL_ASK_REMEMBER_PW);
136 if( zDefaultUser==0 && g.urlUser!=0 ) zDefaultUser = g.urlUser;
137 if( g.urlIsFile ){
138 file_copy(g.urlName, g.argv[3]);
139 db_close(1);
140 db_open_repository(g.argv[3]);
141
--- src/clone.c
+++ src/clone.c
@@ -105,10 +105,11 @@
105 ** admin user. This can be overridden using the -A|--admin-user
106 ** parameter.
107 **
108 ** Options:
109 ** --admin-user|-A USERNAME Make USERNAME the administrator
110 ** --once Don't save url.
111 ** --private Also clone private branches
112 ** --ssl-identity=filename Use the SSL identity if requested by the server
113 ** --ssh-command|-c 'command' Use this SSH command
114 **
115 ** See also: init
@@ -116,12 +117,14 @@
117 void clone_cmd(void){
118 char *zPassword;
119 const char *zDefaultUser; /* Optional name of the default user */
120 int nErr = 0;
121 int bPrivate = 0; /* Also clone private branches */
122 int urlFlags = URL_PROMPT_PW | URL_REMEMBER;
123
124 if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE;
125 if( find_option("once",0,0)!=0) urlFlags &= ~URL_REMEMBER;
126 clone_ssh_find_options();
127 url_proxy_options();
128 if( g.argc < 4 ){
129 usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY");
130 }
@@ -130,11 +133,11 @@
133 fossil_fatal("file already exists: %s", g.argv[3]);
134 }
135
136 zDefaultUser = find_option("admin-user","A",1);
137
138 url_parse(g.argv[2], urlFlags);
139 if( zDefaultUser==0 && g.urlUser!=0 ) zDefaultUser = g.urlUser;
140 if( g.urlIsFile ){
141 file_copy(g.urlName, g.argv[3]);
142 db_close(1);
143 db_open_repository(g.argv[3]);
144
+4 -1
--- src/clone.c
+++ src/clone.c
@@ -105,10 +105,11 @@
105105
** admin user. This can be overridden using the -A|--admin-user
106106
** parameter.
107107
**
108108
** Options:
109109
** --admin-user|-A USERNAME Make USERNAME the administrator
110
+** --once Don't save url.
110111
** --private Also clone private branches
111112
** --ssl-identity=filename Use the SSL identity if requested by the server
112113
** --ssh-command|-c 'command' Use this SSH command
113114
**
114115
** See also: init
@@ -116,12 +117,14 @@
116117
void clone_cmd(void){
117118
char *zPassword;
118119
const char *zDefaultUser; /* Optional name of the default user */
119120
int nErr = 0;
120121
int bPrivate = 0; /* Also clone private branches */
122
+ int urlFlags = URL_PROMPT_PW | URL_REMEMBER;
121123
122124
if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE;
125
+ if( find_option("once",0,0)!=0) urlFlags &= ~URL_REMEMBER;
123126
clone_ssh_find_options();
124127
url_proxy_options();
125128
if( g.argc < 4 ){
126129
usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY");
127130
}
@@ -130,11 +133,11 @@
130133
fossil_fatal("file already exists: %s", g.argv[3]);
131134
}
132135
133136
zDefaultUser = find_option("admin-user","A",1);
134137
135
- url_parse(g.argv[2], URL_PROMPT_PW|URL_ASK_REMEMBER_PW);
138
+ url_parse(g.argv[2], urlFlags);
136139
if( zDefaultUser==0 && g.urlUser!=0 ) zDefaultUser = g.urlUser;
137140
if( g.urlIsFile ){
138141
file_copy(g.urlName, g.argv[3]);
139142
db_close(1);
140143
db_open_repository(g.argv[3]);
141144
--- src/clone.c
+++ src/clone.c
@@ -105,10 +105,11 @@
105 ** admin user. This can be overridden using the -A|--admin-user
106 ** parameter.
107 **
108 ** Options:
109 ** --admin-user|-A USERNAME Make USERNAME the administrator
 
110 ** --private Also clone private branches
111 ** --ssl-identity=filename Use the SSL identity if requested by the server
112 ** --ssh-command|-c 'command' Use this SSH command
113 **
114 ** See also: init
@@ -116,12 +117,14 @@
116 void clone_cmd(void){
117 char *zPassword;
118 const char *zDefaultUser; /* Optional name of the default user */
119 int nErr = 0;
120 int bPrivate = 0; /* Also clone private branches */
 
121
122 if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE;
 
123 clone_ssh_find_options();
124 url_proxy_options();
125 if( g.argc < 4 ){
126 usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY");
127 }
@@ -130,11 +133,11 @@
130 fossil_fatal("file already exists: %s", g.argv[3]);
131 }
132
133 zDefaultUser = find_option("admin-user","A",1);
134
135 url_parse(g.argv[2], URL_PROMPT_PW|URL_ASK_REMEMBER_PW);
136 if( zDefaultUser==0 && g.urlUser!=0 ) zDefaultUser = g.urlUser;
137 if( g.urlIsFile ){
138 file_copy(g.urlName, g.argv[3]);
139 db_close(1);
140 db_open_repository(g.argv[3]);
141
--- src/clone.c
+++ src/clone.c
@@ -105,10 +105,11 @@
105 ** admin user. This can be overridden using the -A|--admin-user
106 ** parameter.
107 **
108 ** Options:
109 ** --admin-user|-A USERNAME Make USERNAME the administrator
110 ** --once Don't save url.
111 ** --private Also clone private branches
112 ** --ssl-identity=filename Use the SSL identity if requested by the server
113 ** --ssh-command|-c 'command' Use this SSH command
114 **
115 ** See also: init
@@ -116,12 +117,14 @@
117 void clone_cmd(void){
118 char *zPassword;
119 const char *zDefaultUser; /* Optional name of the default user */
120 int nErr = 0;
121 int bPrivate = 0; /* Also clone private branches */
122 int urlFlags = URL_PROMPT_PW | URL_REMEMBER;
123
124 if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE;
125 if( find_option("once",0,0)!=0) urlFlags &= ~URL_REMEMBER;
126 clone_ssh_find_options();
127 url_proxy_options();
128 if( g.argc < 4 ){
129 usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY");
130 }
@@ -130,11 +133,11 @@
133 fossil_fatal("file already exists: %s", g.argv[3]);
134 }
135
136 zDefaultUser = find_option("admin-user","A",1);
137
138 url_parse(g.argv[2], urlFlags);
139 if( zDefaultUser==0 && g.urlUser!=0 ) zDefaultUser = g.urlUser;
140 if( g.urlIsFile ){
141 file_copy(g.urlName, g.argv[3]);
142 db_close(1);
143 db_open_repository(g.argv[3]);
144
+4 -1
--- src/sync.c
+++ src/sync.c
@@ -54,10 +54,11 @@
5454
if( g.urlUser!=0 && g.urlPasswd==0 ){
5555
g.urlPasswd = unobscure(db_get("last-sync-pw", 0));
5656
g.urlFlags |= URL_PROMPT_PW;
5757
url_prompt_for_password();
5858
}
59
+ url_remember();
5960
#if 0 /* Disabled for now */
6061
if( (flags & AUTOSYNC_PULL)!=0 && db_get_boolean("auto-shun",1) ){
6162
/* When doing an automatic pull, also automatically pull shuns from
6263
** the server if pull_shuns is enabled.
6364
**
@@ -115,10 +116,11 @@
115116
}
116117
if( urlFlags & URL_REMEMBER ){
117118
clone_ssh_db_set_options();
118119
}
119120
url_parse(zUrl, urlFlags);
121
+ url_remember();
120122
if( g.urlProtocol==0 ){
121123
if( urlOptional ) fossil_exit(0);
122124
usage("URL");
123125
}
124126
user_select();
@@ -262,16 +264,17 @@
262264
}
263265
if( g.argc==3 ){
264266
db_unset("last-sync-url", 0);
265267
db_unset("last-sync-pw", 0);
266268
if( is_false(g.argv[2]) ) return;
267
- url_parse(g.argv[2], URL_REMEMBER|URL_PROMPT_PW);
269
+ url_parse(g.argv[2], URL_REMEMBER|URL_PROMPT_PW|URL_ASK_REMEMBER_PW);
268270
}
271
+ url_remember();
269272
zUrl = db_get("last-sync-url", 0);
270273
if( zUrl==0 ){
271274
fossil_print("off\n");
272275
return;
273276
}else{
274277
url_parse(zUrl, 0);
275278
fossil_print("%s\n", g.urlCanonical);
276279
}
277280
}
278281
--- src/sync.c
+++ src/sync.c
@@ -54,10 +54,11 @@
54 if( g.urlUser!=0 && g.urlPasswd==0 ){
55 g.urlPasswd = unobscure(db_get("last-sync-pw", 0));
56 g.urlFlags |= URL_PROMPT_PW;
57 url_prompt_for_password();
58 }
 
59 #if 0 /* Disabled for now */
60 if( (flags & AUTOSYNC_PULL)!=0 && db_get_boolean("auto-shun",1) ){
61 /* When doing an automatic pull, also automatically pull shuns from
62 ** the server if pull_shuns is enabled.
63 **
@@ -115,10 +116,11 @@
115 }
116 if( urlFlags & URL_REMEMBER ){
117 clone_ssh_db_set_options();
118 }
119 url_parse(zUrl, urlFlags);
 
120 if( g.urlProtocol==0 ){
121 if( urlOptional ) fossil_exit(0);
122 usage("URL");
123 }
124 user_select();
@@ -262,16 +264,17 @@
262 }
263 if( g.argc==3 ){
264 db_unset("last-sync-url", 0);
265 db_unset("last-sync-pw", 0);
266 if( is_false(g.argv[2]) ) return;
267 url_parse(g.argv[2], URL_REMEMBER|URL_PROMPT_PW);
268 }
 
269 zUrl = db_get("last-sync-url", 0);
270 if( zUrl==0 ){
271 fossil_print("off\n");
272 return;
273 }else{
274 url_parse(zUrl, 0);
275 fossil_print("%s\n", g.urlCanonical);
276 }
277 }
278
--- src/sync.c
+++ src/sync.c
@@ -54,10 +54,11 @@
54 if( g.urlUser!=0 && g.urlPasswd==0 ){
55 g.urlPasswd = unobscure(db_get("last-sync-pw", 0));
56 g.urlFlags |= URL_PROMPT_PW;
57 url_prompt_for_password();
58 }
59 url_remember();
60 #if 0 /* Disabled for now */
61 if( (flags & AUTOSYNC_PULL)!=0 && db_get_boolean("auto-shun",1) ){
62 /* When doing an automatic pull, also automatically pull shuns from
63 ** the server if pull_shuns is enabled.
64 **
@@ -115,10 +116,11 @@
116 }
117 if( urlFlags & URL_REMEMBER ){
118 clone_ssh_db_set_options();
119 }
120 url_parse(zUrl, urlFlags);
121 url_remember();
122 if( g.urlProtocol==0 ){
123 if( urlOptional ) fossil_exit(0);
124 usage("URL");
125 }
126 user_select();
@@ -262,16 +264,17 @@
264 }
265 if( g.argc==3 ){
266 db_unset("last-sync-url", 0);
267 db_unset("last-sync-pw", 0);
268 if( is_false(g.argv[2]) ) return;
269 url_parse(g.argv[2], URL_REMEMBER|URL_PROMPT_PW|URL_ASK_REMEMBER_PW);
270 }
271 url_remember();
272 zUrl = db_get("last-sync-url", 0);
273 if( zUrl==0 ){
274 fossil_print("off\n");
275 return;
276 }else{
277 url_parse(zUrl, 0);
278 fossil_print("%s\n", g.urlCanonical);
279 }
280 }
281
+33 -27
--- src/url.c
+++ src/url.c
@@ -17,10 +17,16 @@
1717
**
1818
** This file contains code for parsing URLs that appear on the command-line
1919
*/
2020
#include "config.h"
2121
#include "url.h"
22
+#include <stdio.h>
23
+#ifdef _WIN32
24
+#include <io.h>
25
+#define isatty(d) _isatty(d)
26
+#define fileno(s) _fileno(s)
27
+#endif
2228
2329
#if INTERFACE
2430
/*
2531
** Flags for url_parse()
2632
*/
@@ -64,24 +70,23 @@
6470
**
6571
** http://userid:password@host:port/path
6672
**
6773
** SSH url format is:
6874
**
69
-** ssh://userid:password@host:port/path?fossil=path/to/fossil.exe
75
+** ssh://userid@host:port/path?fossil=path/to/fossil.exe
7076
**
7177
*/
7278
void url_parse(const char *zUrl, unsigned int urlFlags){
7379
int i, j, c;
7480
char *zFile = 0;
75
- int bPrompted = 0;
76
- int bSetUrl = 1;
7781
7882
if( zUrl==0 ){
7983
zUrl = db_get("last-sync-url", 0);
8084
if( zUrl==0 ) return;
81
- g.urlPasswd = unobscure(db_get("last-sync-pw", 0));
82
- bSetUrl = 0;
85
+ if( g.urlPasswd==0 ){
86
+ g.urlPasswd = unobscure(db_get("last-sync-pw", 0));
87
+ }
8388
}
8489
8590
if( strncmp(zUrl, "http://", 7)==0
8691
|| strncmp(zUrl, "https://", 8)==0
8792
|| strncmp(zUrl, "ssh://", 6)==0
@@ -114,18 +119,20 @@
114119
/* Parse up the user-id and password */
115120
for(j=iStart; j<i && zUrl[j]!=':'; j++){}
116121
g.urlUser = mprintf("%.*s", j-iStart, &zUrl[iStart]);
117122
dehttpize(g.urlUser);
118123
if( j<i ){
124
+ if( ( urlFlags & URL_REMEMBER ) && g.urlIsSsh==0 ){
125
+ urlFlags |= URL_ASK_REMEMBER_PW;
126
+ }
119127
g.urlPasswd = mprintf("%.*s", i-j-1, &zUrl[j+1]);
120128
dehttpize(g.urlPasswd);
121129
}
122
- if( g.urlIsSsh && g.urlPasswd ){
123
- zLogin = mprintf("%t:*@", g.urlUser);
124
- }else{
125
- zLogin = mprintf("%t@", g.urlUser);
130
+ if( g.urlIsSsh ){
131
+ urlFlags &= ~URL_ASK_REMEMBER_PW;
126132
}
133
+ zLogin = mprintf("%t@", g.urlUser);
127134
for(j=i+1; (c=zUrl[j])!=0 && c!='/' && c!=':'; j++){}
128135
g.urlName = mprintf("%.*s", j-i-1, &zUrl[i+1]);
129136
i = j;
130137
}else{
131138
for(i=iStart; (c=zUrl[i])!=0 && c!='/' && c!=':'; i++){}
@@ -210,11 +217,11 @@
210217
fossil_fatal("unknown repository: %s", zUrl);
211218
}
212219
}else{
213220
fossil_fatal("unknown repository: %s", zUrl);
214221
}
215
- g.urlFlags = urlFlags;
222
+ if( urlFlags ) g.urlFlags = urlFlags;
216223
if( g.urlIsFile ){
217224
Blob cfile;
218225
dehttpize(zFile);
219226
file_canonical_name(zFile, &cfile, 0);
220227
free(zFile);
@@ -223,18 +230,17 @@
223230
g.urlName = mprintf("%b", &cfile);
224231
g.urlCanonical = mprintf("file://%T", g.urlName);
225232
blob_reset(&cfile);
226233
}else if( g.urlUser!=0 && g.urlPasswd==0 && (urlFlags & URL_PROMPT_PW) ){
227234
url_prompt_for_password();
228
- bPrompted = 1;
229
- }
230
- if( urlFlags & URL_REMEMBER ){
231
- if( bSetUrl ){
232
- db_set("last-sync-url", g.urlCanonical, 0);
233
- }
234
- if( !bPrompted && g.urlPasswd && g.urlUser ){
235
- db_set("last-sync-pw", obscure(g.urlPasswd), 0);
235
+ }else if( g.urlUser!=0 && ( urlFlags & URL_ASK_REMEMBER_PW ) ){
236
+ if( isatty(fileno(stdin)) ){
237
+ if( save_password_prompt() ){
238
+ g.urlFlags = urlFlags |= URL_REMEMBER_PW;
239
+ }else{
240
+ g.urlFlags = urlFlags &= ~URL_REMEMBER_PW;
241
+ }
236242
}
237243
}
238244
}
239245
240246
/*
@@ -444,38 +450,38 @@
444450
if( g.urlPasswd[0]
445451
&& (g.urlFlags & (URL_REMEMBER|URL_ASK_REMEMBER_PW))!=0
446452
){
447453
if( save_password_prompt() ){
448454
g.urlFlags |= URL_REMEMBER_PW;
449
- if( g.urlFlags & URL_REMEMBER ){
450
- db_set("last-sync-pw", obscure(g.urlPasswd), 0);
451
- }
455
+ }else{
456
+ g.urlFlags &= ~URL_REMEMBER_PW;
452457
}
453458
}
454459
}else{
455460
fossil_fatal("missing or incorrect password for user \"%s\"",
456461
g.urlUser);
457462
}
458463
}
459464
460465
/*
461
-** Remember the URL if requested.
466
+** Remember the URL and password if requested.
462467
*/
463468
void url_remember(void){
464
- db_set("last-sync-url", g.urlCanonical, 0);
465
- if( g.urlFlags & URL_REMEMBER_PW ){
466
- db_set("last-sync-pw", obscure(g.urlPasswd), 0);
469
+ if( g.urlFlags & URL_REMEMBER ){
470
+ db_set("last-sync-url", g.urlCanonical, 0);
471
+ if( g.urlUser!=0 && g.urlPasswd!=0 && ( g.urlFlags & URL_REMEMBER_PW ) ){
472
+ db_set("last-sync-pw", obscure(g.urlPasswd), 0);
473
+ }
467474
}
468
- g.urlFlags |= URL_REMEMBER;
469475
}
470476
471477
/* Preemptively prompt for a password if a username is given in the
472478
** URL but no password.
473479
*/
474480
void url_get_password_if_needed(void){
475481
if( (g.urlUser && g.urlUser[0])
476482
&& (g.urlPasswd==0 || g.urlPasswd[0]==0)
477
- && isatty(fileno(stdin))
483
+ && isatty(fileno(stdin))
478484
){
479485
url_prompt_for_password();
480486
}
481487
}
482488
--- src/url.c
+++ src/url.c
@@ -17,10 +17,16 @@
17 **
18 ** This file contains code for parsing URLs that appear on the command-line
19 */
20 #include "config.h"
21 #include "url.h"
 
 
 
 
 
 
22
23 #if INTERFACE
24 /*
25 ** Flags for url_parse()
26 */
@@ -64,24 +70,23 @@
64 **
65 ** http://userid:password@host:port/path
66 **
67 ** SSH url format is:
68 **
69 ** ssh://userid:password@host:port/path?fossil=path/to/fossil.exe
70 **
71 */
72 void url_parse(const char *zUrl, unsigned int urlFlags){
73 int i, j, c;
74 char *zFile = 0;
75 int bPrompted = 0;
76 int bSetUrl = 1;
77
78 if( zUrl==0 ){
79 zUrl = db_get("last-sync-url", 0);
80 if( zUrl==0 ) return;
81 g.urlPasswd = unobscure(db_get("last-sync-pw", 0));
82 bSetUrl = 0;
 
83 }
84
85 if( strncmp(zUrl, "http://", 7)==0
86 || strncmp(zUrl, "https://", 8)==0
87 || strncmp(zUrl, "ssh://", 6)==0
@@ -114,18 +119,20 @@
114 /* Parse up the user-id and password */
115 for(j=iStart; j<i && zUrl[j]!=':'; j++){}
116 g.urlUser = mprintf("%.*s", j-iStart, &zUrl[iStart]);
117 dehttpize(g.urlUser);
118 if( j<i ){
 
 
 
119 g.urlPasswd = mprintf("%.*s", i-j-1, &zUrl[j+1]);
120 dehttpize(g.urlPasswd);
121 }
122 if( g.urlIsSsh && g.urlPasswd ){
123 zLogin = mprintf("%t:*@", g.urlUser);
124 }else{
125 zLogin = mprintf("%t@", g.urlUser);
126 }
 
127 for(j=i+1; (c=zUrl[j])!=0 && c!='/' && c!=':'; j++){}
128 g.urlName = mprintf("%.*s", j-i-1, &zUrl[i+1]);
129 i = j;
130 }else{
131 for(i=iStart; (c=zUrl[i])!=0 && c!='/' && c!=':'; i++){}
@@ -210,11 +217,11 @@
210 fossil_fatal("unknown repository: %s", zUrl);
211 }
212 }else{
213 fossil_fatal("unknown repository: %s", zUrl);
214 }
215 g.urlFlags = urlFlags;
216 if( g.urlIsFile ){
217 Blob cfile;
218 dehttpize(zFile);
219 file_canonical_name(zFile, &cfile, 0);
220 free(zFile);
@@ -223,18 +230,17 @@
223 g.urlName = mprintf("%b", &cfile);
224 g.urlCanonical = mprintf("file://%T", g.urlName);
225 blob_reset(&cfile);
226 }else if( g.urlUser!=0 && g.urlPasswd==0 && (urlFlags & URL_PROMPT_PW) ){
227 url_prompt_for_password();
228 bPrompted = 1;
229 }
230 if( urlFlags & URL_REMEMBER ){
231 if( bSetUrl ){
232 db_set("last-sync-url", g.urlCanonical, 0);
233 }
234 if( !bPrompted && g.urlPasswd && g.urlUser ){
235 db_set("last-sync-pw", obscure(g.urlPasswd), 0);
236 }
237 }
238 }
239
240 /*
@@ -444,38 +450,38 @@
444 if( g.urlPasswd[0]
445 && (g.urlFlags & (URL_REMEMBER|URL_ASK_REMEMBER_PW))!=0
446 ){
447 if( save_password_prompt() ){
448 g.urlFlags |= URL_REMEMBER_PW;
449 if( g.urlFlags & URL_REMEMBER ){
450 db_set("last-sync-pw", obscure(g.urlPasswd), 0);
451 }
452 }
453 }
454 }else{
455 fossil_fatal("missing or incorrect password for user \"%s\"",
456 g.urlUser);
457 }
458 }
459
460 /*
461 ** Remember the URL if requested.
462 */
463 void url_remember(void){
464 db_set("last-sync-url", g.urlCanonical, 0);
465 if( g.urlFlags & URL_REMEMBER_PW ){
466 db_set("last-sync-pw", obscure(g.urlPasswd), 0);
 
 
467 }
468 g.urlFlags |= URL_REMEMBER;
469 }
470
471 /* Preemptively prompt for a password if a username is given in the
472 ** URL but no password.
473 */
474 void url_get_password_if_needed(void){
475 if( (g.urlUser && g.urlUser[0])
476 && (g.urlPasswd==0 || g.urlPasswd[0]==0)
477 && isatty(fileno(stdin))
478 ){
479 url_prompt_for_password();
480 }
481 }
482
--- src/url.c
+++ src/url.c
@@ -17,10 +17,16 @@
17 **
18 ** This file contains code for parsing URLs that appear on the command-line
19 */
20 #include "config.h"
21 #include "url.h"
22 #include <stdio.h>
23 #ifdef _WIN32
24 #include <io.h>
25 #define isatty(d) _isatty(d)
26 #define fileno(s) _fileno(s)
27 #endif
28
29 #if INTERFACE
30 /*
31 ** Flags for url_parse()
32 */
@@ -64,24 +70,23 @@
70 **
71 ** http://userid:password@host:port/path
72 **
73 ** SSH url format is:
74 **
75 ** ssh://userid@host:port/path?fossil=path/to/fossil.exe
76 **
77 */
78 void url_parse(const char *zUrl, unsigned int urlFlags){
79 int i, j, c;
80 char *zFile = 0;
 
 
81
82 if( zUrl==0 ){
83 zUrl = db_get("last-sync-url", 0);
84 if( zUrl==0 ) return;
85 if( g.urlPasswd==0 ){
86 g.urlPasswd = unobscure(db_get("last-sync-pw", 0));
87 }
88 }
89
90 if( strncmp(zUrl, "http://", 7)==0
91 || strncmp(zUrl, "https://", 8)==0
92 || strncmp(zUrl, "ssh://", 6)==0
@@ -114,18 +119,20 @@
119 /* Parse up the user-id and password */
120 for(j=iStart; j<i && zUrl[j]!=':'; j++){}
121 g.urlUser = mprintf("%.*s", j-iStart, &zUrl[iStart]);
122 dehttpize(g.urlUser);
123 if( j<i ){
124 if( ( urlFlags & URL_REMEMBER ) && g.urlIsSsh==0 ){
125 urlFlags |= URL_ASK_REMEMBER_PW;
126 }
127 g.urlPasswd = mprintf("%.*s", i-j-1, &zUrl[j+1]);
128 dehttpize(g.urlPasswd);
129 }
130 if( g.urlIsSsh ){
131 urlFlags &= ~URL_ASK_REMEMBER_PW;
 
 
132 }
133 zLogin = mprintf("%t@", g.urlUser);
134 for(j=i+1; (c=zUrl[j])!=0 && c!='/' && c!=':'; j++){}
135 g.urlName = mprintf("%.*s", j-i-1, &zUrl[i+1]);
136 i = j;
137 }else{
138 for(i=iStart; (c=zUrl[i])!=0 && c!='/' && c!=':'; i++){}
@@ -210,11 +217,11 @@
217 fossil_fatal("unknown repository: %s", zUrl);
218 }
219 }else{
220 fossil_fatal("unknown repository: %s", zUrl);
221 }
222 if( urlFlags ) g.urlFlags = urlFlags;
223 if( g.urlIsFile ){
224 Blob cfile;
225 dehttpize(zFile);
226 file_canonical_name(zFile, &cfile, 0);
227 free(zFile);
@@ -223,18 +230,17 @@
230 g.urlName = mprintf("%b", &cfile);
231 g.urlCanonical = mprintf("file://%T", g.urlName);
232 blob_reset(&cfile);
233 }else if( g.urlUser!=0 && g.urlPasswd==0 && (urlFlags & URL_PROMPT_PW) ){
234 url_prompt_for_password();
235 }else if( g.urlUser!=0 && ( urlFlags & URL_ASK_REMEMBER_PW ) ){
236 if( isatty(fileno(stdin)) ){
237 if( save_password_prompt() ){
238 g.urlFlags = urlFlags |= URL_REMEMBER_PW;
239 }else{
240 g.urlFlags = urlFlags &= ~URL_REMEMBER_PW;
241 }
 
242 }
243 }
244 }
245
246 /*
@@ -444,38 +450,38 @@
450 if( g.urlPasswd[0]
451 && (g.urlFlags & (URL_REMEMBER|URL_ASK_REMEMBER_PW))!=0
452 ){
453 if( save_password_prompt() ){
454 g.urlFlags |= URL_REMEMBER_PW;
455 }else{
456 g.urlFlags &= ~URL_REMEMBER_PW;
 
457 }
458 }
459 }else{
460 fossil_fatal("missing or incorrect password for user \"%s\"",
461 g.urlUser);
462 }
463 }
464
465 /*
466 ** Remember the URL and password if requested.
467 */
468 void url_remember(void){
469 if( g.urlFlags & URL_REMEMBER ){
470 db_set("last-sync-url", g.urlCanonical, 0);
471 if( g.urlUser!=0 && g.urlPasswd!=0 && ( g.urlFlags & URL_REMEMBER_PW ) ){
472 db_set("last-sync-pw", obscure(g.urlPasswd), 0);
473 }
474 }
 
475 }
476
477 /* Preemptively prompt for a password if a username is given in the
478 ** URL but no password.
479 */
480 void url_get_password_if_needed(void){
481 if( (g.urlUser && g.urlUser[0])
482 && (g.urlPasswd==0 || g.urlPasswd[0]==0)
483 && isatty(fileno(stdin))
484 ){
485 url_prompt_for_password();
486 }
487 }
488
+4
--- src/user.c
+++ src/user.c
@@ -135,10 +135,14 @@
135135
** Prompt to save Fossil user password
136136
*/
137137
int save_password_prompt(){
138138
Blob x;
139139
char c;
140
+ const char *old = db_get("last-sync-pw", 0);
141
+ if( (old!=0) && fossil_strcmp(unobscure(old), g.urlPasswd)==0 ){
142
+ return 0;
143
+ }
140144
prompt_user("remember password (Y/n)? ", &x);
141145
c = blob_str(&x)[0];
142146
blob_reset(&x);
143147
return ( c!='n' && c!='N' );
144148
}
145149
--- src/user.c
+++ src/user.c
@@ -135,10 +135,14 @@
135 ** Prompt to save Fossil user password
136 */
137 int save_password_prompt(){
138 Blob x;
139 char c;
 
 
 
 
140 prompt_user("remember password (Y/n)? ", &x);
141 c = blob_str(&x)[0];
142 blob_reset(&x);
143 return ( c!='n' && c!='N' );
144 }
145
--- src/user.c
+++ src/user.c
@@ -135,10 +135,14 @@
135 ** Prompt to save Fossil user password
136 */
137 int save_password_prompt(){
138 Blob x;
139 char c;
140 const char *old = db_get("last-sync-pw", 0);
141 if( (old!=0) && fossil_strcmp(unobscure(old), g.urlPasswd)==0 ){
142 return 0;
143 }
144 prompt_user("remember password (Y/n)? ", &x);
145 c = blob_str(&x)[0];
146 blob_reset(&x);
147 return ( c!='n' && c!='N' );
148 }
149
+4
--- src/user.c
+++ src/user.c
@@ -135,10 +135,14 @@
135135
** Prompt to save Fossil user password
136136
*/
137137
int save_password_prompt(){
138138
Blob x;
139139
char c;
140
+ const char *old = db_get("last-sync-pw", 0);
141
+ if( (old!=0) && fossil_strcmp(unobscure(old), g.urlPasswd)==0 ){
142
+ return 0;
143
+ }
140144
prompt_user("remember password (Y/n)? ", &x);
141145
c = blob_str(&x)[0];
142146
blob_reset(&x);
143147
return ( c!='n' && c!='N' );
144148
}
145149
--- src/user.c
+++ src/user.c
@@ -135,10 +135,14 @@
135 ** Prompt to save Fossil user password
136 */
137 int save_password_prompt(){
138 Blob x;
139 char c;
 
 
 
 
140 prompt_user("remember password (Y/n)? ", &x);
141 c = blob_str(&x)[0];
142 blob_reset(&x);
143 return ( c!='n' && c!='N' );
144 }
145
--- src/user.c
+++ src/user.c
@@ -135,10 +135,14 @@
135 ** Prompt to save Fossil user password
136 */
137 int save_password_prompt(){
138 Blob x;
139 char c;
140 const char *old = db_get("last-sync-pw", 0);
141 if( (old!=0) && fossil_strcmp(unobscure(old), g.urlPasswd)==0 ){
142 return 0;
143 }
144 prompt_user("remember password (Y/n)? ", &x);
145 c = blob_str(&x)[0];
146 blob_reset(&x);
147 return ( c!='n' && c!='N' );
148 }
149
+2
--- src/xfer.c
+++ src/xfer.c
@@ -1781,11 +1781,13 @@
17811781
if( nCycle<2 ){
17821782
g.urlPasswd = 0;
17831783
go = 1;
17841784
if( g.cgiOutput==0 ){
17851785
g.urlFlags |= URL_PROMPT_PW;
1786
+ g.urlFlags &= ~URL_PROMPTED;
17861787
url_prompt_for_password();
1788
+ url_remember();
17871789
}
17881790
}
17891791
}else{
17901792
blob_appendf(&xfer.err, "server says: %s\n", zMsg);
17911793
nErr++;
17921794
--- src/xfer.c
+++ src/xfer.c
@@ -1781,11 +1781,13 @@
1781 if( nCycle<2 ){
1782 g.urlPasswd = 0;
1783 go = 1;
1784 if( g.cgiOutput==0 ){
1785 g.urlFlags |= URL_PROMPT_PW;
 
1786 url_prompt_for_password();
 
1787 }
1788 }
1789 }else{
1790 blob_appendf(&xfer.err, "server says: %s\n", zMsg);
1791 nErr++;
1792
--- src/xfer.c
+++ src/xfer.c
@@ -1781,11 +1781,13 @@
1781 if( nCycle<2 ){
1782 g.urlPasswd = 0;
1783 go = 1;
1784 if( g.cgiOutput==0 ){
1785 g.urlFlags |= URL_PROMPT_PW;
1786 g.urlFlags &= ~URL_PROMPTED;
1787 url_prompt_for_password();
1788 url_remember();
1789 }
1790 }
1791 }else{
1792 blob_appendf(&xfer.err, "server says: %s\n", zMsg);
1793 nErr++;
1794
--- www/changes.wiki
+++ www/changes.wiki
@@ -26,10 +26,13 @@
2626
specifies the number of entries, just like all other commands which
2727
have the -n|--limit option. The various timeline-related functions
2828
now output "+++ end of timeline reached +++" whenever appropriate.
2929
Use "-n 0" if no limit is desired, the end of timeline marker will
3030
not be printed then.
31
+ * Fix handling of password embedded in Fossil URL.
32
+ * New --once option to [/help?cmd=clone | fossil clone] command which does
33
+ not store the URL or password when cloning.
3134
3235
<h2>Changes For Version 1.27 (2013-09-11)</h2>
3336
* Enhance the [/help?cmd=changes | fossil changes],
3437
[/help?cmd=clean | fossil clean], [/help?cmd=extras | fossil extras],
3538
[/help?cmd=ls | fossil ls] and [/help?cmd=status | fossil status] commands
3639
--- www/changes.wiki
+++ www/changes.wiki
@@ -26,10 +26,13 @@
26 specifies the number of entries, just like all other commands which
27 have the -n|--limit option. The various timeline-related functions
28 now output "+++ end of timeline reached +++" whenever appropriate.
29 Use "-n 0" if no limit is desired, the end of timeline marker will
30 not be printed then.
 
 
 
31
32 <h2>Changes For Version 1.27 (2013-09-11)</h2>
33 * Enhance the [/help?cmd=changes | fossil changes],
34 [/help?cmd=clean | fossil clean], [/help?cmd=extras | fossil extras],
35 [/help?cmd=ls | fossil ls] and [/help?cmd=status | fossil status] commands
36
--- www/changes.wiki
+++ www/changes.wiki
@@ -26,10 +26,13 @@
26 specifies the number of entries, just like all other commands which
27 have the -n|--limit option. The various timeline-related functions
28 now output "+++ end of timeline reached +++" whenever appropriate.
29 Use "-n 0" if no limit is desired, the end of timeline marker will
30 not be printed then.
31 * Fix handling of password embedded in Fossil URL.
32 * New --once option to [/help?cmd=clone | fossil clone] command which does
33 not store the URL or password when cloning.
34
35 <h2>Changes For Version 1.27 (2013-09-11)</h2>
36 * Enhance the [/help?cmd=changes | fossil changes],
37 [/help?cmd=clean | fossil clean], [/help?cmd=extras | fossil extras],
38 [/help?cmd=ls | fossil ls] and [/help?cmd=status | fossil status] commands
39
--- www/changes.wiki
+++ www/changes.wiki
@@ -26,10 +26,13 @@
2626
specifies the number of entries, just like all other commands which
2727
have the -n|--limit option. The various timeline-related functions
2828
now output "+++ end of timeline reached +++" whenever appropriate.
2929
Use "-n 0" if no limit is desired, the end of timeline marker will
3030
not be printed then.
31
+ * Fix handling of password embedded in Fossil URL.
32
+ * New --once option to [/help?cmd=clone | fossil clone] command which does
33
+ not store the URL or password when cloning.
3134
3235
<h2>Changes For Version 1.27 (2013-09-11)</h2>
3336
* Enhance the [/help?cmd=changes | fossil changes],
3437
[/help?cmd=clean | fossil clean], [/help?cmd=extras | fossil extras],
3538
[/help?cmd=ls | fossil ls] and [/help?cmd=status | fossil status] commands
3639
--- www/changes.wiki
+++ www/changes.wiki
@@ -26,10 +26,13 @@
26 specifies the number of entries, just like all other commands which
27 have the -n|--limit option. The various timeline-related functions
28 now output "+++ end of timeline reached +++" whenever appropriate.
29 Use "-n 0" if no limit is desired, the end of timeline marker will
30 not be printed then.
 
 
 
31
32 <h2>Changes For Version 1.27 (2013-09-11)</h2>
33 * Enhance the [/help?cmd=changes | fossil changes],
34 [/help?cmd=clean | fossil clean], [/help?cmd=extras | fossil extras],
35 [/help?cmd=ls | fossil ls] and [/help?cmd=status | fossil status] commands
36
--- www/changes.wiki
+++ www/changes.wiki
@@ -26,10 +26,13 @@
26 specifies the number of entries, just like all other commands which
27 have the -n|--limit option. The various timeline-related functions
28 now output "+++ end of timeline reached +++" whenever appropriate.
29 Use "-n 0" if no limit is desired, the end of timeline marker will
30 not be printed then.
31 * Fix handling of password embedded in Fossil URL.
32 * New --once option to [/help?cmd=clone | fossil clone] command which does
33 not store the URL or password when cloning.
34
35 <h2>Changes For Version 1.27 (2013-09-11)</h2>
36 * Enhance the [/help?cmd=changes | fossil changes],
37 [/help?cmd=clean | fossil clean], [/help?cmd=extras | fossil extras],
38 [/help?cmd=ls | fossil ls] and [/help?cmd=status | fossil status] commands
39

Keyboard Shortcuts

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