Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Add links to tarball and ZIP downloads from /dir and /tree pages. Standardize ZIP and tarball basenames using the archive_base_name() routine. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | timeline-enhance-2025 |
| Files: | files | file ages | folders |
| SHA3-256: |
983331a13a9062e23f103246c52f8ce9 |
| User & Date: | drh 2025-10-18 01:20:56.539 |
Context
|
2025-10-18
| ||
| 01:43 | Remove the "tarzip" query parameter from /timeline. Make the default suggested-tarlist be "off" so that the /tarlist pages is disabled by default. check-in: bdbf5db222 user: drh tags: timeline-enhance-2025 | |
| 01:20 | Add links to tarball and ZIP downloads from /dir and /tree pages. Standardize ZIP and tarball basenames using the archive_base_name() routine. check-in: 983331a13a user: drh tags: timeline-enhance-2025 | |
|
2025-10-17
| ||
| 16:38 | Change the title of the /brtimeline page back to the way it was. Add the timelineX restriction to /brtimeline. check-in: 881b705b65 user: drh tags: timeline-enhance-2025 | |
Changes
Changes to src/browse.c.
| ︙ | ︙ | |||
227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
zHeader = mprintf("%z matching \"%s\"", zHeader, zRegexp);
zMatch = mprintf(" matching \"%h\"", zRegexp);
}else{
zMatch = "";
}
style_header("%s", zHeader);
fossil_free(zHeader);
style_adunit_config(ADUNIT_RIGHT_OK);
sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0,
pathelementFunc, 0, 0);
url_initialize(&sURI, "dir");
cgi_check_for_malice();
cgi_query_parameters_to_url(&sURI);
| > > > > > > > > | 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 |
zHeader = mprintf("%z matching \"%s\"", zHeader, zRegexp);
zMatch = mprintf(" matching \"%h\"", zRegexp);
}else{
zMatch = "";
}
style_header("%s", zHeader);
fossil_free(zHeader);
if( rid && zD==0 && zMatch[0]==0 && g.perm.Zip ){
char *zBase = archive_base_name(rid);
style_submenu_element("Tarball","%R/tarball/%!S/%s.tar.gz",
zUuid, zBase);
style_submenu_element("ZIP","%R/zip/%!S/%s.zip",
zUuid, zBase);
fossil_free(zBase);
}
style_adunit_config(ADUNIT_RIGHT_OK);
sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0,
pathelementFunc, 0, 0);
url_initialize(&sURI, "dir");
cgi_check_for_malice();
cgi_query_parameters_to_url(&sURI);
|
| ︙ | ︙ | |||
812 813 814 815 816 817 818 819 820 821 822 823 824 825 |
if( zCI ){
if( nD==0 && !showDirOnly ){
style_submenu_element("File Ages", "%R/fileage?name=%T", zCI);
}
}
style_submenu_element("Flat-View", "%s",
url_render(&sURI, "type", "flat", 0, 0));
/* Compute the file hierarchy.
*/
if( zCI ){
Stmt q;
compute_fileage(rid, 0);
db_prepare(&q,
| > > > > > > > > | 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 |
if( zCI ){
if( nD==0 && !showDirOnly ){
style_submenu_element("File Ages", "%R/fileage?name=%T", zCI);
}
}
style_submenu_element("Flat-View", "%s",
url_render(&sURI, "type", "flat", 0, 0));
if( rid && zD==0 && zRE==0 && !showDirOnly && g.perm.Zip ){
char *zBase = archive_base_name(rid);
style_submenu_element("Tarball","%R/tarball/%!S/%s.tar.gz",
zUuid, zBase);
style_submenu_element("ZIP","%R/zip/%!S/%s.zip",
zUuid, zBase);
fossil_free(zBase);
}
/* Compute the file hierarchy.
*/
if( zCI ){
Stmt q;
compute_fileage(rid, 0);
db_prepare(&q,
|
| ︙ | ︙ |
Changes to src/db.c.
| ︙ | ︙ | |||
1226 1227 1228 1229 1230 1231 1232 | } db_finalize(&s); } /* ** Execute a query. Return the first column of the first row ** of the result set as a string. Space to hold the string is | | | | 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 |
}
db_finalize(&s);
}
/*
** Execute a query. Return the first column of the first row
** of the result set as a string. Space to hold the string is
** obtained from fossil_strdup() and should be freed using fossil_free().
** If the result set is empty, return a copy of zDefault instead.
*/
char *db_text(const char *zDefault, const char *zSql, ...){
va_list ap;
Stmt s;
char *z;
va_start(ap, zSql);
db_vprepare(&s, 0, zSql, ap);
|
| ︙ | ︙ |
Changes to src/tar.c.
| ︙ | ︙ | |||
29 30 31 32 33 34 35 36 37 38 39 40 41 42 | unsigned char *aHdr; /* Space for building headers */ char *zSpaces; /* Spaces for padding */ char *zPrevDir; /* Name of directory for previous entry */ int nPrevDirAlloc; /* size of zPrevDir */ Blob pax; /* PAX data */ } tball; /* ** field lengths of 'ustar' name and prefix fields. */ #define USTAR_NAME_LEN 100 #define USTAR_PREFIX_LEN 155 | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
unsigned char *aHdr; /* Space for building headers */
char *zSpaces; /* Spaces for padding */
char *zPrevDir; /* Name of directory for previous entry */
int nPrevDirAlloc; /* size of zPrevDir */
Blob pax; /* PAX data */
} tball;
/*
** Compute a sensible base-name for an archive file (tarball, ZIP, or SQLAR)
** based on the rid of the check-in contained in that file.
**
** PROJECTNAME-DATETIME-HASHPREFIX
**
** So that the name will be safe to use as a URL or a filename on any system,
** the name is only allowed to contain lower-case ASCII alphabetics,
** digits, '_' and '-'. Upper-case ASCII is converted to lower-case. All
** other bytes are mapped into a lower-case alphabetic.
**
** The value returned is obtained from mprintf() or fossil_strdup() and should
** be released by the caller using fossil_free().
*/
char *archive_base_name(int rid){
char *zName;
int i;
char c;
zName = db_text(0,
"SELECT coalesce(config.value,'unnamed')||"
" strftime('-%%Y%%m%%d%%H%%M%%S-',event.mtime)||"
" substr(blob.uuid,1,10)"
" FROM blob, event LEFT JOIN config"
" WHERE blob.rid=%d"
" AND event.objid=%d"
" AND config.name='project-name'",
rid, rid);
for(i=0; (c = zName[i])!=0; i++){
if( fossil_isupper(c) ){
zName[i] = fossil_tolower(c);
}else if( !fossil_isalnum(c) && c!='_' && c!='-' ){
/* 123456789 123456789 123456 */
zName[i] = "abcdefghijklmnopqrstuvwxyz"[(unsigned)c%26];
}
}
return zName;
}
/*
** field lengths of 'ustar' name and prefix fields.
*/
#define USTAR_NAME_LEN 100
#define USTAR_PREFIX_LEN 155
|
| ︙ | ︙ | |||
651 652 653 654 655 656 657 |
}
zOut = g.argv[3];
if( fossil_strcmp("/dev/null",zOut)==0 || fossil_strcmp("",zOut)==0 ){
zOut = 0;
}
if( zName==0 ){
| | < < < < < < < < | 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 |
}
zOut = g.argv[3];
if( fossil_strcmp("/dev/null",zOut)==0 || fossil_strcmp("",zOut)==0 ){
zOut = 0;
}
if( zName==0 ){
zName = archive_base_name(rid);
}
tarball_of_checkin(rid, zOut ? &tarball : 0,
zName, pInclude, pExclude, listFlag);
glob_free(pInclude);
glob_free(pExclude);
if( listFlag ) fflush(stdout);
if( zOut ){
|
| ︙ | ︙ |
Changes to src/zip.c.
| ︙ | ︙ | |||
862 863 864 865 866 867 868 |
}
zOut = g.argv[3];
if( fossil_strcmp(zOut,"")==0 || fossil_strcmp(zOut,"/dev/null")==0 ){
zOut = 0;
}
if( zName==0 ){
| | < < < < < < < < | 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 |
}
zOut = g.argv[3];
if( fossil_strcmp(zOut,"")==0 || fossil_strcmp(zOut,"/dev/null")==0 ){
zOut = 0;
}
if( zName==0 ){
zName = archive_base_name(rid);
}
zip_of_checkin(eType, rid, zOut ? &zip : 0,
zName, pInclude, pExclude, listFlag);
glob_free(pInclude);
glob_free(pExclude);
if( zOut ){
blob_write_to_file(&zip, zOut);
|
| ︙ | ︙ |