Fossil SCM

Update /dir to support readme and readme.* files being a symlink to the actual document. Symlinks to symlinks are not supported in this instance. The document type is determined by the link target name.

andygoth 2017-10-14 23:20 UTC trunk
Commit eb4dda482056b1db9667927d0ffee24ee3a08bd834b6b39b2dcf5ca334ffddc1
2 files changed +53 -26 +3
+53 -26
--- src/browse.c
+++ src/browse.c
@@ -212,21 +212,21 @@
212212
** Subdirectory names begin with "/". This causes them to sort
213213
** first and it also gives us an easy way to distinguish files
214214
** from directories in the loop that follows.
215215
*/
216216
db_multi_exec(
217
- "CREATE TEMP TABLE localfiles(x UNIQUE NOT NULL, u);"
217
+ "CREATE TEMP TABLE localfiles(x UNIQUE NOT NULL, u, l);"
218218
);
219219
if( zCI ){
220220
Stmt ins;
221221
ManifestFile *pFile;
222222
ManifestFile *pPrev = 0;
223223
int nPrev = 0;
224224
int c;
225225
226226
db_prepare(&ins,
227
- "INSERT OR IGNORE INTO localfiles VALUES(pathelement(:x,0), :u)"
227
+ "INSERT OR IGNORE INTO localfiles VALUES(pathelement(:x,0), :u, :l)"
228228
);
229229
manifest_file_rewind(pM);
230230
while( (pFile = manifest_file_next(pM,0))!=0 ){
231231
if( nD>0
232232
&& (fossil_strncmp(pFile->zName, zD, nD-1)!=0
@@ -240,10 +240,11 @@
240240
){
241241
continue;
242242
}
243243
db_bind_text(&ins, ":x", &pFile->zName[nD]);
244244
db_bind_text(&ins, ":u", pFile->zUuid);
245
+ db_bind_int(&ins, ":l", pFile->zPerm && strchr(pFile->zPerm, 'l')!=0);
245246
db_step(&ins);
246247
db_reset(&ins);
247248
pPrev = pFile;
248249
for(nPrev=0; (c=pPrev->zName[nD+nPrev]) && c!='/'; nPrev++){}
249250
if( c=='/' ) nPrev++;
@@ -250,18 +251,18 @@
250251
}
251252
db_finalize(&ins);
252253
}else if( zD ){
253254
db_multi_exec(
254255
"INSERT OR IGNORE INTO localfiles"
255
- " SELECT pathelement(name,%d), NULL FROM filename"
256
+ " SELECT pathelement(name,%d,0), NULL FROM filename"
256257
" WHERE name GLOB '%q/*'",
257258
nD, zD
258259
);
259260
}else{
260261
db_multi_exec(
261262
"INSERT OR IGNORE INTO localfiles"
262
- " SELECT pathelement(name,0), NULL FROM filename"
263
+ " SELECT pathelement(name,0,0), NULL FROM filename"
263264
);
264265
}
265266
266267
/* Generate a multi-column table listing the contents of zD[]
267268
** directory.
@@ -304,41 +305,67 @@
304305
305306
/* If the directory contains a readme file, then display its content below
306307
** the list of files
307308
*/
308309
db_prepare(&q,
309
- "SELECT x, u FROM localfiles"
310
+ "SELECT x, u, l FROM localfiles"
310311
" WHERE x COLLATE nocase IN"
311312
" ('readme','readme.txt','readme.md','readme.wiki','readme.markdown',"
312313
" 'readme.html') ORDER BY x LIMIT 1;"
313314
);
314315
if( db_step(&q)==SQLITE_ROW ){
315316
const char *zName = db_column_text(&q,0);
316317
const char *zUuid = db_column_text(&q,1);
318
+ int isLink = db_column_int(&q,2);
317319
if( zUuid ){
318320
rid = fast_uuid_to_rid(zUuid);
319
- }else{
320
- if( zD ){
321
- rid = db_int(0,
322
- "SELECT fid FROM filename, mlink, event"
323
- " WHERE name='%q/%q'"
324
- " AND mlink.fnid=filename.fnid"
325
- " AND event.objid=mlink.mid"
326
- " ORDER BY event.mtime DESC LIMIT 1",
327
- zD, zName
328
- );
329
- }else{
330
- rid = db_int(0,
331
- "SELECT fid FROM filename, mlink, event"
332
- " WHERE name='%q'"
333
- " AND mlink.fnid=filename.fnid"
334
- " AND event.objid=mlink.mid"
335
- " ORDER BY event.mtime DESC LIMIT 1",
336
- zName
337
- );
338
- }
339
- }
321
+ }else if( zD ){
322
+ rid = db_int(0,
323
+ "SELECT fid FROM filename, mlink, event"
324
+ " WHERE name='%q/%q'"
325
+ " AND mlink.fnid=filename.fnid"
326
+ " AND event.objid=mlink.mid"
327
+ " ORDER BY event.mtime DESC LIMIT 1",
328
+ zD, zName
329
+ );
330
+ }else{
331
+ rid = db_int(0,
332
+ "SELECT fid FROM filename, mlink, event"
333
+ " WHERE name='%q'"
334
+ " AND mlink.fnid=filename.fnid"
335
+ " AND event.objid=mlink.mid"
336
+ " ORDER BY event.mtime DESC LIMIT 1",
337
+ zName
338
+ );
339
+ }
340
+
341
+ /* If the README file is a symlink, dereference it to find the actual
342
+ * document. To keep things simple and to avoid infinite loops, do not
343
+ * attempt more than one level of dereferencing. */
344
+ if( rid && isLink ){
345
+ char *zDir, *zNewName;
346
+ Blob content;
347
+ content_get(rid, &content);
348
+ zDir = file_dirname(zName);
349
+ if( zDir ){
350
+ zNewName = mprintf("%s/%s", zDir, blob_buffer(&content));
351
+ }else{
352
+ zNewName = blob_buffer(&content);
353
+ }
354
+ file_simplify_name(zNewName, -1, 0);
355
+ rid = db_int(0,
356
+ "SELECT fid FROM filename, mlink, event"
357
+ " WHERE name='%q'"
358
+ " AND mlink.fnid=filename.fnid"
359
+ " AND event.objid=mlink.mid"
360
+ " ORDER BY event.mtime DESC LIMIT 1",
361
+ zNewName
362
+ );
363
+ zName = zNewName;
364
+ zUuid = 0;
365
+ }
366
+
340367
if( rid ){
341368
@ <hr>
342369
if( sqlite3_strlike("readme.html", zName, 0)==0 ){
343370
if( zUuid==0 ){
344371
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
345372
--- src/browse.c
+++ src/browse.c
@@ -212,21 +212,21 @@
212 ** Subdirectory names begin with "/". This causes them to sort
213 ** first and it also gives us an easy way to distinguish files
214 ** from directories in the loop that follows.
215 */
216 db_multi_exec(
217 "CREATE TEMP TABLE localfiles(x UNIQUE NOT NULL, u);"
218 );
219 if( zCI ){
220 Stmt ins;
221 ManifestFile *pFile;
222 ManifestFile *pPrev = 0;
223 int nPrev = 0;
224 int c;
225
226 db_prepare(&ins,
227 "INSERT OR IGNORE INTO localfiles VALUES(pathelement(:x,0), :u)"
228 );
229 manifest_file_rewind(pM);
230 while( (pFile = manifest_file_next(pM,0))!=0 ){
231 if( nD>0
232 && (fossil_strncmp(pFile->zName, zD, nD-1)!=0
@@ -240,10 +240,11 @@
240 ){
241 continue;
242 }
243 db_bind_text(&ins, ":x", &pFile->zName[nD]);
244 db_bind_text(&ins, ":u", pFile->zUuid);
 
245 db_step(&ins);
246 db_reset(&ins);
247 pPrev = pFile;
248 for(nPrev=0; (c=pPrev->zName[nD+nPrev]) && c!='/'; nPrev++){}
249 if( c=='/' ) nPrev++;
@@ -250,18 +251,18 @@
250 }
251 db_finalize(&ins);
252 }else if( zD ){
253 db_multi_exec(
254 "INSERT OR IGNORE INTO localfiles"
255 " SELECT pathelement(name,%d), NULL FROM filename"
256 " WHERE name GLOB '%q/*'",
257 nD, zD
258 );
259 }else{
260 db_multi_exec(
261 "INSERT OR IGNORE INTO localfiles"
262 " SELECT pathelement(name,0), NULL FROM filename"
263 );
264 }
265
266 /* Generate a multi-column table listing the contents of zD[]
267 ** directory.
@@ -304,41 +305,67 @@
304
305 /* If the directory contains a readme file, then display its content below
306 ** the list of files
307 */
308 db_prepare(&q,
309 "SELECT x, u FROM localfiles"
310 " WHERE x COLLATE nocase IN"
311 " ('readme','readme.txt','readme.md','readme.wiki','readme.markdown',"
312 " 'readme.html') ORDER BY x LIMIT 1;"
313 );
314 if( db_step(&q)==SQLITE_ROW ){
315 const char *zName = db_column_text(&q,0);
316 const char *zUuid = db_column_text(&q,1);
 
317 if( zUuid ){
318 rid = fast_uuid_to_rid(zUuid);
319 }else{
320 if( zD ){
321 rid = db_int(0,
322 "SELECT fid FROM filename, mlink, event"
323 " WHERE name='%q/%q'"
324 " AND mlink.fnid=filename.fnid"
325 " AND event.objid=mlink.mid"
326 " ORDER BY event.mtime DESC LIMIT 1",
327 zD, zName
328 );
329 }else{
330 rid = db_int(0,
331 "SELECT fid FROM filename, mlink, event"
332 " WHERE name='%q'"
333 " AND mlink.fnid=filename.fnid"
334 " AND event.objid=mlink.mid"
335 " ORDER BY event.mtime DESC LIMIT 1",
336 zName
337 );
338 }
339 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
340 if( rid ){
341 @ <hr>
342 if( sqlite3_strlike("readme.html", zName, 0)==0 ){
343 if( zUuid==0 ){
344 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
345
--- src/browse.c
+++ src/browse.c
@@ -212,21 +212,21 @@
212 ** Subdirectory names begin with "/". This causes them to sort
213 ** first and it also gives us an easy way to distinguish files
214 ** from directories in the loop that follows.
215 */
216 db_multi_exec(
217 "CREATE TEMP TABLE localfiles(x UNIQUE NOT NULL, u, l);"
218 );
219 if( zCI ){
220 Stmt ins;
221 ManifestFile *pFile;
222 ManifestFile *pPrev = 0;
223 int nPrev = 0;
224 int c;
225
226 db_prepare(&ins,
227 "INSERT OR IGNORE INTO localfiles VALUES(pathelement(:x,0), :u, :l)"
228 );
229 manifest_file_rewind(pM);
230 while( (pFile = manifest_file_next(pM,0))!=0 ){
231 if( nD>0
232 && (fossil_strncmp(pFile->zName, zD, nD-1)!=0
@@ -240,10 +240,11 @@
240 ){
241 continue;
242 }
243 db_bind_text(&ins, ":x", &pFile->zName[nD]);
244 db_bind_text(&ins, ":u", pFile->zUuid);
245 db_bind_int(&ins, ":l", pFile->zPerm && strchr(pFile->zPerm, 'l')!=0);
246 db_step(&ins);
247 db_reset(&ins);
248 pPrev = pFile;
249 for(nPrev=0; (c=pPrev->zName[nD+nPrev]) && c!='/'; nPrev++){}
250 if( c=='/' ) nPrev++;
@@ -250,18 +251,18 @@
251 }
252 db_finalize(&ins);
253 }else if( zD ){
254 db_multi_exec(
255 "INSERT OR IGNORE INTO localfiles"
256 " SELECT pathelement(name,%d,0), NULL FROM filename"
257 " WHERE name GLOB '%q/*'",
258 nD, zD
259 );
260 }else{
261 db_multi_exec(
262 "INSERT OR IGNORE INTO localfiles"
263 " SELECT pathelement(name,0,0), NULL FROM filename"
264 );
265 }
266
267 /* Generate a multi-column table listing the contents of zD[]
268 ** directory.
@@ -304,41 +305,67 @@
305
306 /* If the directory contains a readme file, then display its content below
307 ** the list of files
308 */
309 db_prepare(&q,
310 "SELECT x, u, l FROM localfiles"
311 " WHERE x COLLATE nocase IN"
312 " ('readme','readme.txt','readme.md','readme.wiki','readme.markdown',"
313 " 'readme.html') ORDER BY x LIMIT 1;"
314 );
315 if( db_step(&q)==SQLITE_ROW ){
316 const char *zName = db_column_text(&q,0);
317 const char *zUuid = db_column_text(&q,1);
318 int isLink = db_column_int(&q,2);
319 if( zUuid ){
320 rid = fast_uuid_to_rid(zUuid);
321 }else if( zD ){
322 rid = db_int(0,
323 "SELECT fid FROM filename, mlink, event"
324 " WHERE name='%q/%q'"
325 " AND mlink.fnid=filename.fnid"
326 " AND event.objid=mlink.mid"
327 " ORDER BY event.mtime DESC LIMIT 1",
328 zD, zName
329 );
330 }else{
331 rid = db_int(0,
332 "SELECT fid FROM filename, mlink, event"
333 " WHERE name='%q'"
334 " AND mlink.fnid=filename.fnid"
335 " AND event.objid=mlink.mid"
336 " ORDER BY event.mtime DESC LIMIT 1",
337 zName
338 );
339 }
340
341 /* If the README file is a symlink, dereference it to find the actual
342 * document. To keep things simple and to avoid infinite loops, do not
343 * attempt more than one level of dereferencing. */
344 if( rid && isLink ){
345 char *zDir, *zNewName;
346 Blob content;
347 content_get(rid, &content);
348 zDir = file_dirname(zName);
349 if( zDir ){
350 zNewName = mprintf("%s/%s", zDir, blob_buffer(&content));
351 }else{
352 zNewName = blob_buffer(&content);
353 }
354 file_simplify_name(zNewName, -1, 0);
355 rid = db_int(0,
356 "SELECT fid FROM filename, mlink, event"
357 " WHERE name='%q'"
358 " AND mlink.fnid=filename.fnid"
359 " AND event.objid=mlink.mid"
360 " ORDER BY event.mtime DESC LIMIT 1",
361 zNewName
362 );
363 zName = zNewName;
364 zUuid = 0;
365 }
366
367 if( rid ){
368 @ <hr>
369 if( sqlite3_strlike("readme.html", zName, 0)==0 ){
370 if( zUuid==0 ){
371 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
372
--- www/changes.wiki
+++ www/changes.wiki
@@ -30,10 +30,13 @@
3030
[/help?cmd=zip|zip], and [/help?cmd=tarball|tarball] pages and commands to
3131
honor the versioned manifest setting when outside of an open checkout
3232
directory.
3333
* The admin-log and access-log settings are now on by default for
3434
new repositories.
35
+ * Update /dir to support readme and readme.* files being a symlink to the
36
+ actual document. Symlinks to symlinks are not supported in this instance.
37
+ The document type is determined by the link target name.
3538
* Update the built-in SQLite to version 3.20.1.
3639
3740
<a name='v2_3'></a>
3841
<h2>Changes for Version 2.3 (2017-07-21)</h2>
3942
4043
--- www/changes.wiki
+++ www/changes.wiki
@@ -30,10 +30,13 @@
30 [/help?cmd=zip|zip], and [/help?cmd=tarball|tarball] pages and commands to
31 honor the versioned manifest setting when outside of an open checkout
32 directory.
33 * The admin-log and access-log settings are now on by default for
34 new repositories.
 
 
 
35 * Update the built-in SQLite to version 3.20.1.
36
37 <a name='v2_3'></a>
38 <h2>Changes for Version 2.3 (2017-07-21)</h2>
39
40
--- www/changes.wiki
+++ www/changes.wiki
@@ -30,10 +30,13 @@
30 [/help?cmd=zip|zip], and [/help?cmd=tarball|tarball] pages and commands to
31 honor the versioned manifest setting when outside of an open checkout
32 directory.
33 * The admin-log and access-log settings are now on by default for
34 new repositories.
35 * Update /dir to support readme and readme.* files being a symlink to the
36 actual document. Symlinks to symlinks are not supported in this instance.
37 The document type is determined by the link target name.
38 * Update the built-in SQLite to version 3.20.1.
39
40 <a name='v2_3'></a>
41 <h2>Changes for Version 2.3 (2017-07-21)</h2>
42
43

Keyboard Shortcuts

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