| | @@ -173,85 +173,83 @@ |
| 173 | 173 | } |
| 174 | 174 | fossil_free(zIn); |
| 175 | 175 | } |
| 176 | 176 | |
| 177 | 177 | /* |
| 178 | | -** Global initialization of the transport layer |
| 179 | | -*/ |
| 180 | | -void transport_global_startup(void){ |
| 181 | | - if( g.urlIsSsh ){ |
| 182 | | - /* Only SSH requires a global initialization. For SSH we need to create |
| 183 | | - ** and run an SSH command to talk to the remote machine. |
| 184 | | - */ |
| 185 | | - const char *zSsh; /* The base SSH command */ |
| 186 | | - Blob zCmd; /* The SSH command */ |
| 187 | | - char *zHost; /* The host name to contact */ |
| 188 | | - int n; /* Size of prefix string */ |
| 189 | | - |
| 190 | | - zSsh = db_get("ssh-command", zDefaultSshCmd); |
| 191 | | - blob_init(&zCmd, zSsh, -1); |
| 192 | | - if( g.urlPort!=g.urlDfltPort ){ |
| 193 | | -#ifdef __MINGW32__ |
| 194 | | - blob_appendf(&zCmd, " -P %d", g.urlPort); |
| 195 | | -#else |
| 196 | | - blob_appendf(&zCmd, " -p %d", g.urlPort); |
| 197 | | -#endif |
| 198 | | - } |
| 199 | | - fossil_force_newline(); |
| 200 | | - fossil_print("%s", blob_str(&zCmd)); /* Show the base of the SSH command */ |
| 201 | | - if( g.urlUser && g.urlUser[0] ){ |
| 202 | | - zHost = mprintf("%s@%s", g.urlUser, g.urlName); |
| 203 | | -#ifdef __MINGW32__ |
| 204 | | - /* Only win32 (and specifically PLINK.EXE) support the -pw option */ |
| 205 | | - if( g.urlPasswd && g.urlPasswd[0] ){ |
| 206 | | - Blob pw; |
| 207 | | - blob_zero(&pw); |
| 208 | | - if( g.urlPasswd[0]=='*' ){ |
| 209 | | - char *zPrompt; |
| 210 | | - zPrompt = mprintf("Password for [%s]: ", zHost); |
| 211 | | - prompt_for_password(zPrompt, &pw, 0); |
| 212 | | - free(zPrompt); |
| 213 | | - }else{ |
| 214 | | - blob_init(&pw, g.urlPasswd, -1); |
| 215 | | - } |
| 216 | | - blob_append(&zCmd, " -pw ", -1); |
| 217 | | - shell_escape(&zCmd, blob_str(&pw)); |
| 218 | | - blob_reset(&pw); |
| 219 | | - fossil_print(" -pw ********"); /* Do not show the password text */ |
| 220 | | - } |
| 221 | | -#endif |
| 222 | | - }else{ |
| 223 | | - zHost = mprintf("%s", g.urlName); |
| 224 | | - } |
| 225 | | - n = blob_size(&zCmd); |
| 226 | | - blob_append(&zCmd, " ", 1); |
| 227 | | - shell_escape(&zCmd, zHost); |
| 228 | | - if( g.urlShell ){ |
| 229 | | - blob_appendf(&zCmd, " %s", g.urlShell); |
| 230 | | - }else{ |
| 231 | | -#if defined(FOSSIL_ENABLE_SSH_FAR_SIDE) |
| 232 | | - /* The following works. But only if the fossil on the remote side |
| 233 | | - ** is recent enough to support the test-ssh-far-side command. That |
| 234 | | - ** command was added on 2013-02-06. We will leave this turned off |
| 235 | | - ** until most fossil servers have upgraded to that version or a later |
| 236 | | - ** version. The sync will still work as long as the shell on the far |
| 237 | | - ** side is bash and not tcsh. And if the default far side shell is |
| 238 | | - ** tcsh, then the shell=/bin/bash query parameter can be used as a |
| 239 | | - ** work-around. Enable this code after about a year... |
| 240 | | - */ |
| 241 | | - blob_appendf(&zCmd, " exec %s test-ssh-far-side", g.urlFossil); |
| 242 | | -#endif |
| 243 | | - } |
| 244 | | - fossil_print("%s\n", blob_str(&zCmd)+n); /* Show tail of SSH command */ |
| 245 | | - free(zHost); |
| 246 | | - popen2(blob_str(&zCmd), &sshIn, &sshOut, &sshPid); |
| 247 | | - if( sshPid==0 ){ |
| 248 | | - fossil_fatal("cannot start ssh tunnel using [%b]", &zCmd); |
| 249 | | - } |
| 250 | | - blob_reset(&zCmd); |
| 178 | +** SSH initialization of the transport layer |
| 179 | +*/ |
| 180 | +int transport_ssh_open(void){ |
| 181 | + /* For SSH we need to create and run an SSH http |
| 182 | + ** to talk to the remote machine. |
| 183 | + */ |
| 184 | + const char *zSsh; /* The base SSH command */ |
| 185 | + Blob zCmd; /* The SSH command */ |
| 186 | + char *zHost; /* The host name to contact */ |
| 187 | + char *zPath; /* The path to the remote file for SSH */ |
| 188 | + int n; /* Size of prefix string */ |
| 189 | + |
| 190 | + zSsh = db_get("ssh-command", zDefaultSshCmd); |
| 191 | + blob_init(&zCmd, zSsh, -1); |
| 192 | + if( g.urlPort!=g.urlDfltPort ){ |
| 193 | +#ifdef __MINGW32__ |
| 194 | + blob_appendf(&zCmd, " -P %d", g.urlPort); |
| 195 | +#else |
| 196 | + blob_appendf(&zCmd, " -p %d", g.urlPort); |
| 197 | +#endif |
| 198 | + } |
| 199 | + fossil_force_newline(); |
| 200 | + fossil_print("%s", blob_str(&zCmd)); /* Show the base of the SSH command */ |
| 201 | + if( g.urlUser && g.urlUser[0] ){ |
| 202 | + zHost = mprintf("%s@%s", g.urlUser, g.urlName); |
| 203 | +#ifdef __MINGW32__ |
| 204 | + /* Only win32 (and specifically PLINK.EXE) support the -pw option */ |
| 205 | + if( g.urlPasswd && g.urlPasswd[0] ){ |
| 206 | + Blob pw; |
| 207 | + blob_zero(&pw); |
| 208 | + if( g.urlPasswd[0]=='*' ){ |
| 209 | + char *zPrompt; |
| 210 | + zPrompt = mprintf("Password for [%s]: ", zHost); |
| 211 | + prompt_for_password(zPrompt, &pw, 0); |
| 212 | + free(zPrompt); |
| 213 | + }else{ |
| 214 | + blob_init(&pw, g.urlPasswd, -1); |
| 215 | + } |
| 216 | + blob_append(&zCmd, " -pw ", -1); |
| 217 | + shell_escape(&zCmd, blob_str(&pw)); |
| 218 | + blob_reset(&pw); |
| 219 | + fossil_print(" -pw ********"); /* Do not show the password text */ |
| 220 | + } |
| 221 | +#endif |
| 222 | + }else{ |
| 223 | + zHost = mprintf("%s", g.urlName); |
| 224 | + } |
| 225 | + n = blob_size(&zCmd); |
| 226 | + blob_append(&zCmd, " ", 1); |
| 227 | + shell_escape(&zCmd, zHost); |
| 228 | + if( g.urlShell ){ |
| 229 | + blob_appendf(&zCmd, " %s", g.urlShell); |
| 230 | + } |
| 231 | + if( g.fSshFossilCmd && g.fSshFossilCmd[0] ){ |
| 232 | + blob_append(&zCmd, " ", 1); |
| 233 | + shell_escape(&zCmd, g.fSshFossilCmd); |
| 234 | + blob_appendf(&zCmd, " %s ", g.fSshHttpCmd); |
| 235 | + if( g.urlPath && g.urlPath[0] ){ |
| 236 | + zPath = mprintf("%s", g.urlPath); |
| 237 | + shell_escape(&zCmd, zPath); |
| 238 | + } |
| 239 | + } |
| 240 | + fossil_print("%s\n", blob_str(&zCmd)+n); /* Show tail of SSH command */ |
| 241 | + free(zHost); |
| 242 | + popen2(blob_str(&zCmd), &sshIn, &sshOut, &sshPid); |
| 243 | + if( sshPid==0 ){ |
| 244 | + socket_set_errmsg("cannot start ssh tunnel using [%b]", &zCmd); |
| 245 | + } |
| 246 | + blob_reset(&zCmd); |
| 247 | + if( g.fSshFossilCmd==0 ){ |
| 251 | 248 | transport_ssh_startup(); |
| 252 | 249 | } |
| 250 | + return sshPid==0; |
| 253 | 251 | } |
| 254 | 252 | |
| 255 | 253 | /* |
| 256 | 254 | ** COMMAND: test-ssh-far-side |
| 257 | 255 | ** |
| | @@ -287,11 +285,17 @@ |
| 287 | 285 | ** Return the number of errors. |
| 288 | 286 | */ |
| 289 | 287 | int transport_open(void){ |
| 290 | 288 | int rc = 0; |
| 291 | 289 | if( transport.isOpen==0 ){ |
| 292 | | - if( g.urlIsSsh ){ |
| 290 | + if( g.urlIsSsh && g.fSshFossilCmd ){ |
| 291 | + rc = transport_ssh_open(); |
| 292 | + if( rc==0 ) transport.isOpen = 1; |
| 293 | + }else if( g.urlIsSsh ){ |
| 294 | + if( sshPid==0 ){ |
| 295 | + rc = transport_ssh_open(); |
| 296 | + } |
| 293 | 297 | Blob cmd; |
| 294 | 298 | blob_zero(&cmd); |
| 295 | 299 | shell_escape(&cmd, g.urlFossil); |
| 296 | 300 | blob_append(&cmd, " test-http ", -1); |
| 297 | 301 | shell_escape(&cmd, g.urlPath); |
| | @@ -339,12 +343,14 @@ |
| 339 | 343 | transport.iCursor = 0; |
| 340 | 344 | if( transport.pLog ){ |
| 341 | 345 | fclose(transport.pLog); |
| 342 | 346 | transport.pLog = 0; |
| 343 | 347 | } |
| 344 | | - if( g.urlIsSsh ){ |
| 345 | | - /* No-op */ |
| 348 | + if( g.urlIsSsh && g.fSshFossilCmd ){ |
| 349 | + transport_ssh_close(); |
| 350 | + }else if( g.urlIsSsh ){ |
| 351 | + /* no-op */ |
| 346 | 352 | }else if( g.urlIsHttps ){ |
| 347 | 353 | #ifdef FOSSIL_ENABLE_SSL |
| 348 | 354 | ssl_close(); |
| 349 | 355 | #endif |
| 350 | 356 | }else if( g.urlIsFile ){ |
| | @@ -582,19 +588,23 @@ |
| 582 | 588 | if( g.fSshTrace ) printf("Got line: [%s]\n", &transport.pBuf[iStart]); |
| 583 | 589 | return &transport.pBuf[iStart]; |
| 584 | 590 | } |
| 585 | 591 | |
| 586 | 592 | void transport_global_shutdown(void){ |
| 587 | | - if( g.urlIsSsh && sshPid ){ |
| 588 | | - /*printf("Closing SSH tunnel: ");*/ |
| 589 | | - fflush(stdout); |
| 590 | | - pclose2(sshIn, sshOut, sshPid); |
| 591 | | - sshPid = 0; |
| 592 | | - } |
| 593 | + transport_ssh_close(); |
| 593 | 594 | if( g.urlIsHttps ){ |
| 594 | 595 | #ifdef FOSSIL_ENABLE_SSL |
| 595 | 596 | ssl_global_shutdown(); |
| 596 | 597 | #endif |
| 597 | 598 | }else{ |
| 598 | 599 | socket_global_shutdown(); |
| 599 | 600 | } |
| 600 | 601 | } |
| 602 | + |
| 603 | +void transport_ssh_close(void){ |
| 604 | + if( g.urlIsSsh && sshPid ){ |
| 605 | + /*printf("Closing SSH tunnel: ");*/ |
| 606 | + fflush(stdout); |
| 607 | + pclose2(sshIn, sshOut, sshPid); |
| 608 | + sshPid = 0; |
| 609 | + } |
| 610 | +} |
| 601 | 611 | |