Fossil SCM
Detailed header comment on the ssh_add_path_argument() function explaining what this PATH= business is all about, for future reference.
Commit
ac52d12e66d71692a30116bc76d5cdca25ace9d48e95110600f56950485dc899
Parent
eb135ef204f4679…
1 file changed
+52
-3
+52
-3
| --- src/http.c | ||
| +++ src/http.c | ||
| @@ -271,16 +271,18 @@ | ||
| 271 | 271 | } |
| 272 | 272 | return rc; |
| 273 | 273 | } |
| 274 | 274 | |
| 275 | 275 | /* If iTruth<0 then guess as to whether or not a PATH= argument is required |
| 276 | -** when using ssh to run fossil on a remote machine name zHostname. | |
| 276 | +** when using ssh to run fossil on a remote machine name zHostname. Return | |
| 277 | +** true if a PATH= should be provided and 0 if not. | |
| 277 | 278 | ** |
| 278 | 279 | ** If iTruth is 1 or 0 then that means that the PATH= is or is not required, |
| 279 | 280 | ** respectively. Record this fact for future reference. |
| 280 | 281 | ** |
| 281 | -** If iTruth is 99 or more, then toggle the truth value. | |
| 282 | +** If iTruth is 99 or more, then toggle the value that will be returned | |
| 283 | +** for future iTruth==(-1) queries. | |
| 282 | 284 | */ |
| 283 | 285 | int ssh_needs_path_argument(const char *zHostname, int iTruth){ |
| 284 | 286 | int ans = 0; /* Default to "no" */ |
| 285 | 287 | char *z = mprintf("use-path-for-ssh:%s", zHostname); |
| 286 | 288 | if( iTruth<0 ){ |
| @@ -301,11 +303,11 @@ | ||
| 301 | 303 | } |
| 302 | 304 | |
| 303 | 305 | /* |
| 304 | 306 | ** COMMAND: test-ssh-needs-path |
| 305 | 307 | ** |
| 306 | -** Usage: fossil test-ssh-needs-path HOSTNAME ?BOOLEAN? | |
| 308 | +** Usage: fossil test-ssh-needs-path ?HOSTNAME? ?BOOLEAN? | |
| 307 | 309 | ** |
| 308 | 310 | ** With one argument, show whether or not the PATH= argument is included |
| 309 | 311 | ** by default for HOSTNAME. If the second argument is a boolean, then |
| 310 | 312 | ** change the value. |
| 311 | 313 | ** |
| @@ -332,10 +334,57 @@ | ||
| 332 | 334 | } |
| 333 | 335 | } |
| 334 | 336 | |
| 335 | 337 | /* Add an approprate PATH= argument to the SSH command under construction |
| 336 | 338 | ** in pCmd. |
| 339 | +** | |
| 340 | +** About This Feature | |
| 341 | +** ================== | |
| 342 | +** | |
| 343 | +** On some ssh servers (Macs in particular are guilty of this) the PATH | |
| 344 | +** variable in the shell that runs the command that is sent to the remote | |
| 345 | +** host contains a limited number of read-only system directories: | |
| 346 | +** | |
| 347 | +** /usr/bin:/bin:/usr/sbin:/sbin | |
| 348 | +** | |
| 349 | +** The fossil executable cannot be installed into any of those directories | |
| 350 | +** because they are locked down, and so the "fossil" command cannot run. | |
| 351 | +** | |
| 352 | +** To work around this, the fossil command is prefixed with the PATH= | |
| 353 | +** argument, inserted by this function, to augment the PATH with additional | |
| 354 | +** directories in which the fossil executable is often found. | |
| 355 | +** | |
| 356 | +** But other ssh servers are confused by this initial PATH= argument. | |
| 357 | +** Some ssh servers have a list of programs that they are allowed to run | |
| 358 | +** and will fail if the first argument is not on that list, and PATH=.... | |
| 359 | +** is not on that list. | |
| 360 | +** | |
| 361 | +** So that various commands that use ssh can run seamlessly on a variety | |
| 362 | +** of systems (commands that use ssh include "fossil sync" with an ssh: | |
| 363 | +** URL and the "fossil patch pull" and "fossil patch push" commands where | |
| 364 | +** the destination directory starts with HOSTNAME: or USER@HOSTNAME:.) | |
| 365 | +** the following algorithm is used: | |
| 366 | +** | |
| 367 | +** * First try running the fossil without any PATH= argument. If that | |
| 368 | +** works (and it does on a majority of systems) then we are done. | |
| 369 | +** | |
| 370 | +** * If the first attempt fails, then try again after adding the | |
| 371 | +** PATH= prefix argument. (This function is what adds that | |
| 372 | +** argument.) If the retry works, then remember that fact using | |
| 373 | +** the use-path-for-ssh:HOSTNAME setting so that the first step | |
| 374 | +** is skipped on subsequent uses of the same command. | |
| 375 | +** | |
| 376 | +** See the forum thread at | |
| 377 | +** https://fossil-scm.org/forum/forumpost/4903cb4b691af7ce for more | |
| 378 | +** background. | |
| 379 | +** | |
| 380 | +** See also: | |
| 381 | +** | |
| 382 | +** * The ssh_needs_path_argument() function above. | |
| 383 | +** * The test-ssh-needs-path command that shows the settings | |
| 384 | +** that cache whether or not a PATH= is needed for a particular | |
| 385 | +** HOSTNAME. | |
| 337 | 386 | */ |
| 338 | 387 | void ssh_add_path_argument(Blob *pCmd){ |
| 339 | 388 | blob_append_escaped_arg(pCmd, |
| 340 | 389 | "PATH=$HOME/bin:/usr/local/bin:/opt/homebrew/bin:$PATH", 1); |
| 341 | 390 | } |
| 342 | 391 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -271,16 +271,18 @@ | |
| 271 | } |
| 272 | return rc; |
| 273 | } |
| 274 | |
| 275 | /* If iTruth<0 then guess as to whether or not a PATH= argument is required |
| 276 | ** when using ssh to run fossil on a remote machine name zHostname. |
| 277 | ** |
| 278 | ** If iTruth is 1 or 0 then that means that the PATH= is or is not required, |
| 279 | ** respectively. Record this fact for future reference. |
| 280 | ** |
| 281 | ** If iTruth is 99 or more, then toggle the truth value. |
| 282 | */ |
| 283 | int ssh_needs_path_argument(const char *zHostname, int iTruth){ |
| 284 | int ans = 0; /* Default to "no" */ |
| 285 | char *z = mprintf("use-path-for-ssh:%s", zHostname); |
| 286 | if( iTruth<0 ){ |
| @@ -301,11 +303,11 @@ | |
| 301 | } |
| 302 | |
| 303 | /* |
| 304 | ** COMMAND: test-ssh-needs-path |
| 305 | ** |
| 306 | ** Usage: fossil test-ssh-needs-path HOSTNAME ?BOOLEAN? |
| 307 | ** |
| 308 | ** With one argument, show whether or not the PATH= argument is included |
| 309 | ** by default for HOSTNAME. If the second argument is a boolean, then |
| 310 | ** change the value. |
| 311 | ** |
| @@ -332,10 +334,57 @@ | |
| 332 | } |
| 333 | } |
| 334 | |
| 335 | /* Add an approprate PATH= argument to the SSH command under construction |
| 336 | ** in pCmd. |
| 337 | */ |
| 338 | void ssh_add_path_argument(Blob *pCmd){ |
| 339 | blob_append_escaped_arg(pCmd, |
| 340 | "PATH=$HOME/bin:/usr/local/bin:/opt/homebrew/bin:$PATH", 1); |
| 341 | } |
| 342 |
| --- src/http.c | |
| +++ src/http.c | |
| @@ -271,16 +271,18 @@ | |
| 271 | } |
| 272 | return rc; |
| 273 | } |
| 274 | |
| 275 | /* If iTruth<0 then guess as to whether or not a PATH= argument is required |
| 276 | ** when using ssh to run fossil on a remote machine name zHostname. Return |
| 277 | ** true if a PATH= should be provided and 0 if not. |
| 278 | ** |
| 279 | ** If iTruth is 1 or 0 then that means that the PATH= is or is not required, |
| 280 | ** respectively. Record this fact for future reference. |
| 281 | ** |
| 282 | ** If iTruth is 99 or more, then toggle the value that will be returned |
| 283 | ** for future iTruth==(-1) queries. |
| 284 | */ |
| 285 | int ssh_needs_path_argument(const char *zHostname, int iTruth){ |
| 286 | int ans = 0; /* Default to "no" */ |
| 287 | char *z = mprintf("use-path-for-ssh:%s", zHostname); |
| 288 | if( iTruth<0 ){ |
| @@ -301,11 +303,11 @@ | |
| 303 | } |
| 304 | |
| 305 | /* |
| 306 | ** COMMAND: test-ssh-needs-path |
| 307 | ** |
| 308 | ** Usage: fossil test-ssh-needs-path ?HOSTNAME? ?BOOLEAN? |
| 309 | ** |
| 310 | ** With one argument, show whether or not the PATH= argument is included |
| 311 | ** by default for HOSTNAME. If the second argument is a boolean, then |
| 312 | ** change the value. |
| 313 | ** |
| @@ -332,10 +334,57 @@ | |
| 334 | } |
| 335 | } |
| 336 | |
| 337 | /* Add an approprate PATH= argument to the SSH command under construction |
| 338 | ** in pCmd. |
| 339 | ** |
| 340 | ** About This Feature |
| 341 | ** ================== |
| 342 | ** |
| 343 | ** On some ssh servers (Macs in particular are guilty of this) the PATH |
| 344 | ** variable in the shell that runs the command that is sent to the remote |
| 345 | ** host contains a limited number of read-only system directories: |
| 346 | ** |
| 347 | ** /usr/bin:/bin:/usr/sbin:/sbin |
| 348 | ** |
| 349 | ** The fossil executable cannot be installed into any of those directories |
| 350 | ** because they are locked down, and so the "fossil" command cannot run. |
| 351 | ** |
| 352 | ** To work around this, the fossil command is prefixed with the PATH= |
| 353 | ** argument, inserted by this function, to augment the PATH with additional |
| 354 | ** directories in which the fossil executable is often found. |
| 355 | ** |
| 356 | ** But other ssh servers are confused by this initial PATH= argument. |
| 357 | ** Some ssh servers have a list of programs that they are allowed to run |
| 358 | ** and will fail if the first argument is not on that list, and PATH=.... |
| 359 | ** is not on that list. |
| 360 | ** |
| 361 | ** So that various commands that use ssh can run seamlessly on a variety |
| 362 | ** of systems (commands that use ssh include "fossil sync" with an ssh: |
| 363 | ** URL and the "fossil patch pull" and "fossil patch push" commands where |
| 364 | ** the destination directory starts with HOSTNAME: or USER@HOSTNAME:.) |
| 365 | ** the following algorithm is used: |
| 366 | ** |
| 367 | ** * First try running the fossil without any PATH= argument. If that |
| 368 | ** works (and it does on a majority of systems) then we are done. |
| 369 | ** |
| 370 | ** * If the first attempt fails, then try again after adding the |
| 371 | ** PATH= prefix argument. (This function is what adds that |
| 372 | ** argument.) If the retry works, then remember that fact using |
| 373 | ** the use-path-for-ssh:HOSTNAME setting so that the first step |
| 374 | ** is skipped on subsequent uses of the same command. |
| 375 | ** |
| 376 | ** See the forum thread at |
| 377 | ** https://fossil-scm.org/forum/forumpost/4903cb4b691af7ce for more |
| 378 | ** background. |
| 379 | ** |
| 380 | ** See also: |
| 381 | ** |
| 382 | ** * The ssh_needs_path_argument() function above. |
| 383 | ** * The test-ssh-needs-path command that shows the settings |
| 384 | ** that cache whether or not a PATH= is needed for a particular |
| 385 | ** HOSTNAME. |
| 386 | */ |
| 387 | void ssh_add_path_argument(Blob *pCmd){ |
| 388 | blob_append_escaped_arg(pCmd, |
| 389 | "PATH=$HOME/bin:/usr/local/bin:/opt/homebrew/bin:$PATH", 1); |
| 390 | } |
| 391 |