Fossil SCM

Add the -l and -x options to the test-filezip command.

drh 2025-07-14 13:13 trunk
Commit 932d351ea5619f5d92d763e4b7a116183d0d755eddacf94f8cb80ee6661c78b8
1 file changed +106 -24
+106 -24
--- src/zip.c
+++ src/zip.c
@@ -562,46 +562,128 @@
562562
fossil_free(azDir);
563563
nDir = 0;
564564
azDir = 0;
565565
}
566566
567
+/* Functions found in shell.c */
568
+extern int sqlite3_fileio_init(sqlite3*,char**,const sqlite3_api_routines*);
569
+extern int sqlite3_zipfile_init(sqlite3*,char**,const sqlite3_api_routines*);
570
+
567571
/*
568572
** COMMAND: test-filezip
569573
**
570
-** Generate a ZIP archive specified by the first argument that
571
-** contains files given in the second and subsequent arguments.
574
+** Usage: %fossil test-filezip [OPTIONS] ZIPFILE [FILENAME...]
575
+**
576
+** This command uses Fossil infrastructure or read or create a ZIP
577
+** archive named by the ZIPFILE argument. With no options, a new
578
+** ZIP archive is created and there must be at least one FILENAME
579
+** argument. If the -l option is used, the contents of the named ZIP
580
+** archive are listed on standard output. With the -x argument, the
581
+** contents of the ZIP archive are extracted.
582
+**
583
+** There are two purposes for this command: (1) To server as a test
584
+** platform for the Fossil ZIP archive generator, and (2) to provide
585
+** rudimentary ZIP archive creation capabilities on platforms that do
586
+** not have the "zip" command installed.
587
+**
588
+** Options:
589
+**
590
+** -h|--dereference Follow symlinks
591
+** -l|--list List the contents of the ZIP archive
592
+** -x|--extract Extract files from a ZIP archive
572593
*/
573594
void filezip_cmd(void){
574
- int i;
575
- Blob zip;
576
- Blob file;
577595
int eFType = SymFILE;
578
- Archive sArchive;
579
- memset(&sArchive, 0, sizeof(Archive));
580
- sArchive.eType = ARCHIVE_ZIP;
581
- sArchive.pBlob = &zip;
596
+ int doList = 0;
597
+ int doExtract = 0;
598
+ char *zArchiveName;
582599
if( find_option("dereference","h",0)!=0 ){
583600
eFType = ExtFILE;
584601
}
602
+ if( find_option("list","l",0)!=0 ){
603
+ doList = 1;
604
+ }
605
+ if( find_option("extract","x",0)!=0 ){
606
+ if( doList ){
607
+ fossil_fatal("incompatible options: -l and -x");
608
+ }
609
+ doExtract = 1;
610
+ }
585611
if( g.argc<3 ){
586
- usage("ARCHIVE FILE....");
612
+ usage("ARCHIVE FILES...");
587613
}
614
+ zArchiveName = g.argv[2];
588615
sqlite3_open(":memory:", &g.db);
589
- zip_open();
590
- for(i=3; i<g.argc; i++){
591
- double rDate;
592
- i64 iDate;
593
- blob_zero(&file);
594
- blob_read_from_file(&file, g.argv[i], eFType);
595
- iDate = file_mtime(g.argv[i], eFType);
596
- rDate = ((double)iDate)/86400.0 + 2440587.5;
597
- zip_set_timedate(rDate);
598
- zip_add_file(&sArchive, g.argv[i], &file, file_perm(0,eFType));
599
- blob_reset(&file);
600
- }
601
- zip_close(&sArchive);
602
- blob_write_to_file(&zip, g.argv[2]);
616
+ if( doList ){
617
+ /* Do a content listing of a ZIP archive */
618
+ Stmt q;
619
+ int nRow = 0;
620
+ i64 szTotal = 0;
621
+ if( file_size(zArchiveName, eFType)<0 ){
622
+ fossil_fatal("No such ZIP archive: %s", zArchiveName);
623
+ }
624
+ if( g.argc>3 ){
625
+ fossil_fatal("extra arguments after \"fossil test-filezip -l ARCHIVE\"");
626
+ }
627
+ sqlite3_zipfile_init(g.db, 0, 0);
628
+ db_multi_exec("CREATE VIRTUAL TABLE z1 USING zipfile(%Q)", zArchiveName);
629
+ db_prepare(&q, "SELECT sz, datetime(mtime,'unixepoch'), name FROM z1");
630
+ while( db_step(&q)==SQLITE_ROW ){
631
+ int sz = db_column_int(&q, 0);
632
+ szTotal += sz;
633
+ if( nRow==0 ){
634
+ fossil_print(" Length Date Time Name\n");
635
+ fossil_print("--------- ---------- ----- ----\n");
636
+ }
637
+ nRow++;
638
+ fossil_print("%9d %.16s %s\n", sz, db_column_text(&q,1),
639
+ db_column_text(&q,2));
640
+ }
641
+ if( nRow ){
642
+ fossil_print("--------- --------\n");
643
+ fossil_print("%9lld %16s %d files\n", szTotal, "", nRow);
644
+ }
645
+ db_finalize(&q);
646
+ }else if( doExtract ){
647
+ /* Extract files from an existing ZIP archive */
648
+ if( file_size(zArchiveName, eFType)<0 ){
649
+ fossil_fatal("No such ZIP archive: %s", zArchiveName);
650
+ }
651
+ if( g.argc>3 ){
652
+ fossil_fatal("extra arguments after \"fossil test-filezip -x ARCHIVE\"");
653
+ }
654
+ sqlite3_zipfile_init(g.db, 0, 0);
655
+ sqlite3_fileio_init(g.db, 0, 0);
656
+ db_multi_exec("CREATE VIRTUAL TABLE z1 USING zipfile(%Q)", zArchiveName);
657
+ db_multi_exec("SELECT writefile(name,data) FROM z1");
658
+ }else{
659
+ /* Without the -x or -l options, construct a new ZIP archive */
660
+ int i;
661
+ Blob zip;
662
+ Blob file;
663
+ Archive sArchive;
664
+ memset(&sArchive, 0, sizeof(Archive));
665
+ sArchive.eType = ARCHIVE_ZIP;
666
+ sArchive.pBlob = &zip;
667
+ if( file_size(zArchiveName, eFType)>0 ){
668
+ fossil_fatal("ZIP archive %s already exists", zArchiveName);
669
+ }
670
+ zip_open();
671
+ for(i=3; i<g.argc; i++){
672
+ double rDate;
673
+ i64 iDate;
674
+ blob_zero(&file);
675
+ blob_read_from_file(&file, g.argv[i], eFType);
676
+ iDate = file_mtime(g.argv[i], eFType);
677
+ rDate = ((double)iDate)/86400.0 + 2440587.5;
678
+ zip_set_timedate(rDate);
679
+ zip_add_file(&sArchive, g.argv[i], &file, file_perm(0,eFType));
680
+ blob_reset(&file);
681
+ }
682
+ zip_close(&sArchive);
683
+ blob_write_to_file(&zip, g.argv[2]);
684
+ }
603685
}
604686
605687
/*
606688
** Given the RID for a manifest, construct a ZIP archive containing
607689
** all files in the corresponding baseline.
608690
--- src/zip.c
+++ src/zip.c
@@ -562,46 +562,128 @@
562 fossil_free(azDir);
563 nDir = 0;
564 azDir = 0;
565 }
566
 
 
 
 
567 /*
568 ** COMMAND: test-filezip
569 **
570 ** Generate a ZIP archive specified by the first argument that
571 ** contains files given in the second and subsequent arguments.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
572 */
573 void filezip_cmd(void){
574 int i;
575 Blob zip;
576 Blob file;
577 int eFType = SymFILE;
578 Archive sArchive;
579 memset(&sArchive, 0, sizeof(Archive));
580 sArchive.eType = ARCHIVE_ZIP;
581 sArchive.pBlob = &zip;
582 if( find_option("dereference","h",0)!=0 ){
583 eFType = ExtFILE;
584 }
 
 
 
 
 
 
 
 
 
585 if( g.argc<3 ){
586 usage("ARCHIVE FILE....");
587 }
 
588 sqlite3_open(":memory:", &g.db);
589 zip_open();
590 for(i=3; i<g.argc; i++){
591 double rDate;
592 i64 iDate;
593 blob_zero(&file);
594 blob_read_from_file(&file, g.argv[i], eFType);
595 iDate = file_mtime(g.argv[i], eFType);
596 rDate = ((double)iDate)/86400.0 + 2440587.5;
597 zip_set_timedate(rDate);
598 zip_add_file(&sArchive, g.argv[i], &file, file_perm(0,eFType));
599 blob_reset(&file);
600 }
601 zip_close(&sArchive);
602 blob_write_to_file(&zip, g.argv[2]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
603 }
604
605 /*
606 ** Given the RID for a manifest, construct a ZIP archive containing
607 ** all files in the corresponding baseline.
608
--- src/zip.c
+++ src/zip.c
@@ -562,46 +562,128 @@
562 fossil_free(azDir);
563 nDir = 0;
564 azDir = 0;
565 }
566
567 /* Functions found in shell.c */
568 extern int sqlite3_fileio_init(sqlite3*,char**,const sqlite3_api_routines*);
569 extern int sqlite3_zipfile_init(sqlite3*,char**,const sqlite3_api_routines*);
570
571 /*
572 ** COMMAND: test-filezip
573 **
574 ** Usage: %fossil test-filezip [OPTIONS] ZIPFILE [FILENAME...]
575 **
576 ** This command uses Fossil infrastructure or read or create a ZIP
577 ** archive named by the ZIPFILE argument. With no options, a new
578 ** ZIP archive is created and there must be at least one FILENAME
579 ** argument. If the -l option is used, the contents of the named ZIP
580 ** archive are listed on standard output. With the -x argument, the
581 ** contents of the ZIP archive are extracted.
582 **
583 ** There are two purposes for this command: (1) To server as a test
584 ** platform for the Fossil ZIP archive generator, and (2) to provide
585 ** rudimentary ZIP archive creation capabilities on platforms that do
586 ** not have the "zip" command installed.
587 **
588 ** Options:
589 **
590 ** -h|--dereference Follow symlinks
591 ** -l|--list List the contents of the ZIP archive
592 ** -x|--extract Extract files from a ZIP archive
593 */
594 void filezip_cmd(void){
 
 
 
595 int eFType = SymFILE;
596 int doList = 0;
597 int doExtract = 0;
598 char *zArchiveName;
 
599 if( find_option("dereference","h",0)!=0 ){
600 eFType = ExtFILE;
601 }
602 if( find_option("list","l",0)!=0 ){
603 doList = 1;
604 }
605 if( find_option("extract","x",0)!=0 ){
606 if( doList ){
607 fossil_fatal("incompatible options: -l and -x");
608 }
609 doExtract = 1;
610 }
611 if( g.argc<3 ){
612 usage("ARCHIVE FILES...");
613 }
614 zArchiveName = g.argv[2];
615 sqlite3_open(":memory:", &g.db);
616 if( doList ){
617 /* Do a content listing of a ZIP archive */
618 Stmt q;
619 int nRow = 0;
620 i64 szTotal = 0;
621 if( file_size(zArchiveName, eFType)<0 ){
622 fossil_fatal("No such ZIP archive: %s", zArchiveName);
623 }
624 if( g.argc>3 ){
625 fossil_fatal("extra arguments after \"fossil test-filezip -l ARCHIVE\"");
626 }
627 sqlite3_zipfile_init(g.db, 0, 0);
628 db_multi_exec("CREATE VIRTUAL TABLE z1 USING zipfile(%Q)", zArchiveName);
629 db_prepare(&q, "SELECT sz, datetime(mtime,'unixepoch'), name FROM z1");
630 while( db_step(&q)==SQLITE_ROW ){
631 int sz = db_column_int(&q, 0);
632 szTotal += sz;
633 if( nRow==0 ){
634 fossil_print(" Length Date Time Name\n");
635 fossil_print("--------- ---------- ----- ----\n");
636 }
637 nRow++;
638 fossil_print("%9d %.16s %s\n", sz, db_column_text(&q,1),
639 db_column_text(&q,2));
640 }
641 if( nRow ){
642 fossil_print("--------- --------\n");
643 fossil_print("%9lld %16s %d files\n", szTotal, "", nRow);
644 }
645 db_finalize(&q);
646 }else if( doExtract ){
647 /* Extract files from an existing ZIP archive */
648 if( file_size(zArchiveName, eFType)<0 ){
649 fossil_fatal("No such ZIP archive: %s", zArchiveName);
650 }
651 if( g.argc>3 ){
652 fossil_fatal("extra arguments after \"fossil test-filezip -x ARCHIVE\"");
653 }
654 sqlite3_zipfile_init(g.db, 0, 0);
655 sqlite3_fileio_init(g.db, 0, 0);
656 db_multi_exec("CREATE VIRTUAL TABLE z1 USING zipfile(%Q)", zArchiveName);
657 db_multi_exec("SELECT writefile(name,data) FROM z1");
658 }else{
659 /* Without the -x or -l options, construct a new ZIP archive */
660 int i;
661 Blob zip;
662 Blob file;
663 Archive sArchive;
664 memset(&sArchive, 0, sizeof(Archive));
665 sArchive.eType = ARCHIVE_ZIP;
666 sArchive.pBlob = &zip;
667 if( file_size(zArchiveName, eFType)>0 ){
668 fossil_fatal("ZIP archive %s already exists", zArchiveName);
669 }
670 zip_open();
671 for(i=3; i<g.argc; i++){
672 double rDate;
673 i64 iDate;
674 blob_zero(&file);
675 blob_read_from_file(&file, g.argv[i], eFType);
676 iDate = file_mtime(g.argv[i], eFType);
677 rDate = ((double)iDate)/86400.0 + 2440587.5;
678 zip_set_timedate(rDate);
679 zip_add_file(&sArchive, g.argv[i], &file, file_perm(0,eFType));
680 blob_reset(&file);
681 }
682 zip_close(&sArchive);
683 blob_write_to_file(&zip, g.argv[2]);
684 }
685 }
686
687 /*
688 ** Given the RID for a manifest, construct a ZIP archive containing
689 ** all files in the corresponding baseline.
690

Keyboard Shortcuts

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