Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | The "ssh:"-style requests are eating the query parameters, somewhere. I don't know where yet. Don't use query parameter for the time being. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | get-command |
| Files: | files | file ages | folders |
| SHA3-256: |
8028c868d3c0551d4b3ba766e354b22d |
| User & Date: | drh 2025-10-15 20:12:39.831 |
Context
|
2025-10-15
| ||
| 21:33 | Fix CGI processing so that requests sent over SSH process query parameters. Add the --ssh-sim option to the test-http command (used to debug the previous). Harden the "fossil get" command so that it can checks filenames and does not write a file that is outside of the designated --dest. ... (check-in: 9a76760178 user: drh tags: get-command) | |
| 20:12 | The "ssh:"-style requests are eating the query parameters, somewhere. I don't know where yet. Don't use query parameter for the time being. ... (check-in: 8028c868d3 user: drh tags: get-command) | |
| 17:15 | Implement the "fossil get" command. ... (check-in: 552eee775a user: drh tags: get-command) | |
Changes
Changes to src/checkout.c.
| ︙ | ︙ | |||
464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 |
** than unpacking them into separate files.
**
** -v|--verbose Show all files as they are extracted
*/
void get_cmd(void){
int forceFlag = find_option("force","f",0)!=0;
int bVerbose = find_option("verbose","v",0)!=0;
int bDebug = find_option("debug",0,0)!=0;
const char *zSqlArchive = find_option("sqlar",0,1);
const char *z;
char *zDest = 0; /* Where to store results */
const char *zUrl; /* Url to get */
const char *zVers; /* Version name to get */
unsigned int mHttpFlags = HTTP_GENERIC|HTTP_NOCOMPRESS;
Blob in, out; /* I/O for the HTTP request */
Blob file; /* A file to extract */
sqlite3 *db; /* Database containing downloaded sqlar */
sqlite3_stmt *pStmt; /* Statement for querying the database */
int rc; /* Result of subroutine calls */
z = find_option("dest",0,1);
if( z ) zDest = fossil_strdup(z);
verify_all_options();
if( g.argc<3 || g.argc>4 ){
usage("get URL ?VERSION? ?OPTIONS?");
}
| > > > > > | 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 |
** than unpacking them into separate files.
**
** -v|--verbose Show all files as they are extracted
*/
void get_cmd(void){
int forceFlag = find_option("force","f",0)!=0;
int bVerbose = find_option("verbose","v",0)!=0;
int bQuiet = find_option("quiet","q",0)!=0;
int bDebug = find_option("debug",0,0)!=0;
int bList = find_option("list",0,0)!=0;
const char *zSqlArchive = find_option("sqlar",0,1);
const char *z;
char *zDest = 0; /* Where to store results */
const char *zUrl; /* Url to get */
const char *zVers; /* Version name to get */
unsigned int mHttpFlags = HTTP_GENERIC|HTTP_NOCOMPRESS;
Blob in, out; /* I/O for the HTTP request */
Blob file; /* A file to extract */
sqlite3 *db; /* Database containing downloaded sqlar */
sqlite3_stmt *pStmt; /* Statement for querying the database */
int rc; /* Result of subroutine calls */
int nFile = 0; /* Number of files written */
int nDir = 0; /* Number of directories written */
i64 nByte = 0; /* Number of bytes written */
z = find_option("dest",0,1);
if( z ) zDest = fossil_strdup(z);
verify_all_options();
if( g.argc<3 || g.argc>4 ){
usage("get URL ?VERSION? ?OPTIONS?");
}
|
| ︙ | ︙ | |||
534 535 536 537 538 539 540 |
fossil_fatal("\"%s\" already exists", zDest);
}
}
}
/* Construct a subpath on the URL if necessary */
if( g.url.isSsh || g.url.isFile ){
| | > | 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 |
fossil_fatal("\"%s\" already exists", zDest);
}
}
}
/* Construct a subpath on the URL if necessary */
if( g.url.isSsh || g.url.isFile ){
g.url.subpath = mprintf("/sqlar/%t/%t.sqlar", zVers, zDest);
}
if( bDebug ){
urlparse_print(0);
}
/* Fetch the ZIP archive for the requested check-in */
blob_init(&in, 0, 0);
blob_init(&out, 0, 0);
if( bDebug ) mHttpFlags |= HTTP_VERBOSE;
if( bQuiet ) mHttpFlags |= HTTP_QUIET;
http_exchange(&in, &out, mHttpFlags, 4, 0);
if( zSqlArchive ){
blob_write_to_file(&out, zSqlArchive);
if( bVerbose ) fossil_print("%s\n", zSqlArchive);
return;
}
|
| ︙ | ︙ | |||
574 575 576 577 578 579 580 |
fossil_fatal("SQL error: %s\n", sqlite3_errmsg(db));
}
blob_init(&file, 0, 0);
while( sqlite3_step(pStmt)==SQLITE_ROW ){
const char *zFilename = (const char*)sqlite3_column_text(pStmt, 0);
int mode = sqlite3_column_int(pStmt, 1);
int sz = sqlite3_column_int(pStmt, 2);
| > > | > > > | 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 |
fossil_fatal("SQL error: %s\n", sqlite3_errmsg(db));
}
blob_init(&file, 0, 0);
while( sqlite3_step(pStmt)==SQLITE_ROW ){
const char *zFilename = (const char*)sqlite3_column_text(pStmt, 0);
int mode = sqlite3_column_int(pStmt, 1);
int sz = sqlite3_column_int(pStmt, 2);
if( bList ){
fossil_print("%s\n", zFilename);
}else if( mode & 0x4000 ){
/* A directory name */
nDir++;
file_mkdir(zFilename, ExtFILE, 1);
}else{
/* A file */
unsigned char *inBuf = (unsigned char*)sqlite3_column_blob(pStmt,3);
unsigned int nIn = (unsigned int)sqlite3_column_bytes(pStmt,3);
unsigned long int nOut2 = (unsigned long int)sz;
nFile++;
nByte += sz;
blob_resize(&file, sz);
if( nIn<sz ){
rc = uncompress((unsigned char*)blob_buffer(&file), &nOut2,
inBuf, nIn);
if( rc!=Z_OK ){
fossil_fatal("Failed to uncompress file %s", zFilename);
}
|
| ︙ | ︙ | |||
605 606 607 608 609 610 611 |
fossil_print("%s\n", zFilename);
}
}
}
sqlite3_finalize(pStmt);
sqlite3_close(db);
blob_zero(&out);
| > > > > > > > | > > | 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 |
fossil_print("%s\n", zFilename);
}
}
}
sqlite3_finalize(pStmt);
sqlite3_close(db);
blob_zero(&out);
if( !bVerbose && !bQuiet && nFile>0 && zDest ){
fossil_print("%d files (%,lld bytes) written into %s",
nFile, nByte, zDest);
if( nDir>1 ){
fossil_print(" and %d subdirectories\n", nDir-1);
}else{
fossil_print("\n");
}
}
}
|
Changes to src/http.c.
| ︙ | ︙ | |||
684 685 686 687 688 689 690 |
*/
if( g.url.isSsh /* This is an SSH: sync */
&& (g.url.flags & URL_SSH_EXE)==0 /* Does not have ?fossil=.... */
&& (g.url.flags & URL_SSH_RETRY)==0 /* Not retried already */
){
/* Retry after flipping the SSH_PATH setting */
transport_close(&g.url);
| > | | | | | | > | 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 |
*/
if( g.url.isSsh /* This is an SSH: sync */
&& (g.url.flags & URL_SSH_EXE)==0 /* Does not have ?fossil=.... */
&& (g.url.flags & URL_SSH_RETRY)==0 /* Not retried already */
){
/* Retry after flipping the SSH_PATH setting */
transport_close(&g.url);
if( (mHttpFlags & HTTP_QUIET)==0 ){
fossil_print(
"First attempt to run fossil on %s using SSH failed.\n"
"Retrying %s the PATH= argument.\n",
g.url.hostname,
(g.url.flags & URL_SSH_PATH)!=0 ? "without" : "with"
);
}
g.url.flags ^= URL_SSH_PATH|URL_SSH_RETRY;
rc = http_exchange(pSend,pReply,mHttpFlags,0,zAltMimetype);
if( rc==0 && g.db!=0 ){
(void)ssh_needs_path_argument(g.url.hostname,
(g.url.flags & URL_SSH_PATH)!=0);
}
return rc;
|
| ︙ | ︙ |