Fossil SCM
Get rid of the GLOBAL_URL() kludge. Change the global "g" variable to contain an instance of the UrlData object instead of individual fields of the UrlData object.
Commit
5fdad9bd8cebc34776755ade204bd35d5804e92e
Parent
42e66c1a171ae89…
12 files changed
+6
-6
+1
-1
+31
-31
+7
-6
+8
-6
+4
-4
+4
-6
+10
-10
+61
-61
+1
-1
+6
-6
+3
-3
+6
-6
| --- src/clone.c | ||
| +++ src/clone.c | ||
| @@ -136,13 +136,13 @@ | ||
| 136 | 136 | if( file_size(g.argv[3])>0 ){ |
| 137 | 137 | fossil_fatal("file already exists: %s", g.argv[3]); |
| 138 | 138 | } |
| 139 | 139 | |
| 140 | 140 | url_parse(g.argv[2], urlFlags); |
| 141 | - if( zDefaultUser==0 && g.urlUser!=0 ) zDefaultUser = g.urlUser; | |
| 142 | - if( g.urlIsFile ){ | |
| 143 | - file_copy(g.urlName, g.argv[3]); | |
| 141 | + if( zDefaultUser==0 && g.url.user!=0 ) zDefaultUser = g.url.user; | |
| 142 | + if( g.url.isFile ){ | |
| 143 | + file_copy(g.url.name, g.argv[3]); | |
| 144 | 144 | db_close(1); |
| 145 | 145 | db_open_repository(g.argv[3]); |
| 146 | 146 | db_record_repository_filename(g.argv[3]); |
| 147 | 147 | url_remember(); |
| 148 | 148 | if( !bPrivate ) delete_private_content(); |
| @@ -211,11 +211,11 @@ | ||
| 211 | 211 | void remember_or_get_http_auth( |
| 212 | 212 | const char *zHttpAuth, /* Credentials in the form "user:password" */ |
| 213 | 213 | int fRemember, /* True to remember credentials for later reuse */ |
| 214 | 214 | const char *zUrl /* URL for which these credentials apply */ |
| 215 | 215 | ){ |
| 216 | - char *zKey = mprintf("http-auth:%s", g.urlCanonical); | |
| 216 | + char *zKey = mprintf("http-auth:%s", g.url.canonical); | |
| 217 | 217 | if( zHttpAuth && zHttpAuth[0] ){ |
| 218 | 218 | g.zHttpAuth = mprintf("%s", zHttpAuth); |
| 219 | 219 | } |
| 220 | 220 | if( fRemember ){ |
| 221 | 221 | if( g.zHttpAuth && g.zHttpAuth[0] ){ |
| @@ -233,20 +233,20 @@ | ||
| 233 | 233 | |
| 234 | 234 | /* |
| 235 | 235 | ** Get the HTTP Authorization preference from db. |
| 236 | 236 | */ |
| 237 | 237 | char *get_httpauth(void){ |
| 238 | - char *zKey = mprintf("http-auth:%s", g.urlCanonical); | |
| 238 | + char *zKey = mprintf("http-auth:%s", g.url.canonical); | |
| 239 | 239 | return unobscure(db_get(zKey, 0)); |
| 240 | 240 | free(zKey); |
| 241 | 241 | } |
| 242 | 242 | |
| 243 | 243 | /* |
| 244 | 244 | ** Set the HTTP Authorization preference in db. |
| 245 | 245 | */ |
| 246 | 246 | void set_httpauth(const char *zHttpAuth){ |
| 247 | - char *zKey = mprintf("http-auth:%s", g.urlCanonical); | |
| 247 | + char *zKey = mprintf("http-auth:%s", g.url.canonical); | |
| 248 | 248 | db_set(zKey, obscure(zHttpAuth), 0); |
| 249 | 249 | free(zKey); |
| 250 | 250 | } |
| 251 | 251 | |
| 252 | 252 | /* |
| 253 | 253 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -136,13 +136,13 @@ | |
| 136 | if( file_size(g.argv[3])>0 ){ |
| 137 | fossil_fatal("file already exists: %s", g.argv[3]); |
| 138 | } |
| 139 | |
| 140 | url_parse(g.argv[2], urlFlags); |
| 141 | if( zDefaultUser==0 && g.urlUser!=0 ) zDefaultUser = g.urlUser; |
| 142 | if( g.urlIsFile ){ |
| 143 | file_copy(g.urlName, g.argv[3]); |
| 144 | db_close(1); |
| 145 | db_open_repository(g.argv[3]); |
| 146 | db_record_repository_filename(g.argv[3]); |
| 147 | url_remember(); |
| 148 | if( !bPrivate ) delete_private_content(); |
| @@ -211,11 +211,11 @@ | |
| 211 | void remember_or_get_http_auth( |
| 212 | const char *zHttpAuth, /* Credentials in the form "user:password" */ |
| 213 | int fRemember, /* True to remember credentials for later reuse */ |
| 214 | const char *zUrl /* URL for which these credentials apply */ |
| 215 | ){ |
| 216 | char *zKey = mprintf("http-auth:%s", g.urlCanonical); |
| 217 | if( zHttpAuth && zHttpAuth[0] ){ |
| 218 | g.zHttpAuth = mprintf("%s", zHttpAuth); |
| 219 | } |
| 220 | if( fRemember ){ |
| 221 | if( g.zHttpAuth && g.zHttpAuth[0] ){ |
| @@ -233,20 +233,20 @@ | |
| 233 | |
| 234 | /* |
| 235 | ** Get the HTTP Authorization preference from db. |
| 236 | */ |
| 237 | char *get_httpauth(void){ |
| 238 | char *zKey = mprintf("http-auth:%s", g.urlCanonical); |
| 239 | return unobscure(db_get(zKey, 0)); |
| 240 | free(zKey); |
| 241 | } |
| 242 | |
| 243 | /* |
| 244 | ** Set the HTTP Authorization preference in db. |
| 245 | */ |
| 246 | void set_httpauth(const char *zHttpAuth){ |
| 247 | char *zKey = mprintf("http-auth:%s", g.urlCanonical); |
| 248 | db_set(zKey, obscure(zHttpAuth), 0); |
| 249 | free(zKey); |
| 250 | } |
| 251 | |
| 252 | /* |
| 253 |
| --- src/clone.c | |
| +++ src/clone.c | |
| @@ -136,13 +136,13 @@ | |
| 136 | if( file_size(g.argv[3])>0 ){ |
| 137 | fossil_fatal("file already exists: %s", g.argv[3]); |
| 138 | } |
| 139 | |
| 140 | url_parse(g.argv[2], urlFlags); |
| 141 | if( zDefaultUser==0 && g.url.user!=0 ) zDefaultUser = g.url.user; |
| 142 | if( g.url.isFile ){ |
| 143 | file_copy(g.url.name, g.argv[3]); |
| 144 | db_close(1); |
| 145 | db_open_repository(g.argv[3]); |
| 146 | db_record_repository_filename(g.argv[3]); |
| 147 | url_remember(); |
| 148 | if( !bPrivate ) delete_private_content(); |
| @@ -211,11 +211,11 @@ | |
| 211 | void remember_or_get_http_auth( |
| 212 | const char *zHttpAuth, /* Credentials in the form "user:password" */ |
| 213 | int fRemember, /* True to remember credentials for later reuse */ |
| 214 | const char *zUrl /* URL for which these credentials apply */ |
| 215 | ){ |
| 216 | char *zKey = mprintf("http-auth:%s", g.url.canonical); |
| 217 | if( zHttpAuth && zHttpAuth[0] ){ |
| 218 | g.zHttpAuth = mprintf("%s", zHttpAuth); |
| 219 | } |
| 220 | if( fRemember ){ |
| 221 | if( g.zHttpAuth && g.zHttpAuth[0] ){ |
| @@ -233,20 +233,20 @@ | |
| 233 | |
| 234 | /* |
| 235 | ** Get the HTTP Authorization preference from db. |
| 236 | */ |
| 237 | char *get_httpauth(void){ |
| 238 | char *zKey = mprintf("http-auth:%s", g.url.canonical); |
| 239 | return unobscure(db_get(zKey, 0)); |
| 240 | free(zKey); |
| 241 | } |
| 242 | |
| 243 | /* |
| 244 | ** Set the HTTP Authorization preference in db. |
| 245 | */ |
| 246 | void set_httpauth(const char *zHttpAuth){ |
| 247 | char *zKey = mprintf("http-auth:%s", g.url.canonical); |
| 248 | db_set(zKey, obscure(zHttpAuth), 0); |
| 249 | free(zKey); |
| 250 | } |
| 251 | |
| 252 | /* |
| 253 |
+1
-1
| --- src/configure.c | ||
| +++ src/configure.c | ||
| @@ -924,11 +924,11 @@ | ||
| 924 | 924 | mask = configure_name_to_mask(g.argv[3], 1); |
| 925 | 925 | if( g.argc==5 ){ |
| 926 | 926 | zServer = g.argv[4]; |
| 927 | 927 | } |
| 928 | 928 | url_parse(zServer, URL_PROMPT_PW); |
| 929 | - if( g.urlProtocol==0 ) fossil_fatal("no server URL specified"); | |
| 929 | + if( g.url.protocol==0 ) fossil_fatal("no server URL specified"); | |
| 930 | 930 | user_select(); |
| 931 | 931 | url_enable_proxy("via proxy: "); |
| 932 | 932 | if( legacyFlag ) mask |= CONFIGSET_OLDFORMAT; |
| 933 | 933 | if( overwriteFlag ) mask |= CONFIGSET_OVERWRITE; |
| 934 | 934 | if( strncmp(zMethod, "push", n)==0 ){ |
| 935 | 935 |
| --- src/configure.c | |
| +++ src/configure.c | |
| @@ -924,11 +924,11 @@ | |
| 924 | mask = configure_name_to_mask(g.argv[3], 1); |
| 925 | if( g.argc==5 ){ |
| 926 | zServer = g.argv[4]; |
| 927 | } |
| 928 | url_parse(zServer, URL_PROMPT_PW); |
| 929 | if( g.urlProtocol==0 ) fossil_fatal("no server URL specified"); |
| 930 | user_select(); |
| 931 | url_enable_proxy("via proxy: "); |
| 932 | if( legacyFlag ) mask |= CONFIGSET_OLDFORMAT; |
| 933 | if( overwriteFlag ) mask |= CONFIGSET_OVERWRITE; |
| 934 | if( strncmp(zMethod, "push", n)==0 ){ |
| 935 |
| --- src/configure.c | |
| +++ src/configure.c | |
| @@ -924,11 +924,11 @@ | |
| 924 | mask = configure_name_to_mask(g.argv[3], 1); |
| 925 | if( g.argc==5 ){ |
| 926 | zServer = g.argv[4]; |
| 927 | } |
| 928 | url_parse(zServer, URL_PROMPT_PW); |
| 929 | if( g.url.protocol==0 ) fossil_fatal("no server URL specified"); |
| 930 | user_select(); |
| 931 | url_enable_proxy("via proxy: "); |
| 932 | if( legacyFlag ) mask |= CONFIGSET_OLDFORMAT; |
| 933 | if( overwriteFlag ) mask |= CONFIGSET_OVERWRITE; |
| 934 | if( strncmp(zMethod, "push", n)==0 ){ |
| 935 |
+31
-31
| --- src/http.c | ||
| +++ src/http.c | ||
| @@ -55,31 +55,31 @@ | ||
| 55 | 55 | const char *zPw; /* The user password */ |
| 56 | 56 | Blob pw; /* The nonce with user password appended */ |
| 57 | 57 | Blob sig; /* The signature field */ |
| 58 | 58 | |
| 59 | 59 | blob_zero(pLogin); |
| 60 | - if( g.urlUser==0 || fossil_strcmp(g.urlUser, "anonymous")==0 ){ | |
| 60 | + if( g.url.user==0 || fossil_strcmp(g.url.user, "anonymous")==0 ){ | |
| 61 | 61 | return; /* If no login card for users "nobody" and "anonymous" */ |
| 62 | 62 | } |
| 63 | - if( g.urlIsSsh ){ | |
| 63 | + if( g.url.isSsh ){ | |
| 64 | 64 | return; /* If no login card for SSH: */ |
| 65 | 65 | } |
| 66 | 66 | blob_zero(&nonce); |
| 67 | 67 | blob_zero(&pw); |
| 68 | 68 | sha1sum_blob(pPayload, &nonce); |
| 69 | 69 | blob_copy(&pw, &nonce); |
| 70 | - zLogin = g.urlUser; | |
| 71 | - if( g.urlPasswd ){ | |
| 72 | - zPw = g.urlPasswd; | |
| 70 | + zLogin = g.url.user; | |
| 71 | + if( g.url.passwd ){ | |
| 72 | + zPw = g.url.passwd; | |
| 73 | 73 | }else if( g.cgiOutput ){ |
| 74 | 74 | /* Password failure while doing a sync from the web interface */ |
| 75 | 75 | cgi_printf("*** incorrect or missing password for user %h\n", zLogin); |
| 76 | 76 | zPw = 0; |
| 77 | 77 | }else{ |
| 78 | 78 | /* Password failure while doing a sync from the command-line interface */ |
| 79 | 79 | url_prompt_for_password(); |
| 80 | - zPw = g.urlPasswd; | |
| 80 | + zPw = g.url.passwd; | |
| 81 | 81 | } |
| 82 | 82 | |
| 83 | 83 | /* The login card wants the SHA1 hash of the password, so convert the |
| 84 | 84 | ** password to its SHA1 hash it it isn't already a SHA1 hash. |
| 85 | 85 | */ |
| @@ -102,29 +102,29 @@ | ||
| 102 | 102 | static void http_build_header(Blob *pPayload, Blob *pHdr){ |
| 103 | 103 | int i; |
| 104 | 104 | const char *zSep; |
| 105 | 105 | |
| 106 | 106 | blob_zero(pHdr); |
| 107 | - i = strlen(g.urlPath); | |
| 108 | - if( i>0 && g.urlPath[i-1]=='/' ){ | |
| 107 | + i = strlen(g.url.path); | |
| 108 | + if( i>0 && g.url.path[i-1]=='/' ){ | |
| 109 | 109 | zSep = ""; |
| 110 | 110 | }else{ |
| 111 | 111 | zSep = "/"; |
| 112 | 112 | } |
| 113 | - blob_appendf(pHdr, "POST %s%sxfer/xfer HTTP/1.0\r\n", g.urlPath, zSep); | |
| 114 | - if( g.urlProxyAuth ){ | |
| 115 | - blob_appendf(pHdr, "Proxy-Authorization: %s\r\n", g.urlProxyAuth); | |
| 113 | + blob_appendf(pHdr, "POST %s%sxfer/xfer HTTP/1.0\r\n", g.url.path, zSep); | |
| 114 | + if( g.url.proxyAuth ){ | |
| 115 | + blob_appendf(pHdr, "Proxy-Authorization: %s\r\n", g.url.proxyAuth); | |
| 116 | 116 | } |
| 117 | 117 | if( g.zHttpAuth && g.zHttpAuth[0] ){ |
| 118 | 118 | const char *zCredentials = g.zHttpAuth; |
| 119 | 119 | char *zEncoded = encode64(zCredentials, -1); |
| 120 | 120 | blob_appendf(pHdr, "Authorization: Basic %s\r\n", zEncoded); |
| 121 | 121 | fossil_free(zEncoded); |
| 122 | 122 | } |
| 123 | - blob_appendf(pHdr, "Host: %s\r\n", g.urlHostname); | |
| 123 | + blob_appendf(pHdr, "Host: %s\r\n", g.url.hostname); | |
| 124 | 124 | blob_appendf(pHdr, "User-Agent: %s\r\n", get_user_agent()); |
| 125 | - if( g.urlIsSsh ) blob_appendf(pHdr, "X-Fossil-Transport: SSH\r\n"); | |
| 125 | + if( g.url.isSsh ) blob_appendf(pHdr, "X-Fossil-Transport: SSH\r\n"); | |
| 126 | 126 | if( g.fHttpTrace ){ |
| 127 | 127 | blob_appendf(pHdr, "Content-Type: application/x-fossil-debug\r\n"); |
| 128 | 128 | }else{ |
| 129 | 129 | blob_appendf(pHdr, "Content-Type: application/x-fossil\r\n"); |
| 130 | 130 | } |
| @@ -147,11 +147,11 @@ | ||
| 147 | 147 | ** Prompt to save HTTP Basic Authorization information |
| 148 | 148 | */ |
| 149 | 149 | static int save_httpauth_prompt(void){ |
| 150 | 150 | Blob x; |
| 151 | 151 | char c; |
| 152 | - if( (g.urlFlags & URL_REMEMBER)==0 ) return 0; | |
| 152 | + if( (g.url.flags & URL_REMEMBER)==0 ) return 0; | |
| 153 | 153 | prompt_user("Remember Basic Authorization credentials (Y/n)? ", &x); |
| 154 | 154 | c = blob_str(&x)[0]; |
| 155 | 155 | blob_reset(&x); |
| 156 | 156 | return ( c!='n' && c!='N' ); |
| 157 | 157 | } |
| @@ -166,15 +166,15 @@ | ||
| 166 | 166 | char *zPw; |
| 167 | 167 | char *zPrompt; |
| 168 | 168 | char *zHttpAuth = 0; |
| 169 | 169 | if( !isatty(fileno(stdin)) ) return 0; |
| 170 | 170 | zPrompt = mprintf("\n%s authorization required by\n%s\n", |
| 171 | - g.urlIsHttps==1 ? "Encrypted HTTPS" : "Unencrypted HTTP", g.urlCanonical); | |
| 171 | + g.url.isHttps==1 ? "Encrypted HTTPS" : "Unencrypted HTTP", g.url.canonical); | |
| 172 | 172 | fossil_print(zPrompt); |
| 173 | 173 | free(zPrompt); |
| 174 | - if ( g.urlUser && g.urlPasswd && use_fossil_creds_for_httpauth_prompt() ){ | |
| 175 | - zHttpAuth = mprintf("%s:%s", g.urlUser, g.urlPasswd); | |
| 174 | + if ( g.url.user && g.url.passwd && use_fossil_creds_for_httpauth_prompt() ){ | |
| 175 | + zHttpAuth = mprintf("%s:%s", g.url.user, g.url.passwd); | |
| 176 | 176 | }else{ |
| 177 | 177 | prompt_user("Basic Authorization user: ", &x); |
| 178 | 178 | zUser = mprintf("%b", &x); |
| 179 | 179 | zPrompt = mprintf("HTTP password for %b: ", &x); |
| 180 | 180 | blob_reset(&x); |
| @@ -213,12 +213,12 @@ | ||
| 213 | 213 | char *zLine; /* A single line of the reply header */ |
| 214 | 214 | int i; /* Loop counter */ |
| 215 | 215 | int isError = 0; /* True if the reply is an error message */ |
| 216 | 216 | int isCompressed = 1; /* True if the reply is compressed */ |
| 217 | 217 | |
| 218 | - if( transport_open(GLOBAL_URL()) ){ | |
| 219 | - fossil_warning(transport_errmsg(GLOBAL_URL())); | |
| 218 | + if( transport_open(&g.url) ){ | |
| 219 | + fossil_warning(transport_errmsg(&g.url)); | |
| 220 | 220 | return 1; |
| 221 | 221 | } |
| 222 | 222 | |
| 223 | 223 | /* Construct the login card and prepare the complete payload */ |
| 224 | 224 | blob_zero(&login); |
| @@ -260,32 +260,32 @@ | ||
| 260 | 260 | } |
| 261 | 261 | |
| 262 | 262 | /* |
| 263 | 263 | ** Send the request to the server. |
| 264 | 264 | */ |
| 265 | - transport_send(GLOBAL_URL(), &hdr); | |
| 266 | - transport_send(GLOBAL_URL(), &payload); | |
| 265 | + transport_send(&g.url, &hdr); | |
| 266 | + transport_send(&g.url, &payload); | |
| 267 | 267 | blob_reset(&hdr); |
| 268 | 268 | blob_reset(&payload); |
| 269 | - transport_flip(GLOBAL_URL()); | |
| 269 | + transport_flip(&g.url); | |
| 270 | 270 | |
| 271 | 271 | /* |
| 272 | 272 | ** Read and interpret the server reply |
| 273 | 273 | */ |
| 274 | 274 | closeConnection = 1; |
| 275 | 275 | iLength = -1; |
| 276 | - while( (zLine = transport_receive_line(GLOBAL_URL()))!=0 && zLine[0]!=0 ){ | |
| 276 | + while( (zLine = transport_receive_line(&g.url))!=0 && zLine[0]!=0 ){ | |
| 277 | 277 | /* printf("[%s]\n", zLine); fflush(stdout); */ |
| 278 | 278 | if( fossil_strnicmp(zLine, "http/1.", 7)==0 ){ |
| 279 | 279 | if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err; |
| 280 | 280 | if( rc==401 ){ |
| 281 | 281 | if( fSeenHttpAuth++ < MAX_HTTP_AUTH ){ |
| 282 | 282 | if( g.zHttpAuth ){ |
| 283 | 283 | if( g.zHttpAuth ) free(g.zHttpAuth); |
| 284 | 284 | } |
| 285 | 285 | g.zHttpAuth = prompt_for_httpauth_creds(); |
| 286 | - transport_close(GLOBAL_URL()); | |
| 286 | + transport_close(&g.url); | |
| 287 | 287 | return http_exchange(pSend, pReply, useLogin, maxRedirect); |
| 288 | 288 | } |
| 289 | 289 | } |
| 290 | 290 | if( rc!=200 && rc!=302 ){ |
| 291 | 291 | int ii; |
| @@ -297,11 +297,11 @@ | ||
| 297 | 297 | if( iHttpVersion==0 ){ |
| 298 | 298 | closeConnection = 1; |
| 299 | 299 | }else{ |
| 300 | 300 | closeConnection = 0; |
| 301 | 301 | } |
| 302 | - }else if( g.urlIsSsh && fossil_strnicmp(zLine, "status:", 7)==0 ){ | |
| 302 | + }else if( g.url.isSsh && fossil_strnicmp(zLine, "status:", 7)==0 ){ | |
| 303 | 303 | if( sscanf(zLine, "Status: %d", &rc)!=1 ) goto write_err; |
| 304 | 304 | if( rc!=200 && rc!=302 ){ |
| 305 | 305 | int ii; |
| 306 | 306 | for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){} |
| 307 | 307 | while( zLine[ii]==' ' ) ii++; |
| @@ -337,11 +337,11 @@ | ||
| 337 | 337 | fossil_print("redirect to %s\n", &zLine[i]); |
| 338 | 338 | url_parse(&zLine[i], 0); |
| 339 | 339 | fSeenHttpAuth = 0; |
| 340 | 340 | if( g.zHttpAuth ) free(g.zHttpAuth); |
| 341 | 341 | g.zHttpAuth = get_httpauth(); |
| 342 | - transport_close(GLOBAL_URL()); | |
| 342 | + transport_close(&g.url); | |
| 343 | 343 | return http_exchange(pSend, pReply, useLogin, maxRedirect); |
| 344 | 344 | }else if( fossil_strnicmp(zLine, "content-type: ", 14)==0 ){ |
| 345 | 345 | if( fossil_strnicmp(&zLine[14], "application/x-fossil-debug", -1)==0 ){ |
| 346 | 346 | isCompressed = 0; |
| 347 | 347 | }else if( fossil_strnicmp(&zLine[14], |
| @@ -364,11 +364,11 @@ | ||
| 364 | 364 | /* |
| 365 | 365 | ** Extract the reply payload that follows the header |
| 366 | 366 | */ |
| 367 | 367 | blob_zero(pReply); |
| 368 | 368 | blob_resize(pReply, iLength); |
| 369 | - iLength = transport_receive(GLOBAL_URL(), blob_buffer(pReply), iLength); | |
| 369 | + iLength = transport_receive(&g.url, blob_buffer(pReply), iLength); | |
| 370 | 370 | blob_resize(pReply, iLength); |
| 371 | 371 | if( isError ){ |
| 372 | 372 | char *z; |
| 373 | 373 | int i, j; |
| 374 | 374 | z = blob_str(pReply); |
| @@ -391,20 +391,20 @@ | ||
| 391 | 391 | ** connection from remaining open. The easiest fix for now is to |
| 392 | 392 | ** simply close and restart the connection for each round-trip. |
| 393 | 393 | ** |
| 394 | 394 | ** For SSH we will leave the connection open. |
| 395 | 395 | */ |
| 396 | - if( ! g.urlIsSsh ) closeConnection = 1; /* FIX ME */ | |
| 396 | + if( ! g.url.isSsh ) closeConnection = 1; /* FIX ME */ | |
| 397 | 397 | if( closeConnection ){ |
| 398 | - transport_close(GLOBAL_URL()); | |
| 398 | + transport_close(&g.url); | |
| 399 | 399 | }else{ |
| 400 | - transport_rewind(GLOBAL_URL()); | |
| 400 | + transport_rewind(&g.url); | |
| 401 | 401 | } |
| 402 | 402 | return 0; |
| 403 | 403 | |
| 404 | 404 | /* |
| 405 | 405 | ** Jump to here if an error is seen. |
| 406 | 406 | */ |
| 407 | 407 | write_err: |
| 408 | - transport_close(GLOBAL_URL()); | |
| 408 | + transport_close(&g.url); | |
| 409 | 409 | return 1; |
| 410 | 410 | } |
| 411 | 411 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -55,31 +55,31 @@ | |
| 55 | const char *zPw; /* The user password */ |
| 56 | Blob pw; /* The nonce with user password appended */ |
| 57 | Blob sig; /* The signature field */ |
| 58 | |
| 59 | blob_zero(pLogin); |
| 60 | if( g.urlUser==0 || fossil_strcmp(g.urlUser, "anonymous")==0 ){ |
| 61 | return; /* If no login card for users "nobody" and "anonymous" */ |
| 62 | } |
| 63 | if( g.urlIsSsh ){ |
| 64 | return; /* If no login card for SSH: */ |
| 65 | } |
| 66 | blob_zero(&nonce); |
| 67 | blob_zero(&pw); |
| 68 | sha1sum_blob(pPayload, &nonce); |
| 69 | blob_copy(&pw, &nonce); |
| 70 | zLogin = g.urlUser; |
| 71 | if( g.urlPasswd ){ |
| 72 | zPw = g.urlPasswd; |
| 73 | }else if( g.cgiOutput ){ |
| 74 | /* Password failure while doing a sync from the web interface */ |
| 75 | cgi_printf("*** incorrect or missing password for user %h\n", zLogin); |
| 76 | zPw = 0; |
| 77 | }else{ |
| 78 | /* Password failure while doing a sync from the command-line interface */ |
| 79 | url_prompt_for_password(); |
| 80 | zPw = g.urlPasswd; |
| 81 | } |
| 82 | |
| 83 | /* The login card wants the SHA1 hash of the password, so convert the |
| 84 | ** password to its SHA1 hash it it isn't already a SHA1 hash. |
| 85 | */ |
| @@ -102,29 +102,29 @@ | |
| 102 | static void http_build_header(Blob *pPayload, Blob *pHdr){ |
| 103 | int i; |
| 104 | const char *zSep; |
| 105 | |
| 106 | blob_zero(pHdr); |
| 107 | i = strlen(g.urlPath); |
| 108 | if( i>0 && g.urlPath[i-1]=='/' ){ |
| 109 | zSep = ""; |
| 110 | }else{ |
| 111 | zSep = "/"; |
| 112 | } |
| 113 | blob_appendf(pHdr, "POST %s%sxfer/xfer HTTP/1.0\r\n", g.urlPath, zSep); |
| 114 | if( g.urlProxyAuth ){ |
| 115 | blob_appendf(pHdr, "Proxy-Authorization: %s\r\n", g.urlProxyAuth); |
| 116 | } |
| 117 | if( g.zHttpAuth && g.zHttpAuth[0] ){ |
| 118 | const char *zCredentials = g.zHttpAuth; |
| 119 | char *zEncoded = encode64(zCredentials, -1); |
| 120 | blob_appendf(pHdr, "Authorization: Basic %s\r\n", zEncoded); |
| 121 | fossil_free(zEncoded); |
| 122 | } |
| 123 | blob_appendf(pHdr, "Host: %s\r\n", g.urlHostname); |
| 124 | blob_appendf(pHdr, "User-Agent: %s\r\n", get_user_agent()); |
| 125 | if( g.urlIsSsh ) blob_appendf(pHdr, "X-Fossil-Transport: SSH\r\n"); |
| 126 | if( g.fHttpTrace ){ |
| 127 | blob_appendf(pHdr, "Content-Type: application/x-fossil-debug\r\n"); |
| 128 | }else{ |
| 129 | blob_appendf(pHdr, "Content-Type: application/x-fossil\r\n"); |
| 130 | } |
| @@ -147,11 +147,11 @@ | |
| 147 | ** Prompt to save HTTP Basic Authorization information |
| 148 | */ |
| 149 | static int save_httpauth_prompt(void){ |
| 150 | Blob x; |
| 151 | char c; |
| 152 | if( (g.urlFlags & URL_REMEMBER)==0 ) return 0; |
| 153 | prompt_user("Remember Basic Authorization credentials (Y/n)? ", &x); |
| 154 | c = blob_str(&x)[0]; |
| 155 | blob_reset(&x); |
| 156 | return ( c!='n' && c!='N' ); |
| 157 | } |
| @@ -166,15 +166,15 @@ | |
| 166 | char *zPw; |
| 167 | char *zPrompt; |
| 168 | char *zHttpAuth = 0; |
| 169 | if( !isatty(fileno(stdin)) ) return 0; |
| 170 | zPrompt = mprintf("\n%s authorization required by\n%s\n", |
| 171 | g.urlIsHttps==1 ? "Encrypted HTTPS" : "Unencrypted HTTP", g.urlCanonical); |
| 172 | fossil_print(zPrompt); |
| 173 | free(zPrompt); |
| 174 | if ( g.urlUser && g.urlPasswd && use_fossil_creds_for_httpauth_prompt() ){ |
| 175 | zHttpAuth = mprintf("%s:%s", g.urlUser, g.urlPasswd); |
| 176 | }else{ |
| 177 | prompt_user("Basic Authorization user: ", &x); |
| 178 | zUser = mprintf("%b", &x); |
| 179 | zPrompt = mprintf("HTTP password for %b: ", &x); |
| 180 | blob_reset(&x); |
| @@ -213,12 +213,12 @@ | |
| 213 | char *zLine; /* A single line of the reply header */ |
| 214 | int i; /* Loop counter */ |
| 215 | int isError = 0; /* True if the reply is an error message */ |
| 216 | int isCompressed = 1; /* True if the reply is compressed */ |
| 217 | |
| 218 | if( transport_open(GLOBAL_URL()) ){ |
| 219 | fossil_warning(transport_errmsg(GLOBAL_URL())); |
| 220 | return 1; |
| 221 | } |
| 222 | |
| 223 | /* Construct the login card and prepare the complete payload */ |
| 224 | blob_zero(&login); |
| @@ -260,32 +260,32 @@ | |
| 260 | } |
| 261 | |
| 262 | /* |
| 263 | ** Send the request to the server. |
| 264 | */ |
| 265 | transport_send(GLOBAL_URL(), &hdr); |
| 266 | transport_send(GLOBAL_URL(), &payload); |
| 267 | blob_reset(&hdr); |
| 268 | blob_reset(&payload); |
| 269 | transport_flip(GLOBAL_URL()); |
| 270 | |
| 271 | /* |
| 272 | ** Read and interpret the server reply |
| 273 | */ |
| 274 | closeConnection = 1; |
| 275 | iLength = -1; |
| 276 | while( (zLine = transport_receive_line(GLOBAL_URL()))!=0 && zLine[0]!=0 ){ |
| 277 | /* printf("[%s]\n", zLine); fflush(stdout); */ |
| 278 | if( fossil_strnicmp(zLine, "http/1.", 7)==0 ){ |
| 279 | if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err; |
| 280 | if( rc==401 ){ |
| 281 | if( fSeenHttpAuth++ < MAX_HTTP_AUTH ){ |
| 282 | if( g.zHttpAuth ){ |
| 283 | if( g.zHttpAuth ) free(g.zHttpAuth); |
| 284 | } |
| 285 | g.zHttpAuth = prompt_for_httpauth_creds(); |
| 286 | transport_close(GLOBAL_URL()); |
| 287 | return http_exchange(pSend, pReply, useLogin, maxRedirect); |
| 288 | } |
| 289 | } |
| 290 | if( rc!=200 && rc!=302 ){ |
| 291 | int ii; |
| @@ -297,11 +297,11 @@ | |
| 297 | if( iHttpVersion==0 ){ |
| 298 | closeConnection = 1; |
| 299 | }else{ |
| 300 | closeConnection = 0; |
| 301 | } |
| 302 | }else if( g.urlIsSsh && fossil_strnicmp(zLine, "status:", 7)==0 ){ |
| 303 | if( sscanf(zLine, "Status: %d", &rc)!=1 ) goto write_err; |
| 304 | if( rc!=200 && rc!=302 ){ |
| 305 | int ii; |
| 306 | for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){} |
| 307 | while( zLine[ii]==' ' ) ii++; |
| @@ -337,11 +337,11 @@ | |
| 337 | fossil_print("redirect to %s\n", &zLine[i]); |
| 338 | url_parse(&zLine[i], 0); |
| 339 | fSeenHttpAuth = 0; |
| 340 | if( g.zHttpAuth ) free(g.zHttpAuth); |
| 341 | g.zHttpAuth = get_httpauth(); |
| 342 | transport_close(GLOBAL_URL()); |
| 343 | return http_exchange(pSend, pReply, useLogin, maxRedirect); |
| 344 | }else if( fossil_strnicmp(zLine, "content-type: ", 14)==0 ){ |
| 345 | if( fossil_strnicmp(&zLine[14], "application/x-fossil-debug", -1)==0 ){ |
| 346 | isCompressed = 0; |
| 347 | }else if( fossil_strnicmp(&zLine[14], |
| @@ -364,11 +364,11 @@ | |
| 364 | /* |
| 365 | ** Extract the reply payload that follows the header |
| 366 | */ |
| 367 | blob_zero(pReply); |
| 368 | blob_resize(pReply, iLength); |
| 369 | iLength = transport_receive(GLOBAL_URL(), blob_buffer(pReply), iLength); |
| 370 | blob_resize(pReply, iLength); |
| 371 | if( isError ){ |
| 372 | char *z; |
| 373 | int i, j; |
| 374 | z = blob_str(pReply); |
| @@ -391,20 +391,20 @@ | |
| 391 | ** connection from remaining open. The easiest fix for now is to |
| 392 | ** simply close and restart the connection for each round-trip. |
| 393 | ** |
| 394 | ** For SSH we will leave the connection open. |
| 395 | */ |
| 396 | if( ! g.urlIsSsh ) closeConnection = 1; /* FIX ME */ |
| 397 | if( closeConnection ){ |
| 398 | transport_close(GLOBAL_URL()); |
| 399 | }else{ |
| 400 | transport_rewind(GLOBAL_URL()); |
| 401 | } |
| 402 | return 0; |
| 403 | |
| 404 | /* |
| 405 | ** Jump to here if an error is seen. |
| 406 | */ |
| 407 | write_err: |
| 408 | transport_close(GLOBAL_URL()); |
| 409 | return 1; |
| 410 | } |
| 411 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -55,31 +55,31 @@ | |
| 55 | const char *zPw; /* The user password */ |
| 56 | Blob pw; /* The nonce with user password appended */ |
| 57 | Blob sig; /* The signature field */ |
| 58 | |
| 59 | blob_zero(pLogin); |
| 60 | if( g.url.user==0 || fossil_strcmp(g.url.user, "anonymous")==0 ){ |
| 61 | return; /* If no login card for users "nobody" and "anonymous" */ |
| 62 | } |
| 63 | if( g.url.isSsh ){ |
| 64 | return; /* If no login card for SSH: */ |
| 65 | } |
| 66 | blob_zero(&nonce); |
| 67 | blob_zero(&pw); |
| 68 | sha1sum_blob(pPayload, &nonce); |
| 69 | blob_copy(&pw, &nonce); |
| 70 | zLogin = g.url.user; |
| 71 | if( g.url.passwd ){ |
| 72 | zPw = g.url.passwd; |
| 73 | }else if( g.cgiOutput ){ |
| 74 | /* Password failure while doing a sync from the web interface */ |
| 75 | cgi_printf("*** incorrect or missing password for user %h\n", zLogin); |
| 76 | zPw = 0; |
| 77 | }else{ |
| 78 | /* Password failure while doing a sync from the command-line interface */ |
| 79 | url_prompt_for_password(); |
| 80 | zPw = g.url.passwd; |
| 81 | } |
| 82 | |
| 83 | /* The login card wants the SHA1 hash of the password, so convert the |
| 84 | ** password to its SHA1 hash it it isn't already a SHA1 hash. |
| 85 | */ |
| @@ -102,29 +102,29 @@ | |
| 102 | static void http_build_header(Blob *pPayload, Blob *pHdr){ |
| 103 | int i; |
| 104 | const char *zSep; |
| 105 | |
| 106 | blob_zero(pHdr); |
| 107 | i = strlen(g.url.path); |
| 108 | if( i>0 && g.url.path[i-1]=='/' ){ |
| 109 | zSep = ""; |
| 110 | }else{ |
| 111 | zSep = "/"; |
| 112 | } |
| 113 | blob_appendf(pHdr, "POST %s%sxfer/xfer HTTP/1.0\r\n", g.url.path, zSep); |
| 114 | if( g.url.proxyAuth ){ |
| 115 | blob_appendf(pHdr, "Proxy-Authorization: %s\r\n", g.url.proxyAuth); |
| 116 | } |
| 117 | if( g.zHttpAuth && g.zHttpAuth[0] ){ |
| 118 | const char *zCredentials = g.zHttpAuth; |
| 119 | char *zEncoded = encode64(zCredentials, -1); |
| 120 | blob_appendf(pHdr, "Authorization: Basic %s\r\n", zEncoded); |
| 121 | fossil_free(zEncoded); |
| 122 | } |
| 123 | blob_appendf(pHdr, "Host: %s\r\n", g.url.hostname); |
| 124 | blob_appendf(pHdr, "User-Agent: %s\r\n", get_user_agent()); |
| 125 | if( g.url.isSsh ) blob_appendf(pHdr, "X-Fossil-Transport: SSH\r\n"); |
| 126 | if( g.fHttpTrace ){ |
| 127 | blob_appendf(pHdr, "Content-Type: application/x-fossil-debug\r\n"); |
| 128 | }else{ |
| 129 | blob_appendf(pHdr, "Content-Type: application/x-fossil\r\n"); |
| 130 | } |
| @@ -147,11 +147,11 @@ | |
| 147 | ** Prompt to save HTTP Basic Authorization information |
| 148 | */ |
| 149 | static int save_httpauth_prompt(void){ |
| 150 | Blob x; |
| 151 | char c; |
| 152 | if( (g.url.flags & URL_REMEMBER)==0 ) return 0; |
| 153 | prompt_user("Remember Basic Authorization credentials (Y/n)? ", &x); |
| 154 | c = blob_str(&x)[0]; |
| 155 | blob_reset(&x); |
| 156 | return ( c!='n' && c!='N' ); |
| 157 | } |
| @@ -166,15 +166,15 @@ | |
| 166 | char *zPw; |
| 167 | char *zPrompt; |
| 168 | char *zHttpAuth = 0; |
| 169 | if( !isatty(fileno(stdin)) ) return 0; |
| 170 | zPrompt = mprintf("\n%s authorization required by\n%s\n", |
| 171 | g.url.isHttps==1 ? "Encrypted HTTPS" : "Unencrypted HTTP", g.url.canonical); |
| 172 | fossil_print(zPrompt); |
| 173 | free(zPrompt); |
| 174 | if ( g.url.user && g.url.passwd && use_fossil_creds_for_httpauth_prompt() ){ |
| 175 | zHttpAuth = mprintf("%s:%s", g.url.user, g.url.passwd); |
| 176 | }else{ |
| 177 | prompt_user("Basic Authorization user: ", &x); |
| 178 | zUser = mprintf("%b", &x); |
| 179 | zPrompt = mprintf("HTTP password for %b: ", &x); |
| 180 | blob_reset(&x); |
| @@ -213,12 +213,12 @@ | |
| 213 | char *zLine; /* A single line of the reply header */ |
| 214 | int i; /* Loop counter */ |
| 215 | int isError = 0; /* True if the reply is an error message */ |
| 216 | int isCompressed = 1; /* True if the reply is compressed */ |
| 217 | |
| 218 | if( transport_open(&g.url) ){ |
| 219 | fossil_warning(transport_errmsg(&g.url)); |
| 220 | return 1; |
| 221 | } |
| 222 | |
| 223 | /* Construct the login card and prepare the complete payload */ |
| 224 | blob_zero(&login); |
| @@ -260,32 +260,32 @@ | |
| 260 | } |
| 261 | |
| 262 | /* |
| 263 | ** Send the request to the server. |
| 264 | */ |
| 265 | transport_send(&g.url, &hdr); |
| 266 | transport_send(&g.url, &payload); |
| 267 | blob_reset(&hdr); |
| 268 | blob_reset(&payload); |
| 269 | transport_flip(&g.url); |
| 270 | |
| 271 | /* |
| 272 | ** Read and interpret the server reply |
| 273 | */ |
| 274 | closeConnection = 1; |
| 275 | iLength = -1; |
| 276 | while( (zLine = transport_receive_line(&g.url))!=0 && zLine[0]!=0 ){ |
| 277 | /* printf("[%s]\n", zLine); fflush(stdout); */ |
| 278 | if( fossil_strnicmp(zLine, "http/1.", 7)==0 ){ |
| 279 | if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err; |
| 280 | if( rc==401 ){ |
| 281 | if( fSeenHttpAuth++ < MAX_HTTP_AUTH ){ |
| 282 | if( g.zHttpAuth ){ |
| 283 | if( g.zHttpAuth ) free(g.zHttpAuth); |
| 284 | } |
| 285 | g.zHttpAuth = prompt_for_httpauth_creds(); |
| 286 | transport_close(&g.url); |
| 287 | return http_exchange(pSend, pReply, useLogin, maxRedirect); |
| 288 | } |
| 289 | } |
| 290 | if( rc!=200 && rc!=302 ){ |
| 291 | int ii; |
| @@ -297,11 +297,11 @@ | |
| 297 | if( iHttpVersion==0 ){ |
| 298 | closeConnection = 1; |
| 299 | }else{ |
| 300 | closeConnection = 0; |
| 301 | } |
| 302 | }else if( g.url.isSsh && fossil_strnicmp(zLine, "status:", 7)==0 ){ |
| 303 | if( sscanf(zLine, "Status: %d", &rc)!=1 ) goto write_err; |
| 304 | if( rc!=200 && rc!=302 ){ |
| 305 | int ii; |
| 306 | for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){} |
| 307 | while( zLine[ii]==' ' ) ii++; |
| @@ -337,11 +337,11 @@ | |
| 337 | fossil_print("redirect to %s\n", &zLine[i]); |
| 338 | url_parse(&zLine[i], 0); |
| 339 | fSeenHttpAuth = 0; |
| 340 | if( g.zHttpAuth ) free(g.zHttpAuth); |
| 341 | g.zHttpAuth = get_httpauth(); |
| 342 | transport_close(&g.url); |
| 343 | return http_exchange(pSend, pReply, useLogin, maxRedirect); |
| 344 | }else if( fossil_strnicmp(zLine, "content-type: ", 14)==0 ){ |
| 345 | if( fossil_strnicmp(&zLine[14], "application/x-fossil-debug", -1)==0 ){ |
| 346 | isCompressed = 0; |
| 347 | }else if( fossil_strnicmp(&zLine[14], |
| @@ -364,11 +364,11 @@ | |
| 364 | /* |
| 365 | ** Extract the reply payload that follows the header |
| 366 | */ |
| 367 | blob_zero(pReply); |
| 368 | blob_resize(pReply, iLength); |
| 369 | iLength = transport_receive(&g.url, blob_buffer(pReply), iLength); |
| 370 | blob_resize(pReply, iLength); |
| 371 | if( isError ){ |
| 372 | char *z; |
| 373 | int i, j; |
| 374 | z = blob_str(pReply); |
| @@ -391,20 +391,20 @@ | |
| 391 | ** connection from remaining open. The easiest fix for now is to |
| 392 | ** simply close and restart the connection for each round-trip. |
| 393 | ** |
| 394 | ** For SSH we will leave the connection open. |
| 395 | */ |
| 396 | if( ! g.url.isSsh ) closeConnection = 1; /* FIX ME */ |
| 397 | if( closeConnection ){ |
| 398 | transport_close(&g.url); |
| 399 | }else{ |
| 400 | transport_rewind(&g.url); |
| 401 | } |
| 402 | return 0; |
| 403 | |
| 404 | /* |
| 405 | ** Jump to here if an error is seen. |
| 406 | */ |
| 407 | write_err: |
| 408 | transport_close(&g.url); |
| 409 | return 1; |
| 410 | } |
| 411 |
+7
-6
| --- src/http_socket.c | ||
| +++ src/http_socket.c | ||
| @@ -124,14 +124,14 @@ | ||
| 124 | 124 | } |
| 125 | 125 | } |
| 126 | 126 | |
| 127 | 127 | /* |
| 128 | 128 | ** Open a socket connection. The identify of the server is determined |
| 129 | -** by global variables that are set using url_parse(): | |
| 129 | +** by pUrlData | |
| 130 | 130 | ** |
| 131 | -** g.urlName Name of the server. Ex: www.fossil-scm.org | |
| 132 | -** g.urlPort TCP/IP port to use. Ex: 80 | |
| 131 | +** pUrlDAta->name Name of the server. Ex: www.fossil-scm.org | |
| 132 | +** pUrlDAta->port TCP/IP port to use. Ex: 80 | |
| 133 | 133 | ** |
| 134 | 134 | ** Return the number of errors. |
| 135 | 135 | */ |
| 136 | 136 | int socket_open(UrlData *pUrlData){ |
| 137 | 137 | static struct sockaddr_in addr; /* The server address */ |
| @@ -212,13 +212,14 @@ | ||
| 212 | 212 | } |
| 213 | 213 | return total; |
| 214 | 214 | } |
| 215 | 215 | |
| 216 | 216 | /* |
| 217 | -** Attempt to resolve g.urlName to IP and setup g.zIpAddr so rcvfrom gets | |
| 218 | -** populated. For hostnames with more than one IP (or if overridden in | |
| 219 | -** ~/.ssh/config) the rcvfrom may not match the host to which we connect. | |
| 217 | +** Attempt to resolve pUrlData->name to an IP address and setup g.zIpAddr | |
| 218 | +** so rcvfrom gets populated. For hostnames with more than one IP (or | |
| 219 | +** if overridden in ~/.ssh/config) the rcvfrom may not match the host | |
| 220 | +** to which we connect. | |
| 220 | 221 | */ |
| 221 | 222 | void socket_ssh_resolve_addr(UrlData *pUrlData){ |
| 222 | 223 | struct hostent *pHost; /* Used to make best effort for rcvfrom */ |
| 223 | 224 | struct sockaddr_in addr; |
| 224 | 225 | |
| 225 | 226 |
| --- src/http_socket.c | |
| +++ src/http_socket.c | |
| @@ -124,14 +124,14 @@ | |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | /* |
| 128 | ** Open a socket connection. The identify of the server is determined |
| 129 | ** by global variables that are set using url_parse(): |
| 130 | ** |
| 131 | ** g.urlName Name of the server. Ex: www.fossil-scm.org |
| 132 | ** g.urlPort TCP/IP port to use. Ex: 80 |
| 133 | ** |
| 134 | ** Return the number of errors. |
| 135 | */ |
| 136 | int socket_open(UrlData *pUrlData){ |
| 137 | static struct sockaddr_in addr; /* The server address */ |
| @@ -212,13 +212,14 @@ | |
| 212 | } |
| 213 | return total; |
| 214 | } |
| 215 | |
| 216 | /* |
| 217 | ** Attempt to resolve g.urlName to IP and setup g.zIpAddr so rcvfrom gets |
| 218 | ** populated. For hostnames with more than one IP (or if overridden in |
| 219 | ** ~/.ssh/config) the rcvfrom may not match the host to which we connect. |
| 220 | */ |
| 221 | void socket_ssh_resolve_addr(UrlData *pUrlData){ |
| 222 | struct hostent *pHost; /* Used to make best effort for rcvfrom */ |
| 223 | struct sockaddr_in addr; |
| 224 | |
| 225 |
| --- src/http_socket.c | |
| +++ src/http_socket.c | |
| @@ -124,14 +124,14 @@ | |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | /* |
| 128 | ** Open a socket connection. The identify of the server is determined |
| 129 | ** by pUrlData |
| 130 | ** |
| 131 | ** pUrlDAta->name Name of the server. Ex: www.fossil-scm.org |
| 132 | ** pUrlDAta->port TCP/IP port to use. Ex: 80 |
| 133 | ** |
| 134 | ** Return the number of errors. |
| 135 | */ |
| 136 | int socket_open(UrlData *pUrlData){ |
| 137 | static struct sockaddr_in addr; /* The server address */ |
| @@ -212,13 +212,14 @@ | |
| 212 | } |
| 213 | return total; |
| 214 | } |
| 215 | |
| 216 | /* |
| 217 | ** Attempt to resolve pUrlData->name to an IP address and setup g.zIpAddr |
| 218 | ** so rcvfrom gets populated. For hostnames with more than one IP (or |
| 219 | ** if overridden in ~/.ssh/config) the rcvfrom may not match the host |
| 220 | ** to which we connect. |
| 221 | */ |
| 222 | void socket_ssh_resolve_addr(UrlData *pUrlData){ |
| 223 | struct hostent *pHost; /* Used to make best effort for rcvfrom */ |
| 224 | struct sockaddr_in addr; |
| 225 | |
| 226 |
+8
-6
| --- src/http_ssl.c | ||
| +++ src/http_ssl.c | ||
| @@ -224,13 +224,13 @@ | ||
| 224 | 224 | return rc; |
| 225 | 225 | } |
| 226 | 226 | |
| 227 | 227 | /* |
| 228 | 228 | ** Open an SSL connection. The identify of the server is determined |
| 229 | -** by variables that are set using url_parse(): | |
| 229 | +** as follows: | |
| 230 | 230 | ** |
| 231 | -** pUrlData->name Name of the server. Ex: www.fossil-scm.org | |
| 231 | +** g.url.name Name of the server. Ex: www.fossil-scm.org | |
| 232 | 232 | ** pUrlData->port TCP/IP port to use. Ex: 80 |
| 233 | 233 | ** |
| 234 | 234 | ** Return the number of errors. |
| 235 | 235 | */ |
| 236 | 236 | int ssl_open(UrlData *pUrlData){ |
| @@ -253,11 +253,11 @@ | ||
| 253 | 253 | |
| 254 | 254 | if( pUrlData->useProxy ){ |
| 255 | 255 | int rc; |
| 256 | 256 | BIO *sBio; |
| 257 | 257 | char *connStr; |
| 258 | - connStr = mprintf("%s:%d", g.urlName, pUrlData->port); | |
| 258 | + connStr = mprintf("%s:%d", g.url.name, pUrlData->port); | |
| 259 | 259 | sBio = BIO_new_connect(connStr); |
| 260 | 260 | free(connStr); |
| 261 | 261 | if( BIO_do_connect(sBio)<=0 ){ |
| 262 | 262 | ssl_set_errmsg("SSL: cannot connect to proxy %s:%d (%s)", |
| 263 | 263 | pUrlData->name, pUrlData->port, ERR_reason_error_string(ERR_get_error())); |
| @@ -417,26 +417,28 @@ | ||
| 417 | 417 | free(zHost); |
| 418 | 418 | BIO_free(mem); |
| 419 | 419 | } |
| 420 | 420 | |
| 421 | 421 | /* |
| 422 | -** Get certificate for g.urlName from global config. | |
| 422 | +** Get certificate for pUrlData->urlName from global config. | |
| 423 | 423 | ** Return NULL if no certificate found. |
| 424 | 424 | */ |
| 425 | 425 | X509 *ssl_get_certificate(UrlData *pUrlData, int *pTrusted){ |
| 426 | 426 | char *zHost, *zCert; |
| 427 | 427 | BIO *mem; |
| 428 | 428 | X509 *cert; |
| 429 | 429 | |
| 430 | - zHost = mprintf("cert:%s", pUrlData->useProxy?pUrlData->hostname:pUrlData->name); | |
| 430 | + zHost = mprintf("cert:%s", | |
| 431 | + pUrlData->useProxy ? pUrlData->hostname : pUrlData->name); | |
| 431 | 432 | zCert = db_get(zHost, NULL); |
| 432 | 433 | free(zHost); |
| 433 | 434 | if ( zCert==NULL ) |
| 434 | 435 | return NULL; |
| 435 | 436 | |
| 436 | 437 | if ( pTrusted!=0 ){ |
| 437 | - zHost = mprintf("trusted:%s", pUrlData->useProxy?pUrlData->hostname:pUrlData->name); | |
| 438 | + zHost = mprintf("trusted:%s", | |
| 439 | + pUrlData->useProxy ? pUrlData->hostname : pUrlData->name); | |
| 438 | 440 | *pTrusted = db_get_int(zHost, 0); |
| 439 | 441 | free(zHost); |
| 440 | 442 | } |
| 441 | 443 | |
| 442 | 444 | mem = BIO_new(BIO_s_mem()); |
| 443 | 445 |
| --- src/http_ssl.c | |
| +++ src/http_ssl.c | |
| @@ -224,13 +224,13 @@ | |
| 224 | return rc; |
| 225 | } |
| 226 | |
| 227 | /* |
| 228 | ** Open an SSL connection. The identify of the server is determined |
| 229 | ** by variables that are set using url_parse(): |
| 230 | ** |
| 231 | ** pUrlData->name Name of the server. Ex: www.fossil-scm.org |
| 232 | ** pUrlData->port TCP/IP port to use. Ex: 80 |
| 233 | ** |
| 234 | ** Return the number of errors. |
| 235 | */ |
| 236 | int ssl_open(UrlData *pUrlData){ |
| @@ -253,11 +253,11 @@ | |
| 253 | |
| 254 | if( pUrlData->useProxy ){ |
| 255 | int rc; |
| 256 | BIO *sBio; |
| 257 | char *connStr; |
| 258 | connStr = mprintf("%s:%d", g.urlName, pUrlData->port); |
| 259 | sBio = BIO_new_connect(connStr); |
| 260 | free(connStr); |
| 261 | if( BIO_do_connect(sBio)<=0 ){ |
| 262 | ssl_set_errmsg("SSL: cannot connect to proxy %s:%d (%s)", |
| 263 | pUrlData->name, pUrlData->port, ERR_reason_error_string(ERR_get_error())); |
| @@ -417,26 +417,28 @@ | |
| 417 | free(zHost); |
| 418 | BIO_free(mem); |
| 419 | } |
| 420 | |
| 421 | /* |
| 422 | ** Get certificate for g.urlName from global config. |
| 423 | ** Return NULL if no certificate found. |
| 424 | */ |
| 425 | X509 *ssl_get_certificate(UrlData *pUrlData, int *pTrusted){ |
| 426 | char *zHost, *zCert; |
| 427 | BIO *mem; |
| 428 | X509 *cert; |
| 429 | |
| 430 | zHost = mprintf("cert:%s", pUrlData->useProxy?pUrlData->hostname:pUrlData->name); |
| 431 | zCert = db_get(zHost, NULL); |
| 432 | free(zHost); |
| 433 | if ( zCert==NULL ) |
| 434 | return NULL; |
| 435 | |
| 436 | if ( pTrusted!=0 ){ |
| 437 | zHost = mprintf("trusted:%s", pUrlData->useProxy?pUrlData->hostname:pUrlData->name); |
| 438 | *pTrusted = db_get_int(zHost, 0); |
| 439 | free(zHost); |
| 440 | } |
| 441 | |
| 442 | mem = BIO_new(BIO_s_mem()); |
| 443 |
| --- src/http_ssl.c | |
| +++ src/http_ssl.c | |
| @@ -224,13 +224,13 @@ | |
| 224 | return rc; |
| 225 | } |
| 226 | |
| 227 | /* |
| 228 | ** Open an SSL connection. The identify of the server is determined |
| 229 | ** as follows: |
| 230 | ** |
| 231 | ** g.url.name Name of the server. Ex: www.fossil-scm.org |
| 232 | ** pUrlData->port TCP/IP port to use. Ex: 80 |
| 233 | ** |
| 234 | ** Return the number of errors. |
| 235 | */ |
| 236 | int ssl_open(UrlData *pUrlData){ |
| @@ -253,11 +253,11 @@ | |
| 253 | |
| 254 | if( pUrlData->useProxy ){ |
| 255 | int rc; |
| 256 | BIO *sBio; |
| 257 | char *connStr; |
| 258 | connStr = mprintf("%s:%d", g.url.name, pUrlData->port); |
| 259 | sBio = BIO_new_connect(connStr); |
| 260 | free(connStr); |
| 261 | if( BIO_do_connect(sBio)<=0 ){ |
| 262 | ssl_set_errmsg("SSL: cannot connect to proxy %s:%d (%s)", |
| 263 | pUrlData->name, pUrlData->port, ERR_reason_error_string(ERR_get_error())); |
| @@ -417,26 +417,28 @@ | |
| 417 | free(zHost); |
| 418 | BIO_free(mem); |
| 419 | } |
| 420 | |
| 421 | /* |
| 422 | ** Get certificate for pUrlData->urlName from global config. |
| 423 | ** Return NULL if no certificate found. |
| 424 | */ |
| 425 | X509 *ssl_get_certificate(UrlData *pUrlData, int *pTrusted){ |
| 426 | char *zHost, *zCert; |
| 427 | BIO *mem; |
| 428 | X509 *cert; |
| 429 | |
| 430 | zHost = mprintf("cert:%s", |
| 431 | pUrlData->useProxy ? pUrlData->hostname : pUrlData->name); |
| 432 | zCert = db_get(zHost, NULL); |
| 433 | free(zHost); |
| 434 | if ( zCert==NULL ) |
| 435 | return NULL; |
| 436 | |
| 437 | if ( pTrusted!=0 ){ |
| 438 | zHost = mprintf("trusted:%s", |
| 439 | pUrlData->useProxy ? pUrlData->hostname : pUrlData->name); |
| 440 | *pTrusted = db_get_int(zHost, 0); |
| 441 | free(zHost); |
| 442 | } |
| 443 | |
| 444 | mem = BIO_new(BIO_s_mem()); |
| 445 |
+4
-4
| --- src/http_transport.c | ||
| +++ src/http_transport.c | ||
| @@ -138,15 +138,15 @@ | ||
| 138 | 138 | return sshPid==0; |
| 139 | 139 | } |
| 140 | 140 | |
| 141 | 141 | /* |
| 142 | 142 | ** Open a connection to the server. The server is defined by the following |
| 143 | -** global variables: | |
| 143 | +** variables: | |
| 144 | 144 | ** |
| 145 | -** g.urlName Name of the server. Ex: www.fossil-scm.org | |
| 146 | -** g.urlPort TCP/IP port. Ex: 80 | |
| 147 | -** g.urlIsHttps Use TLS for the connection | |
| 145 | +** pUrlData->name Name of the server. Ex: www.fossil-scm.org | |
| 146 | +** pUrlData->port TCP/IP port. Ex: 80 | |
| 147 | +** pUrlData->isHttps Use TLS for the connection | |
| 148 | 148 | ** |
| 149 | 149 | ** Return the number of errors. |
| 150 | 150 | */ |
| 151 | 151 | int transport_open(UrlData *pUrlData){ |
| 152 | 152 | int rc = 0; |
| 153 | 153 |
| --- src/http_transport.c | |
| +++ src/http_transport.c | |
| @@ -138,15 +138,15 @@ | |
| 138 | return sshPid==0; |
| 139 | } |
| 140 | |
| 141 | /* |
| 142 | ** Open a connection to the server. The server is defined by the following |
| 143 | ** global variables: |
| 144 | ** |
| 145 | ** g.urlName Name of the server. Ex: www.fossil-scm.org |
| 146 | ** g.urlPort TCP/IP port. Ex: 80 |
| 147 | ** g.urlIsHttps Use TLS for the connection |
| 148 | ** |
| 149 | ** Return the number of errors. |
| 150 | */ |
| 151 | int transport_open(UrlData *pUrlData){ |
| 152 | int rc = 0; |
| 153 |
| --- src/http_transport.c | |
| +++ src/http_transport.c | |
| @@ -138,15 +138,15 @@ | |
| 138 | return sshPid==0; |
| 139 | } |
| 140 | |
| 141 | /* |
| 142 | ** Open a connection to the server. The server is defined by the following |
| 143 | ** variables: |
| 144 | ** |
| 145 | ** pUrlData->name Name of the server. Ex: www.fossil-scm.org |
| 146 | ** pUrlData->port TCP/IP port. Ex: 80 |
| 147 | ** pUrlData->isHttps Use TLS for the connection |
| 148 | ** |
| 149 | ** Return the number of errors. |
| 150 | */ |
| 151 | int transport_open(UrlData *pUrlData){ |
| 152 | int rc = 0; |
| 153 |
+4
-6
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -112,15 +112,10 @@ | ||
| 112 | 112 | void *xPostEval; /* Optional, called after Tcl_Eval*(). */ |
| 113 | 113 | void *pPostContext; /* Optional, provided to xPostEval(). */ |
| 114 | 114 | }; |
| 115 | 115 | #endif |
| 116 | 116 | |
| 117 | -/* | |
| 118 | -** All global variables are in this structure. | |
| 119 | -*/ | |
| 120 | -#define GLOBAL_URL() ((UrlData *)(&g.urlIsFile)) | |
| 121 | - | |
| 122 | 117 | struct Global { |
| 123 | 118 | int argc; char **argv; /* Command-line arguments to the program */ |
| 124 | 119 | char *nameOfExe; /* Full path of executable. */ |
| 125 | 120 | const char *zErrlog; /* Log errors to this file, if not NULL */ |
| 126 | 121 | int isConst; /* True if the output is unchanging & cacheable */ |
| @@ -171,11 +166,12 @@ | ||
| 171 | 166 | int clockSkewSeen; /* True if clocks on client and server out of sync */ |
| 172 | 167 | int wikiFlags; /* Wiki conversion flags applied to %w and %W */ |
| 173 | 168 | char isHTTP; /* True if server/CGI modes, else assume CLI. */ |
| 174 | 169 | char javascriptHyperlink; /* If true, set href= using script, not HTML */ |
| 175 | 170 | Blob httpHeader; /* Complete text of the HTTP request header */ |
| 176 | - | |
| 171 | + UrlData url; /* Information about current URL */ | |
| 172 | +#if 0 | |
| 177 | 173 | /* |
| 178 | 174 | ** NOTE: These members MUST be kept in sync with those in the "UrlData" |
| 179 | 175 | ** structure defined in "url.c". |
| 180 | 176 | */ |
| 181 | 177 | int urlIsFile; /* True if a "file:" url */ |
| @@ -194,10 +190,12 @@ | ||
| 194 | 190 | char *urlFossil; /* The fossil query parameter on ssh: */ |
| 195 | 191 | unsigned urlFlags; /* Boolean flags controlling URL processing */ |
| 196 | 192 | int useProxy; /* Used to remember that a proxy is in use */ |
| 197 | 193 | char *proxyUrlPath; |
| 198 | 194 | int proxyOrigPort; /* Tunneled port number for https through proxy */ |
| 195 | +#endif | |
| 196 | + | |
| 199 | 197 | const char *zLogin; /* Login name. NULL or "" if not logged in. */ |
| 200 | 198 | const char *zSSLIdentity; /* Value of --ssl-identity option, filename of |
| 201 | 199 | ** SSL client identity */ |
| 202 | 200 | int useLocalauth; /* No login required if from 127.0.0.1 */ |
| 203 | 201 | int noPswd; /* Logged in without password (on 127.0.0.1) */ |
| 204 | 202 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -112,15 +112,10 @@ | |
| 112 | void *xPostEval; /* Optional, called after Tcl_Eval*(). */ |
| 113 | void *pPostContext; /* Optional, provided to xPostEval(). */ |
| 114 | }; |
| 115 | #endif |
| 116 | |
| 117 | /* |
| 118 | ** All global variables are in this structure. |
| 119 | */ |
| 120 | #define GLOBAL_URL() ((UrlData *)(&g.urlIsFile)) |
| 121 | |
| 122 | struct Global { |
| 123 | int argc; char **argv; /* Command-line arguments to the program */ |
| 124 | char *nameOfExe; /* Full path of executable. */ |
| 125 | const char *zErrlog; /* Log errors to this file, if not NULL */ |
| 126 | int isConst; /* True if the output is unchanging & cacheable */ |
| @@ -171,11 +166,12 @@ | |
| 171 | int clockSkewSeen; /* True if clocks on client and server out of sync */ |
| 172 | int wikiFlags; /* Wiki conversion flags applied to %w and %W */ |
| 173 | char isHTTP; /* True if server/CGI modes, else assume CLI. */ |
| 174 | char javascriptHyperlink; /* If true, set href= using script, not HTML */ |
| 175 | Blob httpHeader; /* Complete text of the HTTP request header */ |
| 176 | |
| 177 | /* |
| 178 | ** NOTE: These members MUST be kept in sync with those in the "UrlData" |
| 179 | ** structure defined in "url.c". |
| 180 | */ |
| 181 | int urlIsFile; /* True if a "file:" url */ |
| @@ -194,10 +190,12 @@ | |
| 194 | char *urlFossil; /* The fossil query parameter on ssh: */ |
| 195 | unsigned urlFlags; /* Boolean flags controlling URL processing */ |
| 196 | int useProxy; /* Used to remember that a proxy is in use */ |
| 197 | char *proxyUrlPath; |
| 198 | int proxyOrigPort; /* Tunneled port number for https through proxy */ |
| 199 | const char *zLogin; /* Login name. NULL or "" if not logged in. */ |
| 200 | const char *zSSLIdentity; /* Value of --ssl-identity option, filename of |
| 201 | ** SSL client identity */ |
| 202 | int useLocalauth; /* No login required if from 127.0.0.1 */ |
| 203 | int noPswd; /* Logged in without password (on 127.0.0.1) */ |
| 204 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -112,15 +112,10 @@ | |
| 112 | void *xPostEval; /* Optional, called after Tcl_Eval*(). */ |
| 113 | void *pPostContext; /* Optional, provided to xPostEval(). */ |
| 114 | }; |
| 115 | #endif |
| 116 | |
| 117 | struct Global { |
| 118 | int argc; char **argv; /* Command-line arguments to the program */ |
| 119 | char *nameOfExe; /* Full path of executable. */ |
| 120 | const char *zErrlog; /* Log errors to this file, if not NULL */ |
| 121 | int isConst; /* True if the output is unchanging & cacheable */ |
| @@ -171,11 +166,12 @@ | |
| 166 | int clockSkewSeen; /* True if clocks on client and server out of sync */ |
| 167 | int wikiFlags; /* Wiki conversion flags applied to %w and %W */ |
| 168 | char isHTTP; /* True if server/CGI modes, else assume CLI. */ |
| 169 | char javascriptHyperlink; /* If true, set href= using script, not HTML */ |
| 170 | Blob httpHeader; /* Complete text of the HTTP request header */ |
| 171 | UrlData url; /* Information about current URL */ |
| 172 | #if 0 |
| 173 | /* |
| 174 | ** NOTE: These members MUST be kept in sync with those in the "UrlData" |
| 175 | ** structure defined in "url.c". |
| 176 | */ |
| 177 | int urlIsFile; /* True if a "file:" url */ |
| @@ -194,10 +190,12 @@ | |
| 190 | char *urlFossil; /* The fossil query parameter on ssh: */ |
| 191 | unsigned urlFlags; /* Boolean flags controlling URL processing */ |
| 192 | int useProxy; /* Used to remember that a proxy is in use */ |
| 193 | char *proxyUrlPath; |
| 194 | int proxyOrigPort; /* Tunneled port number for https through proxy */ |
| 195 | #endif |
| 196 | |
| 197 | const char *zLogin; /* Login name. NULL or "" if not logged in. */ |
| 198 | const char *zSSLIdentity; /* Value of --ssl-identity option, filename of |
| 199 | ** SSL client identity */ |
| 200 | int useLocalauth; /* No login required if from 127.0.0.1 */ |
| 201 | int noPswd; /* Logged in without password (on 127.0.0.1) */ |
| 202 |
+10
-10
| --- src/sync.c | ||
| +++ src/sync.c | ||
| @@ -48,14 +48,14 @@ | ||
| 48 | 48 | } |
| 49 | 49 | }else{ |
| 50 | 50 | /* Autosync defaults on. To make it default off, "return" here. */ |
| 51 | 51 | } |
| 52 | 52 | url_parse(0, URL_REMEMBER); |
| 53 | - if( g.urlProtocol==0 ) return 0; | |
| 54 | - if( g.urlUser!=0 && g.urlPasswd==0 ){ | |
| 55 | - g.urlPasswd = unobscure(db_get("last-sync-pw", 0)); | |
| 56 | - g.urlFlags |= URL_PROMPT_PW; | |
| 53 | + if( g.url.protocol==0 ) return 0; | |
| 54 | + if( g.url.user!=0 && g.url.passwd==0 ){ | |
| 55 | + g.url.passwd = unobscure(db_get("last-sync-pw", 0)); | |
| 56 | + g.url.flags |= URL_PROMPT_PW; | |
| 57 | 57 | url_prompt_for_password(); |
| 58 | 58 | } |
| 59 | 59 | g.zHttpAuth = get_httpauth(); |
| 60 | 60 | url_remember(); |
| 61 | 61 | #if 0 /* Disabled for now */ |
| @@ -69,11 +69,11 @@ | ||
| 69 | 69 | */ |
| 70 | 70 | configSync = CONFIGSET_SHUN; |
| 71 | 71 | } |
| 72 | 72 | #endif |
| 73 | 73 | if( find_option("verbose","v",0)!=0 ) flags |= SYNC_VERBOSE; |
| 74 | - fossil_print("Autosync: %s\n", g.urlCanonical); | |
| 74 | + fossil_print("Autosync: %s\n", g.url.canonical); | |
| 75 | 75 | url_enable_proxy("via proxy: "); |
| 76 | 76 | rc = client_sync(flags, configSync, 0); |
| 77 | 77 | if( rc ) fossil_warning("Autosync failed"); |
| 78 | 78 | return rc; |
| 79 | 79 | } |
| @@ -121,22 +121,22 @@ | ||
| 121 | 121 | clone_ssh_db_set_options(); |
| 122 | 122 | } |
| 123 | 123 | url_parse(zUrl, urlFlags); |
| 124 | 124 | remember_or_get_http_auth(zHttpAuth, urlFlags & URL_REMEMBER, zUrl); |
| 125 | 125 | url_remember(); |
| 126 | - if( g.urlProtocol==0 ){ | |
| 126 | + if( g.url.protocol==0 ){ | |
| 127 | 127 | if( urlOptional ) fossil_exit(0); |
| 128 | 128 | usage("URL"); |
| 129 | 129 | } |
| 130 | 130 | user_select(); |
| 131 | 131 | if( g.argc==2 ){ |
| 132 | 132 | if( ((*pSyncFlags) & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL) ){ |
| 133 | - fossil_print("Sync with %s\n", g.urlCanonical); | |
| 133 | + fossil_print("Sync with %s\n", g.url.canonical); | |
| 134 | 134 | }else if( (*pSyncFlags) & SYNC_PUSH ){ |
| 135 | - fossil_print("Push to %s\n", g.urlCanonical); | |
| 135 | + fossil_print("Push to %s\n", g.url.canonical); | |
| 136 | 136 | }else if( (*pSyncFlags) & SYNC_PULL ){ |
| 137 | - fossil_print("Pull from %s\n", g.urlCanonical); | |
| 137 | + fossil_print("Pull from %s\n", g.url.canonical); | |
| 138 | 138 | } |
| 139 | 139 | } |
| 140 | 140 | url_enable_proxy("via proxy: "); |
| 141 | 141 | *pConfigFlags |= configSync; |
| 142 | 142 | } |
| @@ -278,8 +278,8 @@ | ||
| 278 | 278 | if( zUrl==0 ){ |
| 279 | 279 | fossil_print("off\n"); |
| 280 | 280 | return; |
| 281 | 281 | }else{ |
| 282 | 282 | url_parse(zUrl, 0); |
| 283 | - fossil_print("%s\n", g.urlCanonical); | |
| 283 | + fossil_print("%s\n", g.url.canonical); | |
| 284 | 284 | } |
| 285 | 285 | } |
| 286 | 286 |
| --- src/sync.c | |
| +++ src/sync.c | |
| @@ -48,14 +48,14 @@ | |
| 48 | } |
| 49 | }else{ |
| 50 | /* Autosync defaults on. To make it default off, "return" here. */ |
| 51 | } |
| 52 | url_parse(0, URL_REMEMBER); |
| 53 | if( g.urlProtocol==0 ) return 0; |
| 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 | g.zHttpAuth = get_httpauth(); |
| 60 | url_remember(); |
| 61 | #if 0 /* Disabled for now */ |
| @@ -69,11 +69,11 @@ | |
| 69 | */ |
| 70 | configSync = CONFIGSET_SHUN; |
| 71 | } |
| 72 | #endif |
| 73 | if( find_option("verbose","v",0)!=0 ) flags |= SYNC_VERBOSE; |
| 74 | fossil_print("Autosync: %s\n", g.urlCanonical); |
| 75 | url_enable_proxy("via proxy: "); |
| 76 | rc = client_sync(flags, configSync, 0); |
| 77 | if( rc ) fossil_warning("Autosync failed"); |
| 78 | return rc; |
| 79 | } |
| @@ -121,22 +121,22 @@ | |
| 121 | clone_ssh_db_set_options(); |
| 122 | } |
| 123 | url_parse(zUrl, urlFlags); |
| 124 | remember_or_get_http_auth(zHttpAuth, urlFlags & URL_REMEMBER, zUrl); |
| 125 | url_remember(); |
| 126 | if( g.urlProtocol==0 ){ |
| 127 | if( urlOptional ) fossil_exit(0); |
| 128 | usage("URL"); |
| 129 | } |
| 130 | user_select(); |
| 131 | if( g.argc==2 ){ |
| 132 | if( ((*pSyncFlags) & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL) ){ |
| 133 | fossil_print("Sync with %s\n", g.urlCanonical); |
| 134 | }else if( (*pSyncFlags) & SYNC_PUSH ){ |
| 135 | fossil_print("Push to %s\n", g.urlCanonical); |
| 136 | }else if( (*pSyncFlags) & SYNC_PULL ){ |
| 137 | fossil_print("Pull from %s\n", g.urlCanonical); |
| 138 | } |
| 139 | } |
| 140 | url_enable_proxy("via proxy: "); |
| 141 | *pConfigFlags |= configSync; |
| 142 | } |
| @@ -278,8 +278,8 @@ | |
| 278 | if( zUrl==0 ){ |
| 279 | fossil_print("off\n"); |
| 280 | return; |
| 281 | }else{ |
| 282 | url_parse(zUrl, 0); |
| 283 | fossil_print("%s\n", g.urlCanonical); |
| 284 | } |
| 285 | } |
| 286 |
| --- src/sync.c | |
| +++ src/sync.c | |
| @@ -48,14 +48,14 @@ | |
| 48 | } |
| 49 | }else{ |
| 50 | /* Autosync defaults on. To make it default off, "return" here. */ |
| 51 | } |
| 52 | url_parse(0, URL_REMEMBER); |
| 53 | if( g.url.protocol==0 ) return 0; |
| 54 | if( g.url.user!=0 && g.url.passwd==0 ){ |
| 55 | g.url.passwd = unobscure(db_get("last-sync-pw", 0)); |
| 56 | g.url.flags |= URL_PROMPT_PW; |
| 57 | url_prompt_for_password(); |
| 58 | } |
| 59 | g.zHttpAuth = get_httpauth(); |
| 60 | url_remember(); |
| 61 | #if 0 /* Disabled for now */ |
| @@ -69,11 +69,11 @@ | |
| 69 | */ |
| 70 | configSync = CONFIGSET_SHUN; |
| 71 | } |
| 72 | #endif |
| 73 | if( find_option("verbose","v",0)!=0 ) flags |= SYNC_VERBOSE; |
| 74 | fossil_print("Autosync: %s\n", g.url.canonical); |
| 75 | url_enable_proxy("via proxy: "); |
| 76 | rc = client_sync(flags, configSync, 0); |
| 77 | if( rc ) fossil_warning("Autosync failed"); |
| 78 | return rc; |
| 79 | } |
| @@ -121,22 +121,22 @@ | |
| 121 | clone_ssh_db_set_options(); |
| 122 | } |
| 123 | url_parse(zUrl, urlFlags); |
| 124 | remember_or_get_http_auth(zHttpAuth, urlFlags & URL_REMEMBER, zUrl); |
| 125 | url_remember(); |
| 126 | if( g.url.protocol==0 ){ |
| 127 | if( urlOptional ) fossil_exit(0); |
| 128 | usage("URL"); |
| 129 | } |
| 130 | user_select(); |
| 131 | if( g.argc==2 ){ |
| 132 | if( ((*pSyncFlags) & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL) ){ |
| 133 | fossil_print("Sync with %s\n", g.url.canonical); |
| 134 | }else if( (*pSyncFlags) & SYNC_PUSH ){ |
| 135 | fossil_print("Push to %s\n", g.url.canonical); |
| 136 | }else if( (*pSyncFlags) & SYNC_PULL ){ |
| 137 | fossil_print("Pull from %s\n", g.url.canonical); |
| 138 | } |
| 139 | } |
| 140 | url_enable_proxy("via proxy: "); |
| 141 | *pConfigFlags |= configSync; |
| 142 | } |
| @@ -278,8 +278,8 @@ | |
| 278 | if( zUrl==0 ){ |
| 279 | fossil_print("off\n"); |
| 280 | return; |
| 281 | }else{ |
| 282 | url_parse(zUrl, 0); |
| 283 | fossil_print("%s\n", g.url.canonical); |
| 284 | } |
| 285 | } |
| 286 |
+61
-61
| --- src/url.c | ||
| +++ src/url.c | ||
| @@ -275,22 +275,22 @@ | ||
| 275 | 275 | |
| 276 | 276 | /* |
| 277 | 277 | ** Parse the given URL, which describes a sync server. Populate variables |
| 278 | 278 | ** in the global "g" structure as follows: |
| 279 | 279 | ** |
| 280 | -** g.urlIsFile True if FILE: | |
| 281 | -** g.urlIsHttps True if HTTPS: | |
| 282 | -** g.urlIsSsh True if SSH: | |
| 283 | -** g.urlProtocol "http" or "https" or "file" | |
| 284 | -** g.urlName Hostname for HTTP:, HTTPS:, SSH:. Filename for FILE: | |
| 285 | -** g.urlPort TCP port number for HTTP or HTTPS. | |
| 286 | -** g.urlDfltPort Default TCP port number (80 or 443). | |
| 287 | -** g.urlPath Path name for HTTP or HTTPS. | |
| 288 | -** g.urlUser Userid. | |
| 289 | -** g.urlPasswd Password. | |
| 290 | -** g.urlHostname HOST:PORT or just HOST if port is the default. | |
| 291 | -** g.urlCanonical The URL in canonical form, omitting the password | |
| 280 | +** g.url.isFile True if FILE: | |
| 281 | +** g.url.isHttps True if HTTPS: | |
| 282 | +** g.url.isSsh True if SSH: | |
| 283 | +** g.url.protocol "http" or "https" or "file" | |
| 284 | +** g.url.name Hostname for HTTP:, HTTPS:, SSH:. Filename for FILE: | |
| 285 | +** g.url.port TCP port number for HTTP or HTTPS. | |
| 286 | +** g.url.dfltPort Default TCP port number (80 or 443). | |
| 287 | +** g.url.path Path name for HTTP or HTTPS. | |
| 288 | +** g.url.user Userid. | |
| 289 | +** g.url.passwd Password. | |
| 290 | +** g.url.hostname HOST:PORT or just HOST if port is the default. | |
| 291 | +** g.url.canonical The URL in canonical form, omitting the password | |
| 292 | 292 | ** |
| 293 | 293 | ** HTTP url format as follows (HTTPS is the same with a different scheme): |
| 294 | 294 | ** |
| 295 | 295 | ** http://userid:password@host:port/path |
| 296 | 296 | ** |
| @@ -298,11 +298,11 @@ | ||
| 298 | 298 | ** |
| 299 | 299 | ** ssh://userid@host:port/path?fossil=path/to/fossil.exe |
| 300 | 300 | ** |
| 301 | 301 | */ |
| 302 | 302 | void url_parse(const char *zUrl, unsigned int urlFlags){ |
| 303 | - url_parse_local(zUrl, urlFlags, GLOBAL_URL()); | |
| 303 | + url_parse_local(zUrl, urlFlags, &g.url); | |
| 304 | 304 | } |
| 305 | 305 | |
| 306 | 306 | /* |
| 307 | 307 | ** COMMAND: test-urlparser |
| 308 | 308 | ** |
| @@ -323,25 +323,25 @@ | ||
| 323 | 323 | if( g.argc!=3 && g.argc!=4 ){ |
| 324 | 324 | usage("URL"); |
| 325 | 325 | } |
| 326 | 326 | url_parse(g.argv[2], fg); |
| 327 | 327 | for(i=0; i<2; i++){ |
| 328 | - fossil_print("g.urlIsFile = %d\n", g.urlIsFile); | |
| 329 | - fossil_print("g.urlIsHttps = %d\n", g.urlIsHttps); | |
| 330 | - fossil_print("g.urlIsSsh = %d\n", g.urlIsSsh); | |
| 331 | - fossil_print("g.urlProtocol = %s\n", g.urlProtocol); | |
| 332 | - fossil_print("g.urlName = %s\n", g.urlName); | |
| 333 | - fossil_print("g.urlPort = %d\n", g.urlPort); | |
| 334 | - fossil_print("g.urlDfltPort = %d\n", g.urlDfltPort); | |
| 335 | - fossil_print("g.urlHostname = %s\n", g.urlHostname); | |
| 336 | - fossil_print("g.urlPath = %s\n", g.urlPath); | |
| 337 | - fossil_print("g.urlUser = %s\n", g.urlUser); | |
| 338 | - fossil_print("g.urlPasswd = %s\n", g.urlPasswd); | |
| 339 | - fossil_print("g.urlCanonical = %s\n", g.urlCanonical); | |
| 340 | - fossil_print("g.urlFossil = %s\n", g.urlFossil); | |
| 341 | - fossil_print("g.urlFlags = 0x%02x\n", g.urlFlags); | |
| 342 | - if( g.urlIsFile || g.urlIsSsh ) break; | |
| 328 | + fossil_print("g.url.isFile = %d\n", g.url.isFile); | |
| 329 | + fossil_print("g.url.isHttps = %d\n", g.url.isHttps); | |
| 330 | + fossil_print("g.url.isSsh = %d\n", g.url.isSsh); | |
| 331 | + fossil_print("g.url.protocol = %s\n", g.url.protocol); | |
| 332 | + fossil_print("g.url.name = %s\n", g.url.name); | |
| 333 | + fossil_print("g.url.port = %d\n", g.url.port); | |
| 334 | + fossil_print("g.url.dfltPort = %d\n", g.url.dfltPort); | |
| 335 | + fossil_print("g.url.hostname = %s\n", g.url.hostname); | |
| 336 | + fossil_print("g.url.path = %s\n", g.url.path); | |
| 337 | + fossil_print("g.url.user = %s\n", g.url.user); | |
| 338 | + fossil_print("g.url.passwd = %s\n", g.url.passwd); | |
| 339 | + fossil_print("g.url.canonical = %s\n", g.url.canonical); | |
| 340 | + fossil_print("g.url.fossil = %s\n", g.url.fossil); | |
| 341 | + fossil_print("g.url.flags = 0x%02x\n", g.url.flags); | |
| 342 | + if( g.url.isFile || g.url.isSsh ) break; | |
| 343 | 343 | if( i==0 ){ |
| 344 | 344 | fossil_print("********\n"); |
| 345 | 345 | url_enable_proxy("Using proxy: "); |
| 346 | 346 | } |
| 347 | 347 | } |
| @@ -385,38 +385,38 @@ | ||
| 385 | 385 | if( zProxy==0 || zProxy[0]==0 || is_truth(zProxy) ){ |
| 386 | 386 | zProxy = fossil_getenv("http_proxy"); |
| 387 | 387 | } |
| 388 | 388 | } |
| 389 | 389 | if( zProxy && zProxy[0] && !is_false(zProxy) |
| 390 | - && !g.urlIsSsh && !g.urlIsFile ){ | |
| 391 | - char *zOriginalUrl = g.urlCanonical; | |
| 392 | - char *zOriginalHost = g.urlHostname; | |
| 393 | - int fOriginalIsHttps = g.urlIsHttps; | |
| 394 | - char *zOriginalUser = g.urlUser; | |
| 395 | - char *zOriginalPasswd = g.urlPasswd; | |
| 396 | - char *zOriginalUrlPath = g.urlPath; | |
| 397 | - int iOriginalPort = g.urlPort; | |
| 398 | - unsigned uOriginalFlags = g.urlFlags; | |
| 399 | - g.urlUser = 0; | |
| 400 | - g.urlPasswd = ""; | |
| 390 | + && !g.url.isSsh && !g.url.isFile ){ | |
| 391 | + char *zOriginalUrl = g.url.canonical; | |
| 392 | + char *zOriginalHost = g.url.hostname; | |
| 393 | + int fOriginalIsHttps = g.url.isHttps; | |
| 394 | + char *zOriginalUser = g.url.user; | |
| 395 | + char *zOriginalPasswd = g.url.passwd; | |
| 396 | + char *zOriginalUrlPath = g.url.path; | |
| 397 | + int iOriginalPort = g.url.port; | |
| 398 | + unsigned uOriginalFlags = g.url.flags; | |
| 399 | + g.url.user = 0; | |
| 400 | + g.url.passwd = ""; | |
| 401 | 401 | url_parse(zProxy, 0); |
| 402 | - if( zMsg ) fossil_print("%s%s\n", zMsg, g.urlCanonical); | |
| 403 | - g.urlPath = zOriginalUrl; | |
| 404 | - g.urlHostname = zOriginalHost; | |
| 405 | - if( g.urlUser ){ | |
| 406 | - char *zCredentials1 = mprintf("%s:%s", g.urlUser, g.urlPasswd); | |
| 402 | + if( zMsg ) fossil_print("%s%s\n", zMsg, g.url.canonical); | |
| 403 | + g.url.path = zOriginalUrl; | |
| 404 | + g.url.hostname = zOriginalHost; | |
| 405 | + if( g.url.user ){ | |
| 406 | + char *zCredentials1 = mprintf("%s:%s", g.url.user, g.url.passwd); | |
| 407 | 407 | char *zCredentials2 = encode64(zCredentials1, -1); |
| 408 | - g.urlProxyAuth = mprintf("Basic %z", zCredentials2); | |
| 408 | + g.url.proxyAuth = mprintf("Basic %z", zCredentials2); | |
| 409 | 409 | free(zCredentials1); |
| 410 | 410 | } |
| 411 | - g.urlUser = zOriginalUser; | |
| 412 | - g.urlPasswd = zOriginalPasswd; | |
| 413 | - g.urlIsHttps = fOriginalIsHttps; | |
| 414 | - g.useProxy = 1; | |
| 415 | - g.proxyUrlPath = zOriginalUrlPath; | |
| 416 | - g.proxyOrigPort = iOriginalPort; | |
| 417 | - g.urlFlags = uOriginalFlags; | |
| 411 | + g.url.user = zOriginalUser; | |
| 412 | + g.url.passwd = zOriginalPasswd; | |
| 413 | + g.url.isHttps = fOriginalIsHttps; | |
| 414 | + g.url.useProxy = 1; | |
| 415 | + g.url.proxyUrlPath = zOriginalUrlPath; | |
| 416 | + g.url.proxyOrigPort = iOriginalPort; | |
| 417 | + g.url.flags = uOriginalFlags; | |
| 418 | 418 | } |
| 419 | 419 | } |
| 420 | 420 | |
| 421 | 421 | #if INTERFACE |
| 422 | 422 | /* |
| @@ -529,35 +529,35 @@ | ||
| 529 | 529 | pUrlData->user); |
| 530 | 530 | } |
| 531 | 531 | } |
| 532 | 532 | |
| 533 | 533 | /* |
| 534 | -** Prompt the user for the password for g.urlUser. Store the result | |
| 535 | -** in g.urlPasswd. | |
| 534 | +** Prompt the user for the password for g.url.user. Store the result | |
| 535 | +** in g.url.passwd. | |
| 536 | 536 | */ |
| 537 | 537 | void url_prompt_for_password(void){ |
| 538 | - url_prompt_for_password_local(GLOBAL_URL()); | |
| 538 | + url_prompt_for_password_local(&g.url); | |
| 539 | 539 | } |
| 540 | 540 | |
| 541 | 541 | /* |
| 542 | 542 | ** Remember the URL and password if requested. |
| 543 | 543 | */ |
| 544 | 544 | void url_remember(void){ |
| 545 | - if( g.urlFlags & URL_REMEMBER ){ | |
| 546 | - db_set("last-sync-url", g.urlCanonical, 0); | |
| 547 | - if( g.urlUser!=0 && g.urlPasswd!=0 && ( g.urlFlags & URL_REMEMBER_PW ) ){ | |
| 548 | - db_set("last-sync-pw", obscure(g.urlPasswd), 0); | |
| 545 | + if( g.url.flags & URL_REMEMBER ){ | |
| 546 | + db_set("last-sync-url", g.url.canonical, 0); | |
| 547 | + if( g.url.user!=0 && g.url.passwd!=0 && ( g.url.flags & URL_REMEMBER_PW ) ){ | |
| 548 | + db_set("last-sync-pw", obscure(g.url.passwd), 0); | |
| 549 | 549 | } |
| 550 | 550 | } |
| 551 | 551 | } |
| 552 | 552 | |
| 553 | 553 | /* Preemptively prompt for a password if a username is given in the |
| 554 | 554 | ** URL but no password. |
| 555 | 555 | */ |
| 556 | 556 | void url_get_password_if_needed(void){ |
| 557 | - if( (g.urlUser && g.urlUser[0]) | |
| 558 | - && (g.urlPasswd==0 || g.urlPasswd[0]==0) | |
| 557 | + if( (g.url.user && g.url.user[0]) | |
| 558 | + && (g.url.passwd==0 || g.url.passwd[0]==0) | |
| 559 | 559 | && isatty(fileno(stdin)) |
| 560 | 560 | ){ |
| 561 | 561 | url_prompt_for_password(); |
| 562 | 562 | } |
| 563 | 563 | } |
| 564 | 564 |
| --- src/url.c | |
| +++ src/url.c | |
| @@ -275,22 +275,22 @@ | |
| 275 | |
| 276 | /* |
| 277 | ** Parse the given URL, which describes a sync server. Populate variables |
| 278 | ** in the global "g" structure as follows: |
| 279 | ** |
| 280 | ** g.urlIsFile True if FILE: |
| 281 | ** g.urlIsHttps True if HTTPS: |
| 282 | ** g.urlIsSsh True if SSH: |
| 283 | ** g.urlProtocol "http" or "https" or "file" |
| 284 | ** g.urlName Hostname for HTTP:, HTTPS:, SSH:. Filename for FILE: |
| 285 | ** g.urlPort TCP port number for HTTP or HTTPS. |
| 286 | ** g.urlDfltPort Default TCP port number (80 or 443). |
| 287 | ** g.urlPath Path name for HTTP or HTTPS. |
| 288 | ** g.urlUser Userid. |
| 289 | ** g.urlPasswd Password. |
| 290 | ** g.urlHostname HOST:PORT or just HOST if port is the default. |
| 291 | ** g.urlCanonical The URL in canonical form, omitting the password |
| 292 | ** |
| 293 | ** HTTP url format as follows (HTTPS is the same with a different scheme): |
| 294 | ** |
| 295 | ** http://userid:password@host:port/path |
| 296 | ** |
| @@ -298,11 +298,11 @@ | |
| 298 | ** |
| 299 | ** ssh://userid@host:port/path?fossil=path/to/fossil.exe |
| 300 | ** |
| 301 | */ |
| 302 | void url_parse(const char *zUrl, unsigned int urlFlags){ |
| 303 | url_parse_local(zUrl, urlFlags, GLOBAL_URL()); |
| 304 | } |
| 305 | |
| 306 | /* |
| 307 | ** COMMAND: test-urlparser |
| 308 | ** |
| @@ -323,25 +323,25 @@ | |
| 323 | if( g.argc!=3 && g.argc!=4 ){ |
| 324 | usage("URL"); |
| 325 | } |
| 326 | url_parse(g.argv[2], fg); |
| 327 | for(i=0; i<2; i++){ |
| 328 | fossil_print("g.urlIsFile = %d\n", g.urlIsFile); |
| 329 | fossil_print("g.urlIsHttps = %d\n", g.urlIsHttps); |
| 330 | fossil_print("g.urlIsSsh = %d\n", g.urlIsSsh); |
| 331 | fossil_print("g.urlProtocol = %s\n", g.urlProtocol); |
| 332 | fossil_print("g.urlName = %s\n", g.urlName); |
| 333 | fossil_print("g.urlPort = %d\n", g.urlPort); |
| 334 | fossil_print("g.urlDfltPort = %d\n", g.urlDfltPort); |
| 335 | fossil_print("g.urlHostname = %s\n", g.urlHostname); |
| 336 | fossil_print("g.urlPath = %s\n", g.urlPath); |
| 337 | fossil_print("g.urlUser = %s\n", g.urlUser); |
| 338 | fossil_print("g.urlPasswd = %s\n", g.urlPasswd); |
| 339 | fossil_print("g.urlCanonical = %s\n", g.urlCanonical); |
| 340 | fossil_print("g.urlFossil = %s\n", g.urlFossil); |
| 341 | fossil_print("g.urlFlags = 0x%02x\n", g.urlFlags); |
| 342 | if( g.urlIsFile || g.urlIsSsh ) break; |
| 343 | if( i==0 ){ |
| 344 | fossil_print("********\n"); |
| 345 | url_enable_proxy("Using proxy: "); |
| 346 | } |
| 347 | } |
| @@ -385,38 +385,38 @@ | |
| 385 | if( zProxy==0 || zProxy[0]==0 || is_truth(zProxy) ){ |
| 386 | zProxy = fossil_getenv("http_proxy"); |
| 387 | } |
| 388 | } |
| 389 | if( zProxy && zProxy[0] && !is_false(zProxy) |
| 390 | && !g.urlIsSsh && !g.urlIsFile ){ |
| 391 | char *zOriginalUrl = g.urlCanonical; |
| 392 | char *zOriginalHost = g.urlHostname; |
| 393 | int fOriginalIsHttps = g.urlIsHttps; |
| 394 | char *zOriginalUser = g.urlUser; |
| 395 | char *zOriginalPasswd = g.urlPasswd; |
| 396 | char *zOriginalUrlPath = g.urlPath; |
| 397 | int iOriginalPort = g.urlPort; |
| 398 | unsigned uOriginalFlags = g.urlFlags; |
| 399 | g.urlUser = 0; |
| 400 | g.urlPasswd = ""; |
| 401 | url_parse(zProxy, 0); |
| 402 | if( zMsg ) fossil_print("%s%s\n", zMsg, g.urlCanonical); |
| 403 | g.urlPath = zOriginalUrl; |
| 404 | g.urlHostname = zOriginalHost; |
| 405 | if( g.urlUser ){ |
| 406 | char *zCredentials1 = mprintf("%s:%s", g.urlUser, g.urlPasswd); |
| 407 | char *zCredentials2 = encode64(zCredentials1, -1); |
| 408 | g.urlProxyAuth = mprintf("Basic %z", zCredentials2); |
| 409 | free(zCredentials1); |
| 410 | } |
| 411 | g.urlUser = zOriginalUser; |
| 412 | g.urlPasswd = zOriginalPasswd; |
| 413 | g.urlIsHttps = fOriginalIsHttps; |
| 414 | g.useProxy = 1; |
| 415 | g.proxyUrlPath = zOriginalUrlPath; |
| 416 | g.proxyOrigPort = iOriginalPort; |
| 417 | g.urlFlags = uOriginalFlags; |
| 418 | } |
| 419 | } |
| 420 | |
| 421 | #if INTERFACE |
| 422 | /* |
| @@ -529,35 +529,35 @@ | |
| 529 | pUrlData->user); |
| 530 | } |
| 531 | } |
| 532 | |
| 533 | /* |
| 534 | ** Prompt the user for the password for g.urlUser. Store the result |
| 535 | ** in g.urlPasswd. |
| 536 | */ |
| 537 | void url_prompt_for_password(void){ |
| 538 | url_prompt_for_password_local(GLOBAL_URL()); |
| 539 | } |
| 540 | |
| 541 | /* |
| 542 | ** Remember the URL and password if requested. |
| 543 | */ |
| 544 | void url_remember(void){ |
| 545 | if( g.urlFlags & URL_REMEMBER ){ |
| 546 | db_set("last-sync-url", g.urlCanonical, 0); |
| 547 | if( g.urlUser!=0 && g.urlPasswd!=0 && ( g.urlFlags & URL_REMEMBER_PW ) ){ |
| 548 | db_set("last-sync-pw", obscure(g.urlPasswd), 0); |
| 549 | } |
| 550 | } |
| 551 | } |
| 552 | |
| 553 | /* Preemptively prompt for a password if a username is given in the |
| 554 | ** URL but no password. |
| 555 | */ |
| 556 | void url_get_password_if_needed(void){ |
| 557 | if( (g.urlUser && g.urlUser[0]) |
| 558 | && (g.urlPasswd==0 || g.urlPasswd[0]==0) |
| 559 | && isatty(fileno(stdin)) |
| 560 | ){ |
| 561 | url_prompt_for_password(); |
| 562 | } |
| 563 | } |
| 564 |
| --- src/url.c | |
| +++ src/url.c | |
| @@ -275,22 +275,22 @@ | |
| 275 | |
| 276 | /* |
| 277 | ** Parse the given URL, which describes a sync server. Populate variables |
| 278 | ** in the global "g" structure as follows: |
| 279 | ** |
| 280 | ** g.url.isFile True if FILE: |
| 281 | ** g.url.isHttps True if HTTPS: |
| 282 | ** g.url.isSsh True if SSH: |
| 283 | ** g.url.protocol "http" or "https" or "file" |
| 284 | ** g.url.name Hostname for HTTP:, HTTPS:, SSH:. Filename for FILE: |
| 285 | ** g.url.port TCP port number for HTTP or HTTPS. |
| 286 | ** g.url.dfltPort Default TCP port number (80 or 443). |
| 287 | ** g.url.path Path name for HTTP or HTTPS. |
| 288 | ** g.url.user Userid. |
| 289 | ** g.url.passwd Password. |
| 290 | ** g.url.hostname HOST:PORT or just HOST if port is the default. |
| 291 | ** g.url.canonical The URL in canonical form, omitting the password |
| 292 | ** |
| 293 | ** HTTP url format as follows (HTTPS is the same with a different scheme): |
| 294 | ** |
| 295 | ** http://userid:password@host:port/path |
| 296 | ** |
| @@ -298,11 +298,11 @@ | |
| 298 | ** |
| 299 | ** ssh://userid@host:port/path?fossil=path/to/fossil.exe |
| 300 | ** |
| 301 | */ |
| 302 | void url_parse(const char *zUrl, unsigned int urlFlags){ |
| 303 | url_parse_local(zUrl, urlFlags, &g.url); |
| 304 | } |
| 305 | |
| 306 | /* |
| 307 | ** COMMAND: test-urlparser |
| 308 | ** |
| @@ -323,25 +323,25 @@ | |
| 323 | if( g.argc!=3 && g.argc!=4 ){ |
| 324 | usage("URL"); |
| 325 | } |
| 326 | url_parse(g.argv[2], fg); |
| 327 | for(i=0; i<2; i++){ |
| 328 | fossil_print("g.url.isFile = %d\n", g.url.isFile); |
| 329 | fossil_print("g.url.isHttps = %d\n", g.url.isHttps); |
| 330 | fossil_print("g.url.isSsh = %d\n", g.url.isSsh); |
| 331 | fossil_print("g.url.protocol = %s\n", g.url.protocol); |
| 332 | fossil_print("g.url.name = %s\n", g.url.name); |
| 333 | fossil_print("g.url.port = %d\n", g.url.port); |
| 334 | fossil_print("g.url.dfltPort = %d\n", g.url.dfltPort); |
| 335 | fossil_print("g.url.hostname = %s\n", g.url.hostname); |
| 336 | fossil_print("g.url.path = %s\n", g.url.path); |
| 337 | fossil_print("g.url.user = %s\n", g.url.user); |
| 338 | fossil_print("g.url.passwd = %s\n", g.url.passwd); |
| 339 | fossil_print("g.url.canonical = %s\n", g.url.canonical); |
| 340 | fossil_print("g.url.fossil = %s\n", g.url.fossil); |
| 341 | fossil_print("g.url.flags = 0x%02x\n", g.url.flags); |
| 342 | if( g.url.isFile || g.url.isSsh ) break; |
| 343 | if( i==0 ){ |
| 344 | fossil_print("********\n"); |
| 345 | url_enable_proxy("Using proxy: "); |
| 346 | } |
| 347 | } |
| @@ -385,38 +385,38 @@ | |
| 385 | if( zProxy==0 || zProxy[0]==0 || is_truth(zProxy) ){ |
| 386 | zProxy = fossil_getenv("http_proxy"); |
| 387 | } |
| 388 | } |
| 389 | if( zProxy && zProxy[0] && !is_false(zProxy) |
| 390 | && !g.url.isSsh && !g.url.isFile ){ |
| 391 | char *zOriginalUrl = g.url.canonical; |
| 392 | char *zOriginalHost = g.url.hostname; |
| 393 | int fOriginalIsHttps = g.url.isHttps; |
| 394 | char *zOriginalUser = g.url.user; |
| 395 | char *zOriginalPasswd = g.url.passwd; |
| 396 | char *zOriginalUrlPath = g.url.path; |
| 397 | int iOriginalPort = g.url.port; |
| 398 | unsigned uOriginalFlags = g.url.flags; |
| 399 | g.url.user = 0; |
| 400 | g.url.passwd = ""; |
| 401 | url_parse(zProxy, 0); |
| 402 | if( zMsg ) fossil_print("%s%s\n", zMsg, g.url.canonical); |
| 403 | g.url.path = zOriginalUrl; |
| 404 | g.url.hostname = zOriginalHost; |
| 405 | if( g.url.user ){ |
| 406 | char *zCredentials1 = mprintf("%s:%s", g.url.user, g.url.passwd); |
| 407 | char *zCredentials2 = encode64(zCredentials1, -1); |
| 408 | g.url.proxyAuth = mprintf("Basic %z", zCredentials2); |
| 409 | free(zCredentials1); |
| 410 | } |
| 411 | g.url.user = zOriginalUser; |
| 412 | g.url.passwd = zOriginalPasswd; |
| 413 | g.url.isHttps = fOriginalIsHttps; |
| 414 | g.url.useProxy = 1; |
| 415 | g.url.proxyUrlPath = zOriginalUrlPath; |
| 416 | g.url.proxyOrigPort = iOriginalPort; |
| 417 | g.url.flags = uOriginalFlags; |
| 418 | } |
| 419 | } |
| 420 | |
| 421 | #if INTERFACE |
| 422 | /* |
| @@ -529,35 +529,35 @@ | |
| 529 | pUrlData->user); |
| 530 | } |
| 531 | } |
| 532 | |
| 533 | /* |
| 534 | ** Prompt the user for the password for g.url.user. Store the result |
| 535 | ** in g.url.passwd. |
| 536 | */ |
| 537 | void url_prompt_for_password(void){ |
| 538 | url_prompt_for_password_local(&g.url); |
| 539 | } |
| 540 | |
| 541 | /* |
| 542 | ** Remember the URL and password if requested. |
| 543 | */ |
| 544 | void url_remember(void){ |
| 545 | if( g.url.flags & URL_REMEMBER ){ |
| 546 | db_set("last-sync-url", g.url.canonical, 0); |
| 547 | if( g.url.user!=0 && g.url.passwd!=0 && ( g.url.flags & URL_REMEMBER_PW ) ){ |
| 548 | db_set("last-sync-pw", obscure(g.url.passwd), 0); |
| 549 | } |
| 550 | } |
| 551 | } |
| 552 | |
| 553 | /* Preemptively prompt for a password if a username is given in the |
| 554 | ** URL but no password. |
| 555 | */ |
| 556 | void url_get_password_if_needed(void){ |
| 557 | if( (g.url.user && g.url.user[0]) |
| 558 | && (g.url.passwd==0 || g.url.passwd[0]==0) |
| 559 | && isatty(fileno(stdin)) |
| 560 | ){ |
| 561 | url_prompt_for_password(); |
| 562 | } |
| 563 | } |
| 564 |
+1
-1
| --- src/user.c | ||
| +++ src/user.c | ||
| @@ -375,11 +375,11 @@ | ||
| 375 | 375 | if( attempt_user(fossil_getenv("LOGNAME")) ) return; |
| 376 | 376 | |
| 377 | 377 | if( attempt_user(fossil_getenv("USERNAME")) ) return; |
| 378 | 378 | |
| 379 | 379 | url_parse(0, 0); |
| 380 | - if( g.urlUser && attempt_user(g.urlUser) ) return; | |
| 380 | + if( g.url.user && attempt_user(g.url.user) ) return; | |
| 381 | 381 | |
| 382 | 382 | fossil_print( |
| 383 | 383 | "Cannot figure out who you are! Consider using the --user\n" |
| 384 | 384 | "command line option, setting your USER environment variable,\n" |
| 385 | 385 | "or setting a default user with \"fossil user default USER\".\n" |
| 386 | 386 |
| --- src/user.c | |
| +++ src/user.c | |
| @@ -375,11 +375,11 @@ | |
| 375 | if( attempt_user(fossil_getenv("LOGNAME")) ) return; |
| 376 | |
| 377 | if( attempt_user(fossil_getenv("USERNAME")) ) return; |
| 378 | |
| 379 | url_parse(0, 0); |
| 380 | if( g.urlUser && attempt_user(g.urlUser) ) return; |
| 381 | |
| 382 | fossil_print( |
| 383 | "Cannot figure out who you are! Consider using the --user\n" |
| 384 | "command line option, setting your USER environment variable,\n" |
| 385 | "or setting a default user with \"fossil user default USER\".\n" |
| 386 |
| --- src/user.c | |
| +++ src/user.c | |
| @@ -375,11 +375,11 @@ | |
| 375 | if( attempt_user(fossil_getenv("LOGNAME")) ) return; |
| 376 | |
| 377 | if( attempt_user(fossil_getenv("USERNAME")) ) return; |
| 378 | |
| 379 | url_parse(0, 0); |
| 380 | if( g.url.user && attempt_user(g.url.user) ) return; |
| 381 | |
| 382 | fossil_print( |
| 383 | "Cannot figure out who you are! Consider using the --user\n" |
| 384 | "command line option, setting your USER environment variable,\n" |
| 385 | "or setting a default user with \"fossil user default USER\".\n" |
| 386 |
+6
-6
| --- src/xfer.c | ||
| +++ src/xfer.c | ||
| @@ -1375,11 +1375,11 @@ | ||
| 1375 | 1375 | static double fossil_fabs(double x){ |
| 1376 | 1376 | return x>0.0 ? x : -x; |
| 1377 | 1377 | } |
| 1378 | 1378 | |
| 1379 | 1379 | /* |
| 1380 | -** Sync to the host identified in g.urlName and g.urlPath. This | |
| 1380 | +** Sync to the host identified in g.url.name and g.url.path. This | |
| 1381 | 1381 | ** routine is called by the client. |
| 1382 | 1382 | ** |
| 1383 | 1383 | ** Records are pushed to the server if pushFlag is true. Records |
| 1384 | 1384 | ** are pulled if pullFlag is true. A full sync occurs if both are |
| 1385 | 1385 | ** true. |
| @@ -1823,15 +1823,15 @@ | ||
| 1823 | 1823 | defossilize(zMsg); |
| 1824 | 1824 | fossil_force_newline(); |
| 1825 | 1825 | fossil_print("Error: %s\n", zMsg); |
| 1826 | 1826 | if( fossil_strcmp(zMsg, "login failed")==0 ){ |
| 1827 | 1827 | if( nCycle<2 ){ |
| 1828 | - g.urlPasswd = 0; | |
| 1828 | + g.url.passwd = 0; | |
| 1829 | 1829 | go = 1; |
| 1830 | 1830 | if( g.cgiOutput==0 ){ |
| 1831 | - g.urlFlags |= URL_PROMPT_PW; | |
| 1832 | - g.urlFlags &= ~URL_PROMPTED; | |
| 1831 | + g.url.flags |= URL_PROMPT_PW; | |
| 1832 | + g.url.flags &= ~URL_PROMPTED; | |
| 1833 | 1833 | url_prompt_for_password(); |
| 1834 | 1834 | url_remember(); |
| 1835 | 1835 | } |
| 1836 | 1836 | } |
| 1837 | 1837 | }else{ |
| @@ -1926,13 +1926,13 @@ | ||
| 1926 | 1926 | |
| 1927 | 1927 | fossil_force_newline(); |
| 1928 | 1928 | fossil_print( |
| 1929 | 1929 | "%s finished with %lld bytes sent, %lld bytes received\n", |
| 1930 | 1930 | zOpType, nSent, nRcvd); |
| 1931 | - transport_close(GLOBAL_URL()); | |
| 1932 | - transport_global_shutdown(GLOBAL_URL()); | |
| 1931 | + transport_close(&g.url); | |
| 1932 | + transport_global_shutdown(&g.url); | |
| 1933 | 1933 | db_multi_exec("DROP TABLE onremote"); |
| 1934 | 1934 | manifest_crosslink_end(MC_PERMIT_HOOKS); |
| 1935 | 1935 | content_enable_dephantomize(1); |
| 1936 | 1936 | db_end_transaction(0); |
| 1937 | 1937 | return nErr; |
| 1938 | 1938 | } |
| 1939 | 1939 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -1375,11 +1375,11 @@ | |
| 1375 | static double fossil_fabs(double x){ |
| 1376 | return x>0.0 ? x : -x; |
| 1377 | } |
| 1378 | |
| 1379 | /* |
| 1380 | ** Sync to the host identified in g.urlName and g.urlPath. This |
| 1381 | ** routine is called by the client. |
| 1382 | ** |
| 1383 | ** Records are pushed to the server if pushFlag is true. Records |
| 1384 | ** are pulled if pullFlag is true. A full sync occurs if both are |
| 1385 | ** true. |
| @@ -1823,15 +1823,15 @@ | |
| 1823 | defossilize(zMsg); |
| 1824 | fossil_force_newline(); |
| 1825 | fossil_print("Error: %s\n", zMsg); |
| 1826 | if( fossil_strcmp(zMsg, "login failed")==0 ){ |
| 1827 | if( nCycle<2 ){ |
| 1828 | g.urlPasswd = 0; |
| 1829 | go = 1; |
| 1830 | if( g.cgiOutput==0 ){ |
| 1831 | g.urlFlags |= URL_PROMPT_PW; |
| 1832 | g.urlFlags &= ~URL_PROMPTED; |
| 1833 | url_prompt_for_password(); |
| 1834 | url_remember(); |
| 1835 | } |
| 1836 | } |
| 1837 | }else{ |
| @@ -1926,13 +1926,13 @@ | |
| 1926 | |
| 1927 | fossil_force_newline(); |
| 1928 | fossil_print( |
| 1929 | "%s finished with %lld bytes sent, %lld bytes received\n", |
| 1930 | zOpType, nSent, nRcvd); |
| 1931 | transport_close(GLOBAL_URL()); |
| 1932 | transport_global_shutdown(GLOBAL_URL()); |
| 1933 | db_multi_exec("DROP TABLE onremote"); |
| 1934 | manifest_crosslink_end(MC_PERMIT_HOOKS); |
| 1935 | content_enable_dephantomize(1); |
| 1936 | db_end_transaction(0); |
| 1937 | return nErr; |
| 1938 | } |
| 1939 |
| --- src/xfer.c | |
| +++ src/xfer.c | |
| @@ -1375,11 +1375,11 @@ | |
| 1375 | static double fossil_fabs(double x){ |
| 1376 | return x>0.0 ? x : -x; |
| 1377 | } |
| 1378 | |
| 1379 | /* |
| 1380 | ** Sync to the host identified in g.url.name and g.url.path. This |
| 1381 | ** routine is called by the client. |
| 1382 | ** |
| 1383 | ** Records are pushed to the server if pushFlag is true. Records |
| 1384 | ** are pulled if pullFlag is true. A full sync occurs if both are |
| 1385 | ** true. |
| @@ -1823,15 +1823,15 @@ | |
| 1823 | defossilize(zMsg); |
| 1824 | fossil_force_newline(); |
| 1825 | fossil_print("Error: %s\n", zMsg); |
| 1826 | if( fossil_strcmp(zMsg, "login failed")==0 ){ |
| 1827 | if( nCycle<2 ){ |
| 1828 | g.url.passwd = 0; |
| 1829 | go = 1; |
| 1830 | if( g.cgiOutput==0 ){ |
| 1831 | g.url.flags |= URL_PROMPT_PW; |
| 1832 | g.url.flags &= ~URL_PROMPTED; |
| 1833 | url_prompt_for_password(); |
| 1834 | url_remember(); |
| 1835 | } |
| 1836 | } |
| 1837 | }else{ |
| @@ -1926,13 +1926,13 @@ | |
| 1926 | |
| 1927 | fossil_force_newline(); |
| 1928 | fossil_print( |
| 1929 | "%s finished with %lld bytes sent, %lld bytes received\n", |
| 1930 | zOpType, nSent, nRcvd); |
| 1931 | transport_close(&g.url); |
| 1932 | transport_global_shutdown(&g.url); |
| 1933 | db_multi_exec("DROP TABLE onremote"); |
| 1934 | manifest_crosslink_end(MC_PERMIT_HOOKS); |
| 1935 | content_enable_dephantomize(1); |
| 1936 | db_end_transaction(0); |
| 1937 | return nErr; |
| 1938 | } |
| 1939 |
+3
-3
| --- src/xfersetup.c | ||
| +++ src/xfersetup.c | ||
| @@ -44,11 +44,11 @@ | ||
| 44 | 44 | setup_menu_entry("Ticket", "xfersetup_ticket", |
| 45 | 45 | "Specific TH1 code to run after processing a ticket change."); |
| 46 | 46 | @ </table> |
| 47 | 47 | |
| 48 | 48 | url_parse(0, 0); |
| 49 | - if( g.urlProtocol ){ | |
| 49 | + if( g.url.protocol ){ | |
| 50 | 50 | unsigned syncFlags; |
| 51 | 51 | const char *zButton; |
| 52 | 52 | char *zWarning; |
| 53 | 53 | |
| 54 | 54 | if( db_get_boolean("dont-push", 0) ){ |
| @@ -57,19 +57,19 @@ | ||
| 57 | 57 | zWarning = 0; |
| 58 | 58 | }else{ |
| 59 | 59 | syncFlags = SYNC_PUSH | SYNC_PULL; |
| 60 | 60 | zButton = "Synchronize"; |
| 61 | 61 | zWarning = mprintf("WARNING: Pushing to \"%s\" is enabled.", |
| 62 | - g.urlCanonical); | |
| 62 | + g.url.canonical); | |
| 63 | 63 | } |
| 64 | 64 | if( P("sync") ){ |
| 65 | 65 | user_select(); |
| 66 | 66 | url_enable_proxy(0); |
| 67 | 67 | client_sync(syncFlags, 0, 0); |
| 68 | 68 | } |
| 69 | 69 | @ <p>Press the %h(zButton) button below to synchronize with the |
| 70 | - @ "%h(g.urlCanonical)" repository now. This may be useful when | |
| 70 | + @ "%h(g.url.canonical)" repository now. This may be useful when | |
| 71 | 71 | @ testing the various transfer scripts.</p> |
| 72 | 72 | @ <p>You can use the "http -async" command in your scripts, but |
| 73 | 73 | @ make sure the "th1-uri-regexp" setting is set first.</p> |
| 74 | 74 | if( zWarning ){ |
| 75 | 75 | @ |
| 76 | 76 |
| --- src/xfersetup.c | |
| +++ src/xfersetup.c | |
| @@ -44,11 +44,11 @@ | |
| 44 | setup_menu_entry("Ticket", "xfersetup_ticket", |
| 45 | "Specific TH1 code to run after processing a ticket change."); |
| 46 | @ </table> |
| 47 | |
| 48 | url_parse(0, 0); |
| 49 | if( g.urlProtocol ){ |
| 50 | unsigned syncFlags; |
| 51 | const char *zButton; |
| 52 | char *zWarning; |
| 53 | |
| 54 | if( db_get_boolean("dont-push", 0) ){ |
| @@ -57,19 +57,19 @@ | |
| 57 | zWarning = 0; |
| 58 | }else{ |
| 59 | syncFlags = SYNC_PUSH | SYNC_PULL; |
| 60 | zButton = "Synchronize"; |
| 61 | zWarning = mprintf("WARNING: Pushing to \"%s\" is enabled.", |
| 62 | g.urlCanonical); |
| 63 | } |
| 64 | if( P("sync") ){ |
| 65 | user_select(); |
| 66 | url_enable_proxy(0); |
| 67 | client_sync(syncFlags, 0, 0); |
| 68 | } |
| 69 | @ <p>Press the %h(zButton) button below to synchronize with the |
| 70 | @ "%h(g.urlCanonical)" repository now. This may be useful when |
| 71 | @ testing the various transfer scripts.</p> |
| 72 | @ <p>You can use the "http -async" command in your scripts, but |
| 73 | @ make sure the "th1-uri-regexp" setting is set first.</p> |
| 74 | if( zWarning ){ |
| 75 | @ |
| 76 |
| --- src/xfersetup.c | |
| +++ src/xfersetup.c | |
| @@ -44,11 +44,11 @@ | |
| 44 | setup_menu_entry("Ticket", "xfersetup_ticket", |
| 45 | "Specific TH1 code to run after processing a ticket change."); |
| 46 | @ </table> |
| 47 | |
| 48 | url_parse(0, 0); |
| 49 | if( g.url.protocol ){ |
| 50 | unsigned syncFlags; |
| 51 | const char *zButton; |
| 52 | char *zWarning; |
| 53 | |
| 54 | if( db_get_boolean("dont-push", 0) ){ |
| @@ -57,19 +57,19 @@ | |
| 57 | zWarning = 0; |
| 58 | }else{ |
| 59 | syncFlags = SYNC_PUSH | SYNC_PULL; |
| 60 | zButton = "Synchronize"; |
| 61 | zWarning = mprintf("WARNING: Pushing to \"%s\" is enabled.", |
| 62 | g.url.canonical); |
| 63 | } |
| 64 | if( P("sync") ){ |
| 65 | user_select(); |
| 66 | url_enable_proxy(0); |
| 67 | client_sync(syncFlags, 0, 0); |
| 68 | } |
| 69 | @ <p>Press the %h(zButton) button below to synchronize with the |
| 70 | @ "%h(g.url.canonical)" repository now. This may be useful when |
| 71 | @ testing the various transfer scripts.</p> |
| 72 | @ <p>You can use the "http -async" command in your scripts, but |
| 73 | @ make sure the "th1-uri-regexp" setting is set first.</p> |
| 74 | if( zWarning ){ |
| 75 | @ |
| 76 |