Fossil SCM
strip BOM from artifacts embedded in HTML or text
Commit
01050d689d21d36124adba3eed63820170078bf7
Parent
ec4c9352235ee6b…
1 file changed
+41
-38
+41
-38
| --- src/info.c | ||
| +++ src/info.c | ||
| @@ -22,12 +22,12 @@ | ||
| 22 | 22 | #include "config.h" |
| 23 | 23 | #include "info.h" |
| 24 | 24 | #include <assert.h> |
| 25 | 25 | |
| 26 | 26 | /* |
| 27 | -** Return a string (in memory obtained from malloc) holding a | |
| 28 | -** comma-separated list of tags that apply to check-in with | |
| 27 | +** Return a string (in memory obtained from malloc) holding a | |
| 28 | +** comma-separated list of tags that apply to check-in with | |
| 29 | 29 | ** record-id rid. If the "propagatingOnly" flag is true, then only |
| 30 | 30 | ** show branch tags (tags that propagate to children). |
| 31 | 31 | ** |
| 32 | 32 | ** Return NULL if there are no such tags. |
| 33 | 33 | */ |
| @@ -62,21 +62,21 @@ | ||
| 62 | 62 | char *zTags; |
| 63 | 63 | char *zDate; |
| 64 | 64 | char *zUuid; |
| 65 | 65 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 66 | 66 | if( zUuid ){ |
| 67 | - zDate = db_text(0, | |
| 67 | + zDate = db_text(0, | |
| 68 | 68 | "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d", |
| 69 | 69 | rid |
| 70 | 70 | ); |
| 71 | 71 | /* 01234567890123 */ |
| 72 | 72 | fossil_print("%-13s %s %s\n", zUuidName, zUuid, zDate ? zDate : ""); |
| 73 | 73 | free(zUuid); |
| 74 | 74 | free(zDate); |
| 75 | 75 | } |
| 76 | 76 | if( zUuid && showComment ){ |
| 77 | - zComment = db_text(0, | |
| 77 | + zComment = db_text(0, | |
| 78 | 78 | "SELECT coalesce(ecomment,comment) || " |
| 79 | 79 | " ' (user: ' || coalesce(euser,user,'?') || ')' " |
| 80 | 80 | " FROM event WHERE objid=%d", |
| 81 | 81 | rid |
| 82 | 82 | ); |
| @@ -86,11 +86,11 @@ | ||
| 86 | 86 | " WHERE cid=%d" |
| 87 | 87 | " ORDER BY isprim DESC, mtime DESC /*sort*/", rid); |
| 88 | 88 | while( db_step(&q)==SQLITE_ROW ){ |
| 89 | 89 | const char *zUuid = db_column_text(&q, 0); |
| 90 | 90 | const char *zType = db_column_int(&q, 2) ? "parent:" : "merged-from:"; |
| 91 | - zDate = db_text("", | |
| 91 | + zDate = db_text("", | |
| 92 | 92 | "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d", |
| 93 | 93 | db_column_int(&q, 1) |
| 94 | 94 | ); |
| 95 | 95 | fossil_print("%-13s %s %s\n", zType, zUuid, zDate); |
| 96 | 96 | free(zDate); |
| @@ -100,11 +100,11 @@ | ||
| 100 | 100 | " WHERE pid=%d" |
| 101 | 101 | " ORDER BY isprim DESC, mtime DESC /*sort*/", rid); |
| 102 | 102 | while( db_step(&q)==SQLITE_ROW ){ |
| 103 | 103 | const char *zUuid = db_column_text(&q, 0); |
| 104 | 104 | const char *zType = db_column_int(&q, 2) ? "child:" : "merged-into:"; |
| 105 | - zDate = db_text("", | |
| 105 | + zDate = db_text("", | |
| 106 | 106 | "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d", |
| 107 | 107 | db_column_int(&q, 1) |
| 108 | 108 | ); |
| 109 | 109 | fossil_print("%-13s %s %s\n", zType, zUuid, zDate); |
| 110 | 110 | free(zDate); |
| @@ -289,11 +289,11 @@ | ||
| 289 | 289 | |
| 290 | 290 | |
| 291 | 291 | /* |
| 292 | 292 | ** Append the difference between two RIDs to the output |
| 293 | 293 | */ |
| 294 | -static void append_diff(const char *zFrom, const char *zTo, u64 diffFlags){ | |
| 294 | +static void append_diff(const char *zFrom, const char *zTo, u64 diffFlags){ | |
| 295 | 295 | int fromid; |
| 296 | 296 | int toid; |
| 297 | 297 | Blob from, to, out; |
| 298 | 298 | if( zFrom ){ |
| 299 | 299 | fromid = uuid_to_rid(zFrom, 0); |
| @@ -319,16 +319,16 @@ | ||
| 319 | 319 | @ %s(blob_str(&out)) |
| 320 | 320 | @ </div> |
| 321 | 321 | } |
| 322 | 322 | blob_reset(&from); |
| 323 | 323 | blob_reset(&to); |
| 324 | - blob_reset(&out); | |
| 324 | + blob_reset(&out); | |
| 325 | 325 | } |
| 326 | 326 | |
| 327 | 327 | |
| 328 | 328 | /* |
| 329 | -** Write a line of web-page output that shows changes that have occurred | |
| 329 | +** Write a line of web-page output that shows changes that have occurred | |
| 330 | 330 | ** to a file between two check-ins. |
| 331 | 331 | */ |
| 332 | 332 | static void append_file_change_line( |
| 333 | 333 | const char *zName, /* Name of the file that has changed */ |
| 334 | 334 | const char *zOld, /* blob.uuid before change. NULL for added files */ |
| @@ -424,11 +424,11 @@ | ||
| 424 | 424 | /* |
| 425 | 425 | ** WEBPAGE: vinfo |
| 426 | 426 | ** WEBPAGE: ci |
| 427 | 427 | ** URL: /ci?name=RID|ARTIFACTID |
| 428 | 428 | ** |
| 429 | -** Display information about a particular check-in. | |
| 429 | +** Display information about a particular check-in. | |
| 430 | 430 | ** |
| 431 | 431 | ** We also jump here from /info if the name is a version. |
| 432 | 432 | ** |
| 433 | 433 | ** If the /ci page is used (instead of /vinfo or /info) then the |
| 434 | 434 | ** default behavior is to show unified diffs of all file changes. |
| @@ -462,11 +462,11 @@ | ||
| 462 | 462 | "SELECT uuid FROM plink, blob" |
| 463 | 463 | " WHERE plink.cid=%d AND blob.rid=plink.pid AND plink.isprim", |
| 464 | 464 | rid |
| 465 | 465 | ); |
| 466 | 466 | isLeaf = is_a_leaf(rid); |
| 467 | - db_prepare(&q, | |
| 467 | + db_prepare(&q, | |
| 468 | 468 | "SELECT uuid, datetime(mtime, 'localtime'), user, comment," |
| 469 | 469 | " datetime(omtime, 'localtime'), mtime" |
| 470 | 470 | " FROM blob, event" |
| 471 | 471 | " WHERE blob.rid=%d" |
| 472 | 472 | " AND event.objid=%d", |
| @@ -482,18 +482,18 @@ | ||
| 482 | 482 | const char *zDate; |
| 483 | 483 | const char *zOrigDate; |
| 484 | 484 | char *zThisBranch; |
| 485 | 485 | double thisMtime; |
| 486 | 486 | int seenDiffTitle = 0; |
| 487 | - | |
| 487 | + | |
| 488 | 488 | style_header(zTitle); |
| 489 | 489 | login_anonymous_available(); |
| 490 | 490 | free(zTitle); |
| 491 | 491 | zEUser = db_text(0, |
| 492 | 492 | "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d", |
| 493 | 493 | TAG_USER, rid); |
| 494 | - zEComment = db_text(0, | |
| 494 | + zEComment = db_text(0, | |
| 495 | 495 | "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d", |
| 496 | 496 | TAG_COMMENT, rid); |
| 497 | 497 | zUser = db_column_text(&q, 2); |
| 498 | 498 | zComment = db_column_text(&q, 3); |
| 499 | 499 | zDate = db_column_text(&q,1); |
| @@ -526,11 +526,11 @@ | ||
| 526 | 526 | @ <tr><th>Original Comment:</th><td>%w(zComment)</td></tr> |
| 527 | 527 | }else{ |
| 528 | 528 | @ <tr><th>Comment:</th><td>%w(zComment)</td></tr> |
| 529 | 529 | } |
| 530 | 530 | if( g.perm.Admin ){ |
| 531 | - db_prepare(&q, | |
| 531 | + db_prepare(&q, | |
| 532 | 532 | "SELECT rcvfrom.ipaddr, user.login, datetime(rcvfrom.mtime)" |
| 533 | 533 | " FROM blob JOIN rcvfrom USING(rcvid) LEFT JOIN user USING(uid)" |
| 534 | 534 | " WHERE blob.rid=%d", |
| 535 | 535 | rid |
| 536 | 536 | ); |
| @@ -730,11 +730,11 @@ | ||
| 730 | 730 | style_header("Wiki Page Information Error"); |
| 731 | 731 | @ No such object: %h(g.argv[2]) |
| 732 | 732 | style_footer(); |
| 733 | 733 | return; |
| 734 | 734 | } |
| 735 | - db_prepare(&q, | |
| 735 | + db_prepare(&q, | |
| 736 | 736 | "SELECT substr(tagname, 6, 1000), uuid," |
| 737 | 737 | " datetime(event.mtime, 'localtime'), user" |
| 738 | 738 | " FROM tagxref, tag, blob, event" |
| 739 | 739 | " WHERE tagxref.rid=%d" |
| 740 | 740 | " AND tag.tagid=tagxref.tagid" |
| @@ -901,11 +901,11 @@ | ||
| 901 | 901 | ** branch=TAG |
| 902 | 902 | ** detail=BOOLEAN |
| 903 | 903 | ** sbs=BOOLEAN |
| 904 | 904 | ** |
| 905 | 905 | ** |
| 906 | -** Show all differences between two checkins. | |
| 906 | +** Show all differences between two checkins. | |
| 907 | 907 | */ |
| 908 | 908 | void vdiff_page(void){ |
| 909 | 909 | int ridFrom, ridTo; |
| 910 | 910 | int showDetail = 0; |
| 911 | 911 | int sideBySide = 0; |
| @@ -966,24 +966,24 @@ | ||
| 966 | 966 | cmp = -1; |
| 967 | 967 | }else{ |
| 968 | 968 | cmp = fossil_strcmp(pFileFrom->zName, pFileTo->zName); |
| 969 | 969 | } |
| 970 | 970 | if( cmp<0 ){ |
| 971 | - append_file_change_line(pFileFrom->zName, | |
| 971 | + append_file_change_line(pFileFrom->zName, | |
| 972 | 972 | pFileFrom->zUuid, 0, 0, diffFlags, 0); |
| 973 | 973 | pFileFrom = manifest_file_next(pFrom, 0); |
| 974 | 974 | }else if( cmp>0 ){ |
| 975 | - append_file_change_line(pFileTo->zName, | |
| 975 | + append_file_change_line(pFileTo->zName, | |
| 976 | 976 | 0, pFileTo->zUuid, 0, diffFlags, |
| 977 | 977 | manifest_file_mperm(pFileTo)); |
| 978 | 978 | pFileTo = manifest_file_next(pTo, 0); |
| 979 | 979 | }else if( fossil_strcmp(pFileFrom->zUuid, pFileTo->zUuid)==0 ){ |
| 980 | 980 | /* No changes */ |
| 981 | 981 | pFileFrom = manifest_file_next(pFrom, 0); |
| 982 | 982 | pFileTo = manifest_file_next(pTo, 0); |
| 983 | 983 | }else{ |
| 984 | - append_file_change_line(pFileFrom->zName, | |
| 984 | + append_file_change_line(pFileFrom->zName, | |
| 985 | 985 | pFileFrom->zUuid, |
| 986 | 986 | pFileTo->zUuid, 0, diffFlags, |
| 987 | 987 | manifest_file_mperm(pFileTo)); |
| 988 | 988 | pFileFrom = manifest_file_next(pFrom, 0); |
| 989 | 989 | pFileTo = manifest_file_next(pTo, 0); |
| @@ -1054,11 +1054,11 @@ | ||
| 1054 | 1054 | if( mPerm==PERM_LNK ){ |
| 1055 | 1055 | @ <li>Symbolic link |
| 1056 | 1056 | }else if( mPerm==PERM_EXE ){ |
| 1057 | 1057 | @ <li>Executable file |
| 1058 | 1058 | }else{ |
| 1059 | - @ <li>File | |
| 1059 | + @ <li>File | |
| 1060 | 1060 | } |
| 1061 | 1061 | @ %z(href("%R/finfo?name=%T",zName))%h(zName)</a> |
| 1062 | 1062 | @ <ul> |
| 1063 | 1063 | prevName = fossil_strdup(zName); |
| 1064 | 1064 | } |
| @@ -1081,16 +1081,16 @@ | ||
| 1081 | 1081 | } |
| 1082 | 1082 | } |
| 1083 | 1083 | @ </ul></ul> |
| 1084 | 1084 | free(prevName); |
| 1085 | 1085 | db_finalize(&q); |
| 1086 | - db_prepare(&q, | |
| 1086 | + db_prepare(&q, | |
| 1087 | 1087 | "SELECT substr(tagname, 6, 10000), datetime(event.mtime)," |
| 1088 | 1088 | " coalesce(event.euser, event.user)" |
| 1089 | 1089 | " FROM tagxref, tag, event" |
| 1090 | 1090 | " WHERE tagxref.rid=%d" |
| 1091 | - " AND tag.tagid=tagxref.tagid" | |
| 1091 | + " AND tag.tagid=tagxref.tagid" | |
| 1092 | 1092 | " AND tag.tagname LIKE 'wiki-%%'" |
| 1093 | 1093 | " AND event.objid=tagxref.rid", |
| 1094 | 1094 | rid |
| 1095 | 1095 | ); |
| 1096 | 1096 | while( db_step(&q)==SQLITE_ROW ){ |
| @@ -1152,11 +1152,11 @@ | ||
| 1152 | 1152 | } |
| 1153 | 1153 | cnt++; |
| 1154 | 1154 | } |
| 1155 | 1155 | db_finalize(&q); |
| 1156 | 1156 | } |
| 1157 | - db_prepare(&q, | |
| 1157 | + db_prepare(&q, | |
| 1158 | 1158 | "SELECT target, filename, datetime(mtime), user, src" |
| 1159 | 1159 | " FROM attachment" |
| 1160 | 1160 | " WHERE src=(SELECT uuid FROM blob WHERE rid=%d)" |
| 1161 | 1161 | " ORDER BY mtime DESC /*sort*/", |
| 1162 | 1162 | rid |
| @@ -1287,11 +1287,11 @@ | ||
| 1287 | 1287 | } |
| 1288 | 1288 | |
| 1289 | 1289 | /* |
| 1290 | 1290 | ** WEBPAGE: raw |
| 1291 | 1291 | ** URL: /raw?name=ARTIFACTID&m=TYPE |
| 1292 | -** | |
| 1292 | +** | |
| 1293 | 1293 | ** Return the uninterpreted content of an artifact. Used primarily |
| 1294 | 1294 | ** to view artifacts that are images. |
| 1295 | 1295 | */ |
| 1296 | 1296 | void rawartifact_page(void){ |
| 1297 | 1297 | int rid; |
| @@ -1373,11 +1373,11 @@ | ||
| 1373 | 1373 | } |
| 1374 | 1374 | |
| 1375 | 1375 | /* |
| 1376 | 1376 | ** WEBPAGE: hexdump |
| 1377 | 1377 | ** URL: /hexdump?name=ARTIFACTID |
| 1378 | -** | |
| 1378 | +** | |
| 1379 | 1379 | ** Show the complete content of a file identified by ARTIFACTID |
| 1380 | 1380 | ** as preformatted text. |
| 1381 | 1381 | */ |
| 1382 | 1382 | void hexdump_page(void){ |
| 1383 | 1383 | int rid; |
| @@ -1402,11 +1402,11 @@ | ||
| 1402 | 1402 | style_header("Hex Artifact Content"); |
| 1403 | 1403 | zUuid = db_text("?","SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1404 | 1404 | @ <h2>Artifact %s(zUuid):</h2> |
| 1405 | 1405 | blob_zero(&downloadName); |
| 1406 | 1406 | object_description(rid, 0, &downloadName); |
| 1407 | - style_submenu_element("Download", "Download", | |
| 1407 | + style_submenu_element("Download", "Download", | |
| 1408 | 1408 | "%s/raw/%T?name=%s", g.zTop, blob_str(&downloadName), zUuid); |
| 1409 | 1409 | @ <hr /> |
| 1410 | 1410 | content_get(rid, &content); |
| 1411 | 1411 | @ <blockquote><pre> |
| 1412 | 1412 | hexdump(&content); |
| @@ -1508,11 +1508,11 @@ | ||
| 1508 | 1508 | ** Additional query parameters: |
| 1509 | 1509 | ** |
| 1510 | 1510 | ** ln - show line numbers |
| 1511 | 1511 | ** ln=N - highlight line number N |
| 1512 | 1512 | ** ln=M-N - highlight lines M through N inclusive |
| 1513 | -** | |
| 1513 | +** | |
| 1514 | 1514 | ** Show the complete content of a file identified by ARTIFACTID |
| 1515 | 1515 | ** as preformatted text. |
| 1516 | 1516 | */ |
| 1517 | 1517 | void artifact_page(void){ |
| 1518 | 1518 | int rid = 0; |
| @@ -1545,11 +1545,11 @@ | ||
| 1545 | 1545 | style_header("Artifact Content"); |
| 1546 | 1546 | zUuid = db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1547 | 1547 | @ <h2>Artifact %s(zUuid)</h2> |
| 1548 | 1548 | blob_zero(&downloadName); |
| 1549 | 1549 | object_description(rid, 0, &downloadName); |
| 1550 | - style_submenu_element("Download", "Download", | |
| 1550 | + style_submenu_element("Download", "Download", | |
| 1551 | 1551 | "%s/raw/%T?name=%s", g.zTop, blob_str(&downloadName), zUuid); |
| 1552 | 1552 | zMime = mimetype_from_name(blob_str(&downloadName)); |
| 1553 | 1553 | if( zMime ){ |
| 1554 | 1554 | if( fossil_strcmp(zMime, "text/html")==0 ){ |
| 1555 | 1555 | if( P("txt") ){ |
| @@ -1575,19 +1575,22 @@ | ||
| 1575 | 1575 | content_get(rid, &content); |
| 1576 | 1576 | if( renderAsWiki ){ |
| 1577 | 1577 | wiki_convert(&content, 0, 0); |
| 1578 | 1578 | }else if( renderAsHtml ){ |
| 1579 | 1579 | @ <div> |
| 1580 | + blob_strip_bom(&content, 0); | |
| 1580 | 1581 | cgi_append_content(blob_buffer(&content), blob_size(&content)); |
| 1581 | 1582 | @ </div> |
| 1582 | 1583 | }else{ |
| 1583 | 1584 | style_submenu_element("Hex","Hex", "%s/hexdump?name=%s", g.zTop, zUuid); |
| 1584 | 1585 | zMime = mimetype_from_content(&content); |
| 1585 | 1586 | @ <blockquote> |
| 1586 | 1587 | if( zMime==0 ){ |
| 1587 | 1588 | const char *zLn = P("ln"); |
| 1588 | - const char *z = blob_str(&content); | |
| 1589 | + const char *z; | |
| 1590 | + blob_strip_bom(&content, 0); | |
| 1591 | + z = blob_str(&content); | |
| 1589 | 1592 | if( zLn ){ |
| 1590 | 1593 | output_text_with_line_numbers(z, zLn); |
| 1591 | 1594 | }else{ |
| 1592 | 1595 | @ <pre> |
| 1593 | 1596 | @ %h(z) |
| @@ -1599,11 +1602,11 @@ | ||
| 1599 | 1602 | @ <i>(file is %d(blob_size(&content)) bytes of binary data)</i> |
| 1600 | 1603 | } |
| 1601 | 1604 | @ </blockquote> |
| 1602 | 1605 | } |
| 1603 | 1606 | style_footer(); |
| 1604 | -} | |
| 1607 | +} | |
| 1605 | 1608 | |
| 1606 | 1609 | /* |
| 1607 | 1610 | ** WEBPAGE: tinfo |
| 1608 | 1611 | ** URL: /tinfo?name=ARTIFACTID |
| 1609 | 1612 | ** |
| @@ -1663,20 +1666,20 @@ | ||
| 1663 | 1666 | /* |
| 1664 | 1667 | ** WEBPAGE: info |
| 1665 | 1668 | ** URL: info/ARTIFACTID |
| 1666 | 1669 | ** |
| 1667 | 1670 | ** The argument is a artifact ID which might be a baseline or a file or |
| 1668 | -** a ticket changes or a wiki edit or something else. | |
| 1671 | +** a ticket changes or a wiki edit or something else. | |
| 1669 | 1672 | ** |
| 1670 | 1673 | ** Figure out what the artifact ID is and jump to it. |
| 1671 | 1674 | */ |
| 1672 | 1675 | void info_page(void){ |
| 1673 | 1676 | const char *zName; |
| 1674 | 1677 | Blob uuid; |
| 1675 | 1678 | int rid; |
| 1676 | 1679 | int rc; |
| 1677 | - | |
| 1680 | + | |
| 1678 | 1681 | zName = P("name"); |
| 1679 | 1682 | if( zName==0 ) fossil_redirect_home(); |
| 1680 | 1683 | if( validate16(zName, strlen(zName)) ){ |
| 1681 | 1684 | if( db_exists("SELECT 1 FROM ticket WHERE tkt_uuid GLOB '%q*'", zName) ){ |
| 1682 | 1685 | tktview_page(); |
| @@ -1769,28 +1772,28 @@ | ||
| 1769 | 1772 | { "#d3a8bc", 0 }, |
| 1770 | 1773 | { "#d3b5a8", 0 }, |
| 1771 | 1774 | { "#d1d3a8", 0 }, |
| 1772 | 1775 | { "#b1d3a8", 0 }, |
| 1773 | 1776 | |
| 1774 | - { "#8eb2a1", 0 }, | |
| 1777 | + { "#8eb2a1", 0 }, | |
| 1775 | 1778 | { "#8ea7b2", 0 }, |
| 1776 | 1779 | { "#8f8eb2", 0 }, |
| 1777 | 1780 | { "#ab8eb2", 0 }, |
| 1778 | 1781 | { "#b28e9e", 0 }, |
| 1779 | 1782 | { "#b2988e", 0 }, |
| 1780 | 1783 | { "#b0b28e", 0 }, |
| 1781 | 1784 | { "#95b28e", 0 }, |
| 1782 | 1785 | |
| 1783 | - { "#80d6b0", 0 }, | |
| 1786 | + { "#80d6b0", 0 }, | |
| 1784 | 1787 | { "#80bbd6", 0 }, |
| 1785 | 1788 | { "#8680d6", 0 }, |
| 1786 | 1789 | { "#c680d6", 0 }, |
| 1787 | 1790 | { "#d680a6", 0 }, |
| 1788 | 1791 | { "#d69b80", 0 }, |
| 1789 | 1792 | { "#d1d680", 0 }, |
| 1790 | 1793 | { "#91d680", 0 }, |
| 1791 | - | |
| 1794 | + | |
| 1792 | 1795 | |
| 1793 | 1796 | { "custom", "##" }, |
| 1794 | 1797 | }; |
| 1795 | 1798 | int nColor = sizeof(aColor)/sizeof(aColor[0])-1; |
| 1796 | 1799 | int stdClrFound = 0; |
| @@ -1893,11 +1896,11 @@ | ||
| 1893 | 1896 | const char *zNewComment; /* Revised check-in comment */ |
| 1894 | 1897 | const char *zUser; /* Current user for the check-in */ |
| 1895 | 1898 | const char *zNewUser; /* Revised user */ |
| 1896 | 1899 | const char *zDate; /* Current date of the check-in */ |
| 1897 | 1900 | const char *zNewDate; /* Revised check-in date */ |
| 1898 | - const char *zColor; | |
| 1901 | + const char *zColor; | |
| 1899 | 1902 | const char *zNewColor; |
| 1900 | 1903 | const char *zNewTagFlag; |
| 1901 | 1904 | const char *zNewTag; |
| 1902 | 1905 | const char *zNewBrFlag; |
| 1903 | 1906 | const char *zNewBranch; |
| @@ -1906,11 +1909,11 @@ | ||
| 1906 | 1909 | int fNewPropagateColor; /* True if color propagates after edit */ |
| 1907 | 1910 | const char *zChngTime = 0; /* Value of chngtime= query param, if any */ |
| 1908 | 1911 | char *zUuid; |
| 1909 | 1912 | Blob comment; |
| 1910 | 1913 | Stmt q; |
| 1911 | - | |
| 1914 | + | |
| 1912 | 1915 | login_check_credentials(); |
| 1913 | 1916 | if( !g.perm.Write ){ login_needed(); return; } |
| 1914 | 1917 | rid = name_to_typed_rid(P("r"), "ci"); |
| 1915 | 1918 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1916 | 1919 | zComment = db_text(0, "SELECT coalesce(ecomment,comment)" |
| @@ -1953,11 +1956,11 @@ | ||
| 1953 | 1956 | blob_zero(&ctrl); |
| 1954 | 1957 | zNow = date_in_standard_format(zChngTime ? zChngTime : "now"); |
| 1955 | 1958 | blob_appendf(&ctrl, "D %s\n", zNow); |
| 1956 | 1959 | db_multi_exec("CREATE TEMP TABLE newtags(tag UNIQUE, prefix, value)"); |
| 1957 | 1960 | if( zNewColor[0] |
| 1958 | - && (fPropagateColor!=fNewPropagateColor | |
| 1961 | + && (fPropagateColor!=fNewPropagateColor | |
| 1959 | 1962 | || fossil_strcmp(zColor,zNewColor)!=0) |
| 1960 | 1963 | ){ |
| 1961 | 1964 | char *zPrefix = "+"; |
| 1962 | 1965 | if( fNewPropagateColor ){ |
| 1963 | 1966 | zPrefix = "*"; |
| 1964 | 1967 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -22,12 +22,12 @@ | |
| 22 | #include "config.h" |
| 23 | #include "info.h" |
| 24 | #include <assert.h> |
| 25 | |
| 26 | /* |
| 27 | ** Return a string (in memory obtained from malloc) holding a |
| 28 | ** comma-separated list of tags that apply to check-in with |
| 29 | ** record-id rid. If the "propagatingOnly" flag is true, then only |
| 30 | ** show branch tags (tags that propagate to children). |
| 31 | ** |
| 32 | ** Return NULL if there are no such tags. |
| 33 | */ |
| @@ -62,21 +62,21 @@ | |
| 62 | char *zTags; |
| 63 | char *zDate; |
| 64 | char *zUuid; |
| 65 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 66 | if( zUuid ){ |
| 67 | zDate = db_text(0, |
| 68 | "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d", |
| 69 | rid |
| 70 | ); |
| 71 | /* 01234567890123 */ |
| 72 | fossil_print("%-13s %s %s\n", zUuidName, zUuid, zDate ? zDate : ""); |
| 73 | free(zUuid); |
| 74 | free(zDate); |
| 75 | } |
| 76 | if( zUuid && showComment ){ |
| 77 | zComment = db_text(0, |
| 78 | "SELECT coalesce(ecomment,comment) || " |
| 79 | " ' (user: ' || coalesce(euser,user,'?') || ')' " |
| 80 | " FROM event WHERE objid=%d", |
| 81 | rid |
| 82 | ); |
| @@ -86,11 +86,11 @@ | |
| 86 | " WHERE cid=%d" |
| 87 | " ORDER BY isprim DESC, mtime DESC /*sort*/", rid); |
| 88 | while( db_step(&q)==SQLITE_ROW ){ |
| 89 | const char *zUuid = db_column_text(&q, 0); |
| 90 | const char *zType = db_column_int(&q, 2) ? "parent:" : "merged-from:"; |
| 91 | zDate = db_text("", |
| 92 | "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d", |
| 93 | db_column_int(&q, 1) |
| 94 | ); |
| 95 | fossil_print("%-13s %s %s\n", zType, zUuid, zDate); |
| 96 | free(zDate); |
| @@ -100,11 +100,11 @@ | |
| 100 | " WHERE pid=%d" |
| 101 | " ORDER BY isprim DESC, mtime DESC /*sort*/", rid); |
| 102 | while( db_step(&q)==SQLITE_ROW ){ |
| 103 | const char *zUuid = db_column_text(&q, 0); |
| 104 | const char *zType = db_column_int(&q, 2) ? "child:" : "merged-into:"; |
| 105 | zDate = db_text("", |
| 106 | "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d", |
| 107 | db_column_int(&q, 1) |
| 108 | ); |
| 109 | fossil_print("%-13s %s %s\n", zType, zUuid, zDate); |
| 110 | free(zDate); |
| @@ -289,11 +289,11 @@ | |
| 289 | |
| 290 | |
| 291 | /* |
| 292 | ** Append the difference between two RIDs to the output |
| 293 | */ |
| 294 | static void append_diff(const char *zFrom, const char *zTo, u64 diffFlags){ |
| 295 | int fromid; |
| 296 | int toid; |
| 297 | Blob from, to, out; |
| 298 | if( zFrom ){ |
| 299 | fromid = uuid_to_rid(zFrom, 0); |
| @@ -319,16 +319,16 @@ | |
| 319 | @ %s(blob_str(&out)) |
| 320 | @ </div> |
| 321 | } |
| 322 | blob_reset(&from); |
| 323 | blob_reset(&to); |
| 324 | blob_reset(&out); |
| 325 | } |
| 326 | |
| 327 | |
| 328 | /* |
| 329 | ** Write a line of web-page output that shows changes that have occurred |
| 330 | ** to a file between two check-ins. |
| 331 | */ |
| 332 | static void append_file_change_line( |
| 333 | const char *zName, /* Name of the file that has changed */ |
| 334 | const char *zOld, /* blob.uuid before change. NULL for added files */ |
| @@ -424,11 +424,11 @@ | |
| 424 | /* |
| 425 | ** WEBPAGE: vinfo |
| 426 | ** WEBPAGE: ci |
| 427 | ** URL: /ci?name=RID|ARTIFACTID |
| 428 | ** |
| 429 | ** Display information about a particular check-in. |
| 430 | ** |
| 431 | ** We also jump here from /info if the name is a version. |
| 432 | ** |
| 433 | ** If the /ci page is used (instead of /vinfo or /info) then the |
| 434 | ** default behavior is to show unified diffs of all file changes. |
| @@ -462,11 +462,11 @@ | |
| 462 | "SELECT uuid FROM plink, blob" |
| 463 | " WHERE plink.cid=%d AND blob.rid=plink.pid AND plink.isprim", |
| 464 | rid |
| 465 | ); |
| 466 | isLeaf = is_a_leaf(rid); |
| 467 | db_prepare(&q, |
| 468 | "SELECT uuid, datetime(mtime, 'localtime'), user, comment," |
| 469 | " datetime(omtime, 'localtime'), mtime" |
| 470 | " FROM blob, event" |
| 471 | " WHERE blob.rid=%d" |
| 472 | " AND event.objid=%d", |
| @@ -482,18 +482,18 @@ | |
| 482 | const char *zDate; |
| 483 | const char *zOrigDate; |
| 484 | char *zThisBranch; |
| 485 | double thisMtime; |
| 486 | int seenDiffTitle = 0; |
| 487 | |
| 488 | style_header(zTitle); |
| 489 | login_anonymous_available(); |
| 490 | free(zTitle); |
| 491 | zEUser = db_text(0, |
| 492 | "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d", |
| 493 | TAG_USER, rid); |
| 494 | zEComment = db_text(0, |
| 495 | "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d", |
| 496 | TAG_COMMENT, rid); |
| 497 | zUser = db_column_text(&q, 2); |
| 498 | zComment = db_column_text(&q, 3); |
| 499 | zDate = db_column_text(&q,1); |
| @@ -526,11 +526,11 @@ | |
| 526 | @ <tr><th>Original Comment:</th><td>%w(zComment)</td></tr> |
| 527 | }else{ |
| 528 | @ <tr><th>Comment:</th><td>%w(zComment)</td></tr> |
| 529 | } |
| 530 | if( g.perm.Admin ){ |
| 531 | db_prepare(&q, |
| 532 | "SELECT rcvfrom.ipaddr, user.login, datetime(rcvfrom.mtime)" |
| 533 | " FROM blob JOIN rcvfrom USING(rcvid) LEFT JOIN user USING(uid)" |
| 534 | " WHERE blob.rid=%d", |
| 535 | rid |
| 536 | ); |
| @@ -730,11 +730,11 @@ | |
| 730 | style_header("Wiki Page Information Error"); |
| 731 | @ No such object: %h(g.argv[2]) |
| 732 | style_footer(); |
| 733 | return; |
| 734 | } |
| 735 | db_prepare(&q, |
| 736 | "SELECT substr(tagname, 6, 1000), uuid," |
| 737 | " datetime(event.mtime, 'localtime'), user" |
| 738 | " FROM tagxref, tag, blob, event" |
| 739 | " WHERE tagxref.rid=%d" |
| 740 | " AND tag.tagid=tagxref.tagid" |
| @@ -901,11 +901,11 @@ | |
| 901 | ** branch=TAG |
| 902 | ** detail=BOOLEAN |
| 903 | ** sbs=BOOLEAN |
| 904 | ** |
| 905 | ** |
| 906 | ** Show all differences between two checkins. |
| 907 | */ |
| 908 | void vdiff_page(void){ |
| 909 | int ridFrom, ridTo; |
| 910 | int showDetail = 0; |
| 911 | int sideBySide = 0; |
| @@ -966,24 +966,24 @@ | |
| 966 | cmp = -1; |
| 967 | }else{ |
| 968 | cmp = fossil_strcmp(pFileFrom->zName, pFileTo->zName); |
| 969 | } |
| 970 | if( cmp<0 ){ |
| 971 | append_file_change_line(pFileFrom->zName, |
| 972 | pFileFrom->zUuid, 0, 0, diffFlags, 0); |
| 973 | pFileFrom = manifest_file_next(pFrom, 0); |
| 974 | }else if( cmp>0 ){ |
| 975 | append_file_change_line(pFileTo->zName, |
| 976 | 0, pFileTo->zUuid, 0, diffFlags, |
| 977 | manifest_file_mperm(pFileTo)); |
| 978 | pFileTo = manifest_file_next(pTo, 0); |
| 979 | }else if( fossil_strcmp(pFileFrom->zUuid, pFileTo->zUuid)==0 ){ |
| 980 | /* No changes */ |
| 981 | pFileFrom = manifest_file_next(pFrom, 0); |
| 982 | pFileTo = manifest_file_next(pTo, 0); |
| 983 | }else{ |
| 984 | append_file_change_line(pFileFrom->zName, |
| 985 | pFileFrom->zUuid, |
| 986 | pFileTo->zUuid, 0, diffFlags, |
| 987 | manifest_file_mperm(pFileTo)); |
| 988 | pFileFrom = manifest_file_next(pFrom, 0); |
| 989 | pFileTo = manifest_file_next(pTo, 0); |
| @@ -1054,11 +1054,11 @@ | |
| 1054 | if( mPerm==PERM_LNK ){ |
| 1055 | @ <li>Symbolic link |
| 1056 | }else if( mPerm==PERM_EXE ){ |
| 1057 | @ <li>Executable file |
| 1058 | }else{ |
| 1059 | @ <li>File |
| 1060 | } |
| 1061 | @ %z(href("%R/finfo?name=%T",zName))%h(zName)</a> |
| 1062 | @ <ul> |
| 1063 | prevName = fossil_strdup(zName); |
| 1064 | } |
| @@ -1081,16 +1081,16 @@ | |
| 1081 | } |
| 1082 | } |
| 1083 | @ </ul></ul> |
| 1084 | free(prevName); |
| 1085 | db_finalize(&q); |
| 1086 | db_prepare(&q, |
| 1087 | "SELECT substr(tagname, 6, 10000), datetime(event.mtime)," |
| 1088 | " coalesce(event.euser, event.user)" |
| 1089 | " FROM tagxref, tag, event" |
| 1090 | " WHERE tagxref.rid=%d" |
| 1091 | " AND tag.tagid=tagxref.tagid" |
| 1092 | " AND tag.tagname LIKE 'wiki-%%'" |
| 1093 | " AND event.objid=tagxref.rid", |
| 1094 | rid |
| 1095 | ); |
| 1096 | while( db_step(&q)==SQLITE_ROW ){ |
| @@ -1152,11 +1152,11 @@ | |
| 1152 | } |
| 1153 | cnt++; |
| 1154 | } |
| 1155 | db_finalize(&q); |
| 1156 | } |
| 1157 | db_prepare(&q, |
| 1158 | "SELECT target, filename, datetime(mtime), user, src" |
| 1159 | " FROM attachment" |
| 1160 | " WHERE src=(SELECT uuid FROM blob WHERE rid=%d)" |
| 1161 | " ORDER BY mtime DESC /*sort*/", |
| 1162 | rid |
| @@ -1287,11 +1287,11 @@ | |
| 1287 | } |
| 1288 | |
| 1289 | /* |
| 1290 | ** WEBPAGE: raw |
| 1291 | ** URL: /raw?name=ARTIFACTID&m=TYPE |
| 1292 | ** |
| 1293 | ** Return the uninterpreted content of an artifact. Used primarily |
| 1294 | ** to view artifacts that are images. |
| 1295 | */ |
| 1296 | void rawartifact_page(void){ |
| 1297 | int rid; |
| @@ -1373,11 +1373,11 @@ | |
| 1373 | } |
| 1374 | |
| 1375 | /* |
| 1376 | ** WEBPAGE: hexdump |
| 1377 | ** URL: /hexdump?name=ARTIFACTID |
| 1378 | ** |
| 1379 | ** Show the complete content of a file identified by ARTIFACTID |
| 1380 | ** as preformatted text. |
| 1381 | */ |
| 1382 | void hexdump_page(void){ |
| 1383 | int rid; |
| @@ -1402,11 +1402,11 @@ | |
| 1402 | style_header("Hex Artifact Content"); |
| 1403 | zUuid = db_text("?","SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1404 | @ <h2>Artifact %s(zUuid):</h2> |
| 1405 | blob_zero(&downloadName); |
| 1406 | object_description(rid, 0, &downloadName); |
| 1407 | style_submenu_element("Download", "Download", |
| 1408 | "%s/raw/%T?name=%s", g.zTop, blob_str(&downloadName), zUuid); |
| 1409 | @ <hr /> |
| 1410 | content_get(rid, &content); |
| 1411 | @ <blockquote><pre> |
| 1412 | hexdump(&content); |
| @@ -1508,11 +1508,11 @@ | |
| 1508 | ** Additional query parameters: |
| 1509 | ** |
| 1510 | ** ln - show line numbers |
| 1511 | ** ln=N - highlight line number N |
| 1512 | ** ln=M-N - highlight lines M through N inclusive |
| 1513 | ** |
| 1514 | ** Show the complete content of a file identified by ARTIFACTID |
| 1515 | ** as preformatted text. |
| 1516 | */ |
| 1517 | void artifact_page(void){ |
| 1518 | int rid = 0; |
| @@ -1545,11 +1545,11 @@ | |
| 1545 | style_header("Artifact Content"); |
| 1546 | zUuid = db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1547 | @ <h2>Artifact %s(zUuid)</h2> |
| 1548 | blob_zero(&downloadName); |
| 1549 | object_description(rid, 0, &downloadName); |
| 1550 | style_submenu_element("Download", "Download", |
| 1551 | "%s/raw/%T?name=%s", g.zTop, blob_str(&downloadName), zUuid); |
| 1552 | zMime = mimetype_from_name(blob_str(&downloadName)); |
| 1553 | if( zMime ){ |
| 1554 | if( fossil_strcmp(zMime, "text/html")==0 ){ |
| 1555 | if( P("txt") ){ |
| @@ -1575,19 +1575,22 @@ | |
| 1575 | content_get(rid, &content); |
| 1576 | if( renderAsWiki ){ |
| 1577 | wiki_convert(&content, 0, 0); |
| 1578 | }else if( renderAsHtml ){ |
| 1579 | @ <div> |
| 1580 | cgi_append_content(blob_buffer(&content), blob_size(&content)); |
| 1581 | @ </div> |
| 1582 | }else{ |
| 1583 | style_submenu_element("Hex","Hex", "%s/hexdump?name=%s", g.zTop, zUuid); |
| 1584 | zMime = mimetype_from_content(&content); |
| 1585 | @ <blockquote> |
| 1586 | if( zMime==0 ){ |
| 1587 | const char *zLn = P("ln"); |
| 1588 | const char *z = blob_str(&content); |
| 1589 | if( zLn ){ |
| 1590 | output_text_with_line_numbers(z, zLn); |
| 1591 | }else{ |
| 1592 | @ <pre> |
| 1593 | @ %h(z) |
| @@ -1599,11 +1602,11 @@ | |
| 1599 | @ <i>(file is %d(blob_size(&content)) bytes of binary data)</i> |
| 1600 | } |
| 1601 | @ </blockquote> |
| 1602 | } |
| 1603 | style_footer(); |
| 1604 | } |
| 1605 | |
| 1606 | /* |
| 1607 | ** WEBPAGE: tinfo |
| 1608 | ** URL: /tinfo?name=ARTIFACTID |
| 1609 | ** |
| @@ -1663,20 +1666,20 @@ | |
| 1663 | /* |
| 1664 | ** WEBPAGE: info |
| 1665 | ** URL: info/ARTIFACTID |
| 1666 | ** |
| 1667 | ** The argument is a artifact ID which might be a baseline or a file or |
| 1668 | ** a ticket changes or a wiki edit or something else. |
| 1669 | ** |
| 1670 | ** Figure out what the artifact ID is and jump to it. |
| 1671 | */ |
| 1672 | void info_page(void){ |
| 1673 | const char *zName; |
| 1674 | Blob uuid; |
| 1675 | int rid; |
| 1676 | int rc; |
| 1677 | |
| 1678 | zName = P("name"); |
| 1679 | if( zName==0 ) fossil_redirect_home(); |
| 1680 | if( validate16(zName, strlen(zName)) ){ |
| 1681 | if( db_exists("SELECT 1 FROM ticket WHERE tkt_uuid GLOB '%q*'", zName) ){ |
| 1682 | tktview_page(); |
| @@ -1769,28 +1772,28 @@ | |
| 1769 | { "#d3a8bc", 0 }, |
| 1770 | { "#d3b5a8", 0 }, |
| 1771 | { "#d1d3a8", 0 }, |
| 1772 | { "#b1d3a8", 0 }, |
| 1773 | |
| 1774 | { "#8eb2a1", 0 }, |
| 1775 | { "#8ea7b2", 0 }, |
| 1776 | { "#8f8eb2", 0 }, |
| 1777 | { "#ab8eb2", 0 }, |
| 1778 | { "#b28e9e", 0 }, |
| 1779 | { "#b2988e", 0 }, |
| 1780 | { "#b0b28e", 0 }, |
| 1781 | { "#95b28e", 0 }, |
| 1782 | |
| 1783 | { "#80d6b0", 0 }, |
| 1784 | { "#80bbd6", 0 }, |
| 1785 | { "#8680d6", 0 }, |
| 1786 | { "#c680d6", 0 }, |
| 1787 | { "#d680a6", 0 }, |
| 1788 | { "#d69b80", 0 }, |
| 1789 | { "#d1d680", 0 }, |
| 1790 | { "#91d680", 0 }, |
| 1791 | |
| 1792 | |
| 1793 | { "custom", "##" }, |
| 1794 | }; |
| 1795 | int nColor = sizeof(aColor)/sizeof(aColor[0])-1; |
| 1796 | int stdClrFound = 0; |
| @@ -1893,11 +1896,11 @@ | |
| 1893 | const char *zNewComment; /* Revised check-in comment */ |
| 1894 | const char *zUser; /* Current user for the check-in */ |
| 1895 | const char *zNewUser; /* Revised user */ |
| 1896 | const char *zDate; /* Current date of the check-in */ |
| 1897 | const char *zNewDate; /* Revised check-in date */ |
| 1898 | const char *zColor; |
| 1899 | const char *zNewColor; |
| 1900 | const char *zNewTagFlag; |
| 1901 | const char *zNewTag; |
| 1902 | const char *zNewBrFlag; |
| 1903 | const char *zNewBranch; |
| @@ -1906,11 +1909,11 @@ | |
| 1906 | int fNewPropagateColor; /* True if color propagates after edit */ |
| 1907 | const char *zChngTime = 0; /* Value of chngtime= query param, if any */ |
| 1908 | char *zUuid; |
| 1909 | Blob comment; |
| 1910 | Stmt q; |
| 1911 | |
| 1912 | login_check_credentials(); |
| 1913 | if( !g.perm.Write ){ login_needed(); return; } |
| 1914 | rid = name_to_typed_rid(P("r"), "ci"); |
| 1915 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1916 | zComment = db_text(0, "SELECT coalesce(ecomment,comment)" |
| @@ -1953,11 +1956,11 @@ | |
| 1953 | blob_zero(&ctrl); |
| 1954 | zNow = date_in_standard_format(zChngTime ? zChngTime : "now"); |
| 1955 | blob_appendf(&ctrl, "D %s\n", zNow); |
| 1956 | db_multi_exec("CREATE TEMP TABLE newtags(tag UNIQUE, prefix, value)"); |
| 1957 | if( zNewColor[0] |
| 1958 | && (fPropagateColor!=fNewPropagateColor |
| 1959 | || fossil_strcmp(zColor,zNewColor)!=0) |
| 1960 | ){ |
| 1961 | char *zPrefix = "+"; |
| 1962 | if( fNewPropagateColor ){ |
| 1963 | zPrefix = "*"; |
| 1964 |
| --- src/info.c | |
| +++ src/info.c | |
| @@ -22,12 +22,12 @@ | |
| 22 | #include "config.h" |
| 23 | #include "info.h" |
| 24 | #include <assert.h> |
| 25 | |
| 26 | /* |
| 27 | ** Return a string (in memory obtained from malloc) holding a |
| 28 | ** comma-separated list of tags that apply to check-in with |
| 29 | ** record-id rid. If the "propagatingOnly" flag is true, then only |
| 30 | ** show branch tags (tags that propagate to children). |
| 31 | ** |
| 32 | ** Return NULL if there are no such tags. |
| 33 | */ |
| @@ -62,21 +62,21 @@ | |
| 62 | char *zTags; |
| 63 | char *zDate; |
| 64 | char *zUuid; |
| 65 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 66 | if( zUuid ){ |
| 67 | zDate = db_text(0, |
| 68 | "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d", |
| 69 | rid |
| 70 | ); |
| 71 | /* 01234567890123 */ |
| 72 | fossil_print("%-13s %s %s\n", zUuidName, zUuid, zDate ? zDate : ""); |
| 73 | free(zUuid); |
| 74 | free(zDate); |
| 75 | } |
| 76 | if( zUuid && showComment ){ |
| 77 | zComment = db_text(0, |
| 78 | "SELECT coalesce(ecomment,comment) || " |
| 79 | " ' (user: ' || coalesce(euser,user,'?') || ')' " |
| 80 | " FROM event WHERE objid=%d", |
| 81 | rid |
| 82 | ); |
| @@ -86,11 +86,11 @@ | |
| 86 | " WHERE cid=%d" |
| 87 | " ORDER BY isprim DESC, mtime DESC /*sort*/", rid); |
| 88 | while( db_step(&q)==SQLITE_ROW ){ |
| 89 | const char *zUuid = db_column_text(&q, 0); |
| 90 | const char *zType = db_column_int(&q, 2) ? "parent:" : "merged-from:"; |
| 91 | zDate = db_text("", |
| 92 | "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d", |
| 93 | db_column_int(&q, 1) |
| 94 | ); |
| 95 | fossil_print("%-13s %s %s\n", zType, zUuid, zDate); |
| 96 | free(zDate); |
| @@ -100,11 +100,11 @@ | |
| 100 | " WHERE pid=%d" |
| 101 | " ORDER BY isprim DESC, mtime DESC /*sort*/", rid); |
| 102 | while( db_step(&q)==SQLITE_ROW ){ |
| 103 | const char *zUuid = db_column_text(&q, 0); |
| 104 | const char *zType = db_column_int(&q, 2) ? "child:" : "merged-into:"; |
| 105 | zDate = db_text("", |
| 106 | "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d", |
| 107 | db_column_int(&q, 1) |
| 108 | ); |
| 109 | fossil_print("%-13s %s %s\n", zType, zUuid, zDate); |
| 110 | free(zDate); |
| @@ -289,11 +289,11 @@ | |
| 289 | |
| 290 | |
| 291 | /* |
| 292 | ** Append the difference between two RIDs to the output |
| 293 | */ |
| 294 | static void append_diff(const char *zFrom, const char *zTo, u64 diffFlags){ |
| 295 | int fromid; |
| 296 | int toid; |
| 297 | Blob from, to, out; |
| 298 | if( zFrom ){ |
| 299 | fromid = uuid_to_rid(zFrom, 0); |
| @@ -319,16 +319,16 @@ | |
| 319 | @ %s(blob_str(&out)) |
| 320 | @ </div> |
| 321 | } |
| 322 | blob_reset(&from); |
| 323 | blob_reset(&to); |
| 324 | blob_reset(&out); |
| 325 | } |
| 326 | |
| 327 | |
| 328 | /* |
| 329 | ** Write a line of web-page output that shows changes that have occurred |
| 330 | ** to a file between two check-ins. |
| 331 | */ |
| 332 | static void append_file_change_line( |
| 333 | const char *zName, /* Name of the file that has changed */ |
| 334 | const char *zOld, /* blob.uuid before change. NULL for added files */ |
| @@ -424,11 +424,11 @@ | |
| 424 | /* |
| 425 | ** WEBPAGE: vinfo |
| 426 | ** WEBPAGE: ci |
| 427 | ** URL: /ci?name=RID|ARTIFACTID |
| 428 | ** |
| 429 | ** Display information about a particular check-in. |
| 430 | ** |
| 431 | ** We also jump here from /info if the name is a version. |
| 432 | ** |
| 433 | ** If the /ci page is used (instead of /vinfo or /info) then the |
| 434 | ** default behavior is to show unified diffs of all file changes. |
| @@ -462,11 +462,11 @@ | |
| 462 | "SELECT uuid FROM plink, blob" |
| 463 | " WHERE plink.cid=%d AND blob.rid=plink.pid AND plink.isprim", |
| 464 | rid |
| 465 | ); |
| 466 | isLeaf = is_a_leaf(rid); |
| 467 | db_prepare(&q, |
| 468 | "SELECT uuid, datetime(mtime, 'localtime'), user, comment," |
| 469 | " datetime(omtime, 'localtime'), mtime" |
| 470 | " FROM blob, event" |
| 471 | " WHERE blob.rid=%d" |
| 472 | " AND event.objid=%d", |
| @@ -482,18 +482,18 @@ | |
| 482 | const char *zDate; |
| 483 | const char *zOrigDate; |
| 484 | char *zThisBranch; |
| 485 | double thisMtime; |
| 486 | int seenDiffTitle = 0; |
| 487 | |
| 488 | style_header(zTitle); |
| 489 | login_anonymous_available(); |
| 490 | free(zTitle); |
| 491 | zEUser = db_text(0, |
| 492 | "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d", |
| 493 | TAG_USER, rid); |
| 494 | zEComment = db_text(0, |
| 495 | "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d", |
| 496 | TAG_COMMENT, rid); |
| 497 | zUser = db_column_text(&q, 2); |
| 498 | zComment = db_column_text(&q, 3); |
| 499 | zDate = db_column_text(&q,1); |
| @@ -526,11 +526,11 @@ | |
| 526 | @ <tr><th>Original Comment:</th><td>%w(zComment)</td></tr> |
| 527 | }else{ |
| 528 | @ <tr><th>Comment:</th><td>%w(zComment)</td></tr> |
| 529 | } |
| 530 | if( g.perm.Admin ){ |
| 531 | db_prepare(&q, |
| 532 | "SELECT rcvfrom.ipaddr, user.login, datetime(rcvfrom.mtime)" |
| 533 | " FROM blob JOIN rcvfrom USING(rcvid) LEFT JOIN user USING(uid)" |
| 534 | " WHERE blob.rid=%d", |
| 535 | rid |
| 536 | ); |
| @@ -730,11 +730,11 @@ | |
| 730 | style_header("Wiki Page Information Error"); |
| 731 | @ No such object: %h(g.argv[2]) |
| 732 | style_footer(); |
| 733 | return; |
| 734 | } |
| 735 | db_prepare(&q, |
| 736 | "SELECT substr(tagname, 6, 1000), uuid," |
| 737 | " datetime(event.mtime, 'localtime'), user" |
| 738 | " FROM tagxref, tag, blob, event" |
| 739 | " WHERE tagxref.rid=%d" |
| 740 | " AND tag.tagid=tagxref.tagid" |
| @@ -901,11 +901,11 @@ | |
| 901 | ** branch=TAG |
| 902 | ** detail=BOOLEAN |
| 903 | ** sbs=BOOLEAN |
| 904 | ** |
| 905 | ** |
| 906 | ** Show all differences between two checkins. |
| 907 | */ |
| 908 | void vdiff_page(void){ |
| 909 | int ridFrom, ridTo; |
| 910 | int showDetail = 0; |
| 911 | int sideBySide = 0; |
| @@ -966,24 +966,24 @@ | |
| 966 | cmp = -1; |
| 967 | }else{ |
| 968 | cmp = fossil_strcmp(pFileFrom->zName, pFileTo->zName); |
| 969 | } |
| 970 | if( cmp<0 ){ |
| 971 | append_file_change_line(pFileFrom->zName, |
| 972 | pFileFrom->zUuid, 0, 0, diffFlags, 0); |
| 973 | pFileFrom = manifest_file_next(pFrom, 0); |
| 974 | }else if( cmp>0 ){ |
| 975 | append_file_change_line(pFileTo->zName, |
| 976 | 0, pFileTo->zUuid, 0, diffFlags, |
| 977 | manifest_file_mperm(pFileTo)); |
| 978 | pFileTo = manifest_file_next(pTo, 0); |
| 979 | }else if( fossil_strcmp(pFileFrom->zUuid, pFileTo->zUuid)==0 ){ |
| 980 | /* No changes */ |
| 981 | pFileFrom = manifest_file_next(pFrom, 0); |
| 982 | pFileTo = manifest_file_next(pTo, 0); |
| 983 | }else{ |
| 984 | append_file_change_line(pFileFrom->zName, |
| 985 | pFileFrom->zUuid, |
| 986 | pFileTo->zUuid, 0, diffFlags, |
| 987 | manifest_file_mperm(pFileTo)); |
| 988 | pFileFrom = manifest_file_next(pFrom, 0); |
| 989 | pFileTo = manifest_file_next(pTo, 0); |
| @@ -1054,11 +1054,11 @@ | |
| 1054 | if( mPerm==PERM_LNK ){ |
| 1055 | @ <li>Symbolic link |
| 1056 | }else if( mPerm==PERM_EXE ){ |
| 1057 | @ <li>Executable file |
| 1058 | }else{ |
| 1059 | @ <li>File |
| 1060 | } |
| 1061 | @ %z(href("%R/finfo?name=%T",zName))%h(zName)</a> |
| 1062 | @ <ul> |
| 1063 | prevName = fossil_strdup(zName); |
| 1064 | } |
| @@ -1081,16 +1081,16 @@ | |
| 1081 | } |
| 1082 | } |
| 1083 | @ </ul></ul> |
| 1084 | free(prevName); |
| 1085 | db_finalize(&q); |
| 1086 | db_prepare(&q, |
| 1087 | "SELECT substr(tagname, 6, 10000), datetime(event.mtime)," |
| 1088 | " coalesce(event.euser, event.user)" |
| 1089 | " FROM tagxref, tag, event" |
| 1090 | " WHERE tagxref.rid=%d" |
| 1091 | " AND tag.tagid=tagxref.tagid" |
| 1092 | " AND tag.tagname LIKE 'wiki-%%'" |
| 1093 | " AND event.objid=tagxref.rid", |
| 1094 | rid |
| 1095 | ); |
| 1096 | while( db_step(&q)==SQLITE_ROW ){ |
| @@ -1152,11 +1152,11 @@ | |
| 1152 | } |
| 1153 | cnt++; |
| 1154 | } |
| 1155 | db_finalize(&q); |
| 1156 | } |
| 1157 | db_prepare(&q, |
| 1158 | "SELECT target, filename, datetime(mtime), user, src" |
| 1159 | " FROM attachment" |
| 1160 | " WHERE src=(SELECT uuid FROM blob WHERE rid=%d)" |
| 1161 | " ORDER BY mtime DESC /*sort*/", |
| 1162 | rid |
| @@ -1287,11 +1287,11 @@ | |
| 1287 | } |
| 1288 | |
| 1289 | /* |
| 1290 | ** WEBPAGE: raw |
| 1291 | ** URL: /raw?name=ARTIFACTID&m=TYPE |
| 1292 | ** |
| 1293 | ** Return the uninterpreted content of an artifact. Used primarily |
| 1294 | ** to view artifacts that are images. |
| 1295 | */ |
| 1296 | void rawartifact_page(void){ |
| 1297 | int rid; |
| @@ -1373,11 +1373,11 @@ | |
| 1373 | } |
| 1374 | |
| 1375 | /* |
| 1376 | ** WEBPAGE: hexdump |
| 1377 | ** URL: /hexdump?name=ARTIFACTID |
| 1378 | ** |
| 1379 | ** Show the complete content of a file identified by ARTIFACTID |
| 1380 | ** as preformatted text. |
| 1381 | */ |
| 1382 | void hexdump_page(void){ |
| 1383 | int rid; |
| @@ -1402,11 +1402,11 @@ | |
| 1402 | style_header("Hex Artifact Content"); |
| 1403 | zUuid = db_text("?","SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1404 | @ <h2>Artifact %s(zUuid):</h2> |
| 1405 | blob_zero(&downloadName); |
| 1406 | object_description(rid, 0, &downloadName); |
| 1407 | style_submenu_element("Download", "Download", |
| 1408 | "%s/raw/%T?name=%s", g.zTop, blob_str(&downloadName), zUuid); |
| 1409 | @ <hr /> |
| 1410 | content_get(rid, &content); |
| 1411 | @ <blockquote><pre> |
| 1412 | hexdump(&content); |
| @@ -1508,11 +1508,11 @@ | |
| 1508 | ** Additional query parameters: |
| 1509 | ** |
| 1510 | ** ln - show line numbers |
| 1511 | ** ln=N - highlight line number N |
| 1512 | ** ln=M-N - highlight lines M through N inclusive |
| 1513 | ** |
| 1514 | ** Show the complete content of a file identified by ARTIFACTID |
| 1515 | ** as preformatted text. |
| 1516 | */ |
| 1517 | void artifact_page(void){ |
| 1518 | int rid = 0; |
| @@ -1545,11 +1545,11 @@ | |
| 1545 | style_header("Artifact Content"); |
| 1546 | zUuid = db_text("?", "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1547 | @ <h2>Artifact %s(zUuid)</h2> |
| 1548 | blob_zero(&downloadName); |
| 1549 | object_description(rid, 0, &downloadName); |
| 1550 | style_submenu_element("Download", "Download", |
| 1551 | "%s/raw/%T?name=%s", g.zTop, blob_str(&downloadName), zUuid); |
| 1552 | zMime = mimetype_from_name(blob_str(&downloadName)); |
| 1553 | if( zMime ){ |
| 1554 | if( fossil_strcmp(zMime, "text/html")==0 ){ |
| 1555 | if( P("txt") ){ |
| @@ -1575,19 +1575,22 @@ | |
| 1575 | content_get(rid, &content); |
| 1576 | if( renderAsWiki ){ |
| 1577 | wiki_convert(&content, 0, 0); |
| 1578 | }else if( renderAsHtml ){ |
| 1579 | @ <div> |
| 1580 | blob_strip_bom(&content, 0); |
| 1581 | cgi_append_content(blob_buffer(&content), blob_size(&content)); |
| 1582 | @ </div> |
| 1583 | }else{ |
| 1584 | style_submenu_element("Hex","Hex", "%s/hexdump?name=%s", g.zTop, zUuid); |
| 1585 | zMime = mimetype_from_content(&content); |
| 1586 | @ <blockquote> |
| 1587 | if( zMime==0 ){ |
| 1588 | const char *zLn = P("ln"); |
| 1589 | const char *z; |
| 1590 | blob_strip_bom(&content, 0); |
| 1591 | z = blob_str(&content); |
| 1592 | if( zLn ){ |
| 1593 | output_text_with_line_numbers(z, zLn); |
| 1594 | }else{ |
| 1595 | @ <pre> |
| 1596 | @ %h(z) |
| @@ -1599,11 +1602,11 @@ | |
| 1602 | @ <i>(file is %d(blob_size(&content)) bytes of binary data)</i> |
| 1603 | } |
| 1604 | @ </blockquote> |
| 1605 | } |
| 1606 | style_footer(); |
| 1607 | } |
| 1608 | |
| 1609 | /* |
| 1610 | ** WEBPAGE: tinfo |
| 1611 | ** URL: /tinfo?name=ARTIFACTID |
| 1612 | ** |
| @@ -1663,20 +1666,20 @@ | |
| 1666 | /* |
| 1667 | ** WEBPAGE: info |
| 1668 | ** URL: info/ARTIFACTID |
| 1669 | ** |
| 1670 | ** The argument is a artifact ID which might be a baseline or a file or |
| 1671 | ** a ticket changes or a wiki edit or something else. |
| 1672 | ** |
| 1673 | ** Figure out what the artifact ID is and jump to it. |
| 1674 | */ |
| 1675 | void info_page(void){ |
| 1676 | const char *zName; |
| 1677 | Blob uuid; |
| 1678 | int rid; |
| 1679 | int rc; |
| 1680 | |
| 1681 | zName = P("name"); |
| 1682 | if( zName==0 ) fossil_redirect_home(); |
| 1683 | if( validate16(zName, strlen(zName)) ){ |
| 1684 | if( db_exists("SELECT 1 FROM ticket WHERE tkt_uuid GLOB '%q*'", zName) ){ |
| 1685 | tktview_page(); |
| @@ -1769,28 +1772,28 @@ | |
| 1772 | { "#d3a8bc", 0 }, |
| 1773 | { "#d3b5a8", 0 }, |
| 1774 | { "#d1d3a8", 0 }, |
| 1775 | { "#b1d3a8", 0 }, |
| 1776 | |
| 1777 | { "#8eb2a1", 0 }, |
| 1778 | { "#8ea7b2", 0 }, |
| 1779 | { "#8f8eb2", 0 }, |
| 1780 | { "#ab8eb2", 0 }, |
| 1781 | { "#b28e9e", 0 }, |
| 1782 | { "#b2988e", 0 }, |
| 1783 | { "#b0b28e", 0 }, |
| 1784 | { "#95b28e", 0 }, |
| 1785 | |
| 1786 | { "#80d6b0", 0 }, |
| 1787 | { "#80bbd6", 0 }, |
| 1788 | { "#8680d6", 0 }, |
| 1789 | { "#c680d6", 0 }, |
| 1790 | { "#d680a6", 0 }, |
| 1791 | { "#d69b80", 0 }, |
| 1792 | { "#d1d680", 0 }, |
| 1793 | { "#91d680", 0 }, |
| 1794 | |
| 1795 | |
| 1796 | { "custom", "##" }, |
| 1797 | }; |
| 1798 | int nColor = sizeof(aColor)/sizeof(aColor[0])-1; |
| 1799 | int stdClrFound = 0; |
| @@ -1893,11 +1896,11 @@ | |
| 1896 | const char *zNewComment; /* Revised check-in comment */ |
| 1897 | const char *zUser; /* Current user for the check-in */ |
| 1898 | const char *zNewUser; /* Revised user */ |
| 1899 | const char *zDate; /* Current date of the check-in */ |
| 1900 | const char *zNewDate; /* Revised check-in date */ |
| 1901 | const char *zColor; |
| 1902 | const char *zNewColor; |
| 1903 | const char *zNewTagFlag; |
| 1904 | const char *zNewTag; |
| 1905 | const char *zNewBrFlag; |
| 1906 | const char *zNewBranch; |
| @@ -1906,11 +1909,11 @@ | |
| 1909 | int fNewPropagateColor; /* True if color propagates after edit */ |
| 1910 | const char *zChngTime = 0; /* Value of chngtime= query param, if any */ |
| 1911 | char *zUuid; |
| 1912 | Blob comment; |
| 1913 | Stmt q; |
| 1914 | |
| 1915 | login_check_credentials(); |
| 1916 | if( !g.perm.Write ){ login_needed(); return; } |
| 1917 | rid = name_to_typed_rid(P("r"), "ci"); |
| 1918 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); |
| 1919 | zComment = db_text(0, "SELECT coalesce(ecomment,comment)" |
| @@ -1953,11 +1956,11 @@ | |
| 1956 | blob_zero(&ctrl); |
| 1957 | zNow = date_in_standard_format(zChngTime ? zChngTime : "now"); |
| 1958 | blob_appendf(&ctrl, "D %s\n", zNow); |
| 1959 | db_multi_exec("CREATE TEMP TABLE newtags(tag UNIQUE, prefix, value)"); |
| 1960 | if( zNewColor[0] |
| 1961 | && (fPropagateColor!=fNewPropagateColor |
| 1962 | || fossil_strcmp(zColor,zNewColor)!=0) |
| 1963 | ){ |
| 1964 | char *zPrefix = "+"; |
| 1965 | if( fNewPropagateColor ){ |
| 1966 | zPrefix = "*"; |
| 1967 |