Fossil SCM

Improved origin tracking for unversioned files. Show Admin/Setup users the rcvid and allow them to see the originating IP address and to delete unversioned files. Update the rcvfrom table viewer to include unversioned file entries.

drh 2016-08-23 01:22 trunk
Commit 8972aae720b007e1d6a95c72de83b028fa39aa6c
2 files changed +79 -3 +13 -1
+79 -3
--- src/shun.c
+++ src/shun.c
@@ -327,10 +327,15 @@
327327
}
328328
db_multi_exec(
329329
"CREATE TEMP TABLE rcvidUsed(x INTEGER PRIMARY KEY);"
330330
"INSERT OR IGNORE INTO rcvidUsed(x) SELECT rcvid FROM blob;"
331331
);
332
+ if( db_table_exists("repository","unversioned") ){
333
+ db_multi_exec(
334
+ "INSERT OR IGNORE INTO rcvidUsed(x) SELECT rcvid FROM unversioned;"
335
+ );
336
+ }
332337
db_prepare(&q,
333338
"SELECT rcvid, login, datetime(rcvfrom.mtime), rcvfrom.ipaddr,"
334339
" EXISTS(SELECT 1 FROM rcvidUsed WHERE x=rcvfrom.rcvid)"
335340
" FROM rcvfrom LEFT JOIN user USING(uid)"
336341
" ORDER BY rcvid DESC LIMIT %d OFFSET %d",
@@ -389,10 +394,11 @@
389394
** parameters. Requires Admin privilege.
390395
*/
391396
void rcvfrom_page(void){
392397
int rcvid = atoi(PD("rcvid","0"));
393398
Stmt q;
399
+ int cnt;
394400
395401
login_check_credentials();
396402
if( !g.perm.Admin ){
397403
login_needed(0);
398404
return;
@@ -441,20 +447,90 @@
441447
db_prepare(&q,
442448
"SELECT blob.rid, blob.uuid, blob.size, description.summary\n"
443449
" FROM blob LEFT JOIN description ON (blob.rid=description.rid)"
444450
" WHERE blob.rcvid=%d", rcvid
445451
);
446
- @ <tr><th valign="top" align="right">Artifacts:</th>
447
- @ <td valign="top">
452
+ cnt = 0;
448453
while( db_step(&q)==SQLITE_ROW ){
449454
const char *zUuid = db_column_text(&q, 1);
450455
int size = db_column_int(&q, 2);
451456
const char *zDesc = db_column_text(&q, 3);
452457
if( zDesc==0 ) zDesc = "";
458
+ if( cnt==0 ){
459
+ @ <tr><th valign="top" align="right">Artifacts:</th>
460
+ @ <td valign="top">
461
+ }
462
+ cnt++;
453463
@ <a href="%R/info/%s(zUuid)">%s(zUuid)</a>
454464
@ %h(zDesc) (size: %d(size))<br />
455465
}
456
- @ </td></tr>
466
+ if( cnt>0 ){
467
+ @ <p>
468
+ if( db_exists(
469
+ "SELECT 1 FROM blob WHERE rcvid=%d AND"
470
+ " NOT EXISTS (SELECT 1 FROM shun WHERE shun.uuid=blob.uuid)", rcvid)
471
+ ){
472
+ @ <form action='%R/shun'>
473
+ @ <input type="hidden" name="shun">
474
+ @ <input type="hidden" name="rcvid" value='%d(rcvid)'>
475
+ @ <input type="submit" value="Shun All These Artifacts">
476
+ @ </form>
477
+ }
478
+ if( db_exists(
479
+ "SELECT 1 FROM blob WHERE rcvid=%d AND"
480
+ " EXISTS (SELECT 1 FROM shun WHERE shun.uuid=blob.uuid)", rcvid)
481
+ ){
482
+ @ <form action='%R/shun'>
483
+ @ <input type="hidden" name="unshun">
484
+ @ <input type="hidden" name="rcvid" value='%d(rcvid)'>
485
+ @ <input type="submit" value="Unshun All These Artifacts">
486
+ @ </form>
487
+ }
488
+ @ </td></tr>
489
+ }
490
+ if( db_table_exists("repository","unversioned") ){
491
+ cnt = 0;
492
+ if( PB("uvdelete") && PB("confirmdelete") ){
493
+ db_multi_exec(
494
+ "DELETE FROM unversioned WHERE rcvid=%d", rcvid
495
+ );
496
+ }
497
+ db_finalize(&q);
498
+ db_prepare(&q,
499
+ "SELECT name, hash, sz\n"
500
+ " FROM unversioned "
501
+ " WHERE rcvid=%d", rcvid
502
+
457503
);
504
+ while( db_step(&q)==SQLITE_ROW ){
505
+ const char *zName = db_column_text(&q,0);
506
+ const char *zHash = db_column_text(&q,1);
507
+ int size = db_column_int(&q,2);
508
+ int isDeleted = zHash==0;
509
+ if( cnt==0 ){
510
+ @ <tr><th valign="top" align="right">Unversioned&nbsp;Files:</th>
511
+ @ <td valign="top">
512
+ }
513
+ cnt++;
514
+ if( isDeleted ){
515
+ @ %h(zName) (deleted)<br />
516
+ }else{
517
+ @ <a href="%R/uv/%h(zName)">%h(zName)</a> (size: %d(size))<br />
518
+ }
519
+ }
520
+ if( cnt>0 ){
521
+ @ <p><form action='%R/rcvfrom'>
522
+ @ <input type="hidden" name="rcvid" value='%d(rcvid)'>
523
+ @ <input type="hidden" name="uvdelete" value="1">
524
+ if( PB("uvdelete") ){
525
+ @ <input type="hidden" name="confirmdelete" value="1">
526
+ @ <input type="submit" value="Confirm Deletion of These Files">
527
+ }else{
528
+ @ <input type="submit" value="Delete These Unversioned Files">
529
+ }
530
+ @ </form>
531
+ @ </td></tr>
532
+ }
533
+ }
458534
@ </table>
459535
db_finalize(&q);
460536
style_footer();
461537
}
462538
--- src/shun.c
+++ src/shun.c
@@ -327,10 +327,15 @@
327 }
328 db_multi_exec(
329 "CREATE TEMP TABLE rcvidUsed(x INTEGER PRIMARY KEY);"
330 "INSERT OR IGNORE INTO rcvidUsed(x) SELECT rcvid FROM blob;"
331 );
 
 
 
 
 
332 db_prepare(&q,
333 "SELECT rcvid, login, datetime(rcvfrom.mtime), rcvfrom.ipaddr,"
334 " EXISTS(SELECT 1 FROM rcvidUsed WHERE x=rcvfrom.rcvid)"
335 " FROM rcvfrom LEFT JOIN user USING(uid)"
336 " ORDER BY rcvid DESC LIMIT %d OFFSET %d",
@@ -389,10 +394,11 @@
389 ** parameters. Requires Admin privilege.
390 */
391 void rcvfrom_page(void){
392 int rcvid = atoi(PD("rcvid","0"));
393 Stmt q;
 
394
395 login_check_credentials();
396 if( !g.perm.Admin ){
397 login_needed(0);
398 return;
@@ -441,20 +447,90 @@
441 db_prepare(&q,
442 "SELECT blob.rid, blob.uuid, blob.size, description.summary\n"
443 " FROM blob LEFT JOIN description ON (blob.rid=description.rid)"
444 " WHERE blob.rcvid=%d", rcvid
445 );
446 @ <tr><th valign="top" align="right">Artifacts:</th>
447 @ <td valign="top">
448 while( db_step(&q)==SQLITE_ROW ){
449 const char *zUuid = db_column_text(&q, 1);
450 int size = db_column_int(&q, 2);
451 const char *zDesc = db_column_text(&q, 3);
452 if( zDesc==0 ) zDesc = "";
 
 
 
 
 
453 @ <a href="%R/info/%s(zUuid)">%s(zUuid)</a>
454 @ %h(zDesc) (size: %d(size))<br />
455 }
456 @ </td></tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
457 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
458 @ </table>
459 db_finalize(&q);
460 style_footer();
461 }
462
--- src/shun.c
+++ src/shun.c
@@ -327,10 +327,15 @@
327 }
328 db_multi_exec(
329 "CREATE TEMP TABLE rcvidUsed(x INTEGER PRIMARY KEY);"
330 "INSERT OR IGNORE INTO rcvidUsed(x) SELECT rcvid FROM blob;"
331 );
332 if( db_table_exists("repository","unversioned") ){
333 db_multi_exec(
334 "INSERT OR IGNORE INTO rcvidUsed(x) SELECT rcvid FROM unversioned;"
335 );
336 }
337 db_prepare(&q,
338 "SELECT rcvid, login, datetime(rcvfrom.mtime), rcvfrom.ipaddr,"
339 " EXISTS(SELECT 1 FROM rcvidUsed WHERE x=rcvfrom.rcvid)"
340 " FROM rcvfrom LEFT JOIN user USING(uid)"
341 " ORDER BY rcvid DESC LIMIT %d OFFSET %d",
@@ -389,10 +394,11 @@
394 ** parameters. Requires Admin privilege.
395 */
396 void rcvfrom_page(void){
397 int rcvid = atoi(PD("rcvid","0"));
398 Stmt q;
399 int cnt;
400
401 login_check_credentials();
402 if( !g.perm.Admin ){
403 login_needed(0);
404 return;
@@ -441,20 +447,90 @@
447 db_prepare(&q,
448 "SELECT blob.rid, blob.uuid, blob.size, description.summary\n"
449 " FROM blob LEFT JOIN description ON (blob.rid=description.rid)"
450 " WHERE blob.rcvid=%d", rcvid
451 );
452 cnt = 0;
 
453 while( db_step(&q)==SQLITE_ROW ){
454 const char *zUuid = db_column_text(&q, 1);
455 int size = db_column_int(&q, 2);
456 const char *zDesc = db_column_text(&q, 3);
457 if( zDesc==0 ) zDesc = "";
458 if( cnt==0 ){
459 @ <tr><th valign="top" align="right">Artifacts:</th>
460 @ <td valign="top">
461 }
462 cnt++;
463 @ <a href="%R/info/%s(zUuid)">%s(zUuid)</a>
464 @ %h(zDesc) (size: %d(size))<br />
465 }
466 if( cnt>0 ){
467 @ <p>
468 if( db_exists(
469 "SELECT 1 FROM blob WHERE rcvid=%d AND"
470 " NOT EXISTS (SELECT 1 FROM shun WHERE shun.uuid=blob.uuid)", rcvid)
471 ){
472 @ <form action='%R/shun'>
473 @ <input type="hidden" name="shun">
474 @ <input type="hidden" name="rcvid" value='%d(rcvid)'>
475 @ <input type="submit" value="Shun All These Artifacts">
476 @ </form>
477 }
478 if( db_exists(
479 "SELECT 1 FROM blob WHERE rcvid=%d AND"
480 " EXISTS (SELECT 1 FROM shun WHERE shun.uuid=blob.uuid)", rcvid)
481 ){
482 @ <form action='%R/shun'>
483 @ <input type="hidden" name="unshun">
484 @ <input type="hidden" name="rcvid" value='%d(rcvid)'>
485 @ <input type="submit" value="Unshun All These Artifacts">
486 @ </form>
487 }
488 @ </td></tr>
489 }
490 if( db_table_exists("repository","unversioned") ){
491 cnt = 0;
492 if( PB("uvdelete") && PB("confirmdelete") ){
493 db_multi_exec(
494 "DELETE FROM unversioned WHERE rcvid=%d", rcvid
495 );
496 }
497 db_finalize(&q);
498 db_prepare(&q,
499 "SELECT name, hash, sz\n"
500 " FROM unversioned "
501 " WHERE rcvid=%d", rcvid
502
503 );
504 while( db_step(&q)==SQLITE_ROW ){
505 const char *zName = db_column_text(&q,0);
506 const char *zHash = db_column_text(&q,1);
507 int size = db_column_int(&q,2);
508 int isDeleted = zHash==0;
509 if( cnt==0 ){
510 @ <tr><th valign="top" align="right">Unversioned&nbsp;Files:</th>
511 @ <td valign="top">
512 }
513 cnt++;
514 if( isDeleted ){
515 @ %h(zName) (deleted)<br />
516 }else{
517 @ <a href="%R/uv/%h(zName)">%h(zName)</a> (size: %d(size))<br />
518 }
519 }
520 if( cnt>0 ){
521 @ <p><form action='%R/rcvfrom'>
522 @ <input type="hidden" name="rcvid" value='%d(rcvid)'>
523 @ <input type="hidden" name="uvdelete" value="1">
524 if( PB("uvdelete") ){
525 @ <input type="hidden" name="confirmdelete" value="1">
526 @ <input type="submit" value="Confirm Deletion of These Files">
527 }else{
528 @ <input type="submit" value="Delete These Unversioned Files">
529 }
530 @ </form>
531 @ </td></tr>
532 }
533 }
534 @ </table>
535 db_finalize(&q);
536 style_footer();
537 }
538
--- src/unversioned.c
+++ src/unversioned.c
@@ -376,11 +376,12 @@
376376
" name,"
377377
" mtime,"
378378
" hash,"
379379
" sz,"
380380
" (SELECT login FROM rcvfrom, user"
381
- " WHERE user.uid=rcvfrom.uid AND rcvfrom.rcvid=unversioned.rcvid)"
381
+ " WHERE user.uid=rcvfrom.uid AND rcvfrom.rcvid=unversioned.rcvid),"
382
+ " rcvid"
382383
" FROM unversioned"
383384
);
384385
iNow = db_int64(0, "SELECT strftime('%%s','now');");
385386
while( db_step(&q)==SQLITE_ROW ){
386387
const char *zName = db_column_text(&q, 0);
@@ -388,10 +389,11 @@
388389
const char *zHash = db_column_text(&q, 2);
389390
int isDeleted = zHash==0;
390391
int fullSize = db_column_int(&q, 3);
391392
char *zAge = human_readable_age((iNow - mtime)/86400.0);
392393
const char *zLogin = db_column_text(&q, 4);
394
+ int rcvid = db_column_int(&q,5);
393395
if( zLogin==0 ) zLogin = "";
394396
if( (n++)==0 ){
395397
@ <div class="uvlist">
396398
@ <table cellpadding="2" cellspacing="0" border="1" id="uvtab">
397399
@ <thead><tr>
@@ -398,10 +400,13 @@
398400
@ <th> Name
399401
@ <th> Age
400402
@ <th> Size
401403
@ <th> User
402404
@ <th> SHA1
405
+ if( g.perm.Admin ){
406
+ @ <th> rcvid
407
+ }
403408
@ </tr></thead>
404409
@ <tbody>
405410
}
406411
if( isDeleted ){
407412
sqlite3_snprintf(sizeof(zSzName), zSzName, "<i>Deleted</i>");
@@ -416,10 +421,17 @@
416421
@ <td> <a href='%R/uv/%T(zName)'>%h(zName)</a> </td>
417422
@ <td data-sortkey='%016llx(-mtime)'> %s(zAge) </td>
418423
@ <td data-sortkey='%08x(fullSize)'> %s(zSzName) </td>
419424
@ <td> %h(zLogin) </td>
420425
@ <td> %h(zHash) </td>
426
+ if( g.perm.Admin ){
427
+ if( rcvid ){
428
+ @ <td> <a href="%R/rcvfrom?rcvid=%d(rcvid)">%d(rcvid)</a>
429
+ }else{
430
+ @ <td>
431
+ }
432
+ }
421433
@ </tr>
422434
fossil_free(zAge);
423435
}
424436
db_finalize(&q);
425437
if( n ){
426438
--- src/unversioned.c
+++ src/unversioned.c
@@ -376,11 +376,12 @@
376 " name,"
377 " mtime,"
378 " hash,"
379 " sz,"
380 " (SELECT login FROM rcvfrom, user"
381 " WHERE user.uid=rcvfrom.uid AND rcvfrom.rcvid=unversioned.rcvid)"
 
382 " FROM unversioned"
383 );
384 iNow = db_int64(0, "SELECT strftime('%%s','now');");
385 while( db_step(&q)==SQLITE_ROW ){
386 const char *zName = db_column_text(&q, 0);
@@ -388,10 +389,11 @@
388 const char *zHash = db_column_text(&q, 2);
389 int isDeleted = zHash==0;
390 int fullSize = db_column_int(&q, 3);
391 char *zAge = human_readable_age((iNow - mtime)/86400.0);
392 const char *zLogin = db_column_text(&q, 4);
 
393 if( zLogin==0 ) zLogin = "";
394 if( (n++)==0 ){
395 @ <div class="uvlist">
396 @ <table cellpadding="2" cellspacing="0" border="1" id="uvtab">
397 @ <thead><tr>
@@ -398,10 +400,13 @@
398 @ <th> Name
399 @ <th> Age
400 @ <th> Size
401 @ <th> User
402 @ <th> SHA1
 
 
 
403 @ </tr></thead>
404 @ <tbody>
405 }
406 if( isDeleted ){
407 sqlite3_snprintf(sizeof(zSzName), zSzName, "<i>Deleted</i>");
@@ -416,10 +421,17 @@
416 @ <td> <a href='%R/uv/%T(zName)'>%h(zName)</a> </td>
417 @ <td data-sortkey='%016llx(-mtime)'> %s(zAge) </td>
418 @ <td data-sortkey='%08x(fullSize)'> %s(zSzName) </td>
419 @ <td> %h(zLogin) </td>
420 @ <td> %h(zHash) </td>
 
 
 
 
 
 
 
421 @ </tr>
422 fossil_free(zAge);
423 }
424 db_finalize(&q);
425 if( n ){
426
--- src/unversioned.c
+++ src/unversioned.c
@@ -376,11 +376,12 @@
376 " name,"
377 " mtime,"
378 " hash,"
379 " sz,"
380 " (SELECT login FROM rcvfrom, user"
381 " WHERE user.uid=rcvfrom.uid AND rcvfrom.rcvid=unversioned.rcvid),"
382 " rcvid"
383 " FROM unversioned"
384 );
385 iNow = db_int64(0, "SELECT strftime('%%s','now');");
386 while( db_step(&q)==SQLITE_ROW ){
387 const char *zName = db_column_text(&q, 0);
@@ -388,10 +389,11 @@
389 const char *zHash = db_column_text(&q, 2);
390 int isDeleted = zHash==0;
391 int fullSize = db_column_int(&q, 3);
392 char *zAge = human_readable_age((iNow - mtime)/86400.0);
393 const char *zLogin = db_column_text(&q, 4);
394 int rcvid = db_column_int(&q,5);
395 if( zLogin==0 ) zLogin = "";
396 if( (n++)==0 ){
397 @ <div class="uvlist">
398 @ <table cellpadding="2" cellspacing="0" border="1" id="uvtab">
399 @ <thead><tr>
@@ -398,10 +400,13 @@
400 @ <th> Name
401 @ <th> Age
402 @ <th> Size
403 @ <th> User
404 @ <th> SHA1
405 if( g.perm.Admin ){
406 @ <th> rcvid
407 }
408 @ </tr></thead>
409 @ <tbody>
410 }
411 if( isDeleted ){
412 sqlite3_snprintf(sizeof(zSzName), zSzName, "<i>Deleted</i>");
@@ -416,10 +421,17 @@
421 @ <td> <a href='%R/uv/%T(zName)'>%h(zName)</a> </td>
422 @ <td data-sortkey='%016llx(-mtime)'> %s(zAge) </td>
423 @ <td data-sortkey='%08x(fullSize)'> %s(zSzName) </td>
424 @ <td> %h(zLogin) </td>
425 @ <td> %h(zHash) </td>
426 if( g.perm.Admin ){
427 if( rcvid ){
428 @ <td> <a href="%R/rcvfrom?rcvid=%d(rcvid)">%d(rcvid)</a>
429 }else{
430 @ <td>
431 }
432 }
433 @ </tr>
434 fossil_free(zAge);
435 }
436 db_finalize(&q);
437 if( n ){
438

Keyboard Shortcuts

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