Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | merge trunk |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | openssl-1.1 |
Files: | files | file ages | folders |
SHA3-256: |
368c78a855cf65e9cacee8c898a6f1bb |
User & Date: | jan.nijtmans 2018-09-11 14:54:21.184 |
Context
2018-09-15
| ||
20:27 | add support for TLS 1.3, when compiled with OpenSSL 1.1.1 (LTS). Windows build adapted to use OpenSSL 1.1.1 by default. Still compiles and runs with older OpenSSL as well ... (check-in: 115544e9 user: jan.nijtmans tags: trunk) | |
2018-09-11
| ||
14:54 | merge trunk ... (Closed-Leaf check-in: 368c78a8 user: jan.nijtmans tags: openssl-1.1) | |
14:29 | Compile openssl with option no-weak-ssl-ciphers (or -DOPENSSL_NO_WEAK_SSL_CIPHERS) Update custum Makefile.mingw ... (check-in: 58b7b4e5 user: jan.nijtmans tags: trunk) | |
2018-08-24
| ||
08:29 | Merge trunk. Undo unintended changes in previous commit ... (check-in: 5583448c user: jan.nijtmans tags: openssl-1.1) | |
Changes
Changes to Makefile.in.
︙ | ︙ | |||
32 33 34 35 36 37 38 | E = @EXEEXT@ TCC = @CC@ #### Tcl shell for use in running the fossil testsuite. If you do not # care about testing the end result, this can be blank. # | | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | E = @EXEEXT@ TCC = @CC@ #### Tcl shell for use in running the fossil testsuite. If you do not # care about testing the end result, this can be blank. # TCLSH = @TCLSH@ CFLAGS = @CFLAGS@ LIB = @LDFLAGS@ @EXTRA_LDFLAGS@ @LIBS@ BCCFLAGS = @CPPFLAGS@ $(CFLAGS) TCCFLAGS = @EXTRA_CFLAGS@ @CPPFLAGS@ $(CFLAGS) -DHAVE_AUTOCONFIG_H -D_HAVE_SQLITE_CONFIG_H INSTALLDIR = $(DESTDIR)@prefix@/bin USE_SYSTEM_SQLITE = @USE_SYSTEM_SQLITE@ |
︙ | ︙ |
Changes to auto.def.
︙ | ︙ | |||
31 32 33 34 35 36 37 | cc-with {-includes {stdint.h inttypes.h}} { cc-check-types uint32_t uint16_t int16_t uint8_t } # Use pread/pwrite system calls in place of seek + read/write if possible define USE_PREAD [cc-check-functions pread] | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | cc-with {-includes {stdint.h inttypes.h}} { cc-check-types uint32_t uint16_t int16_t uint8_t } # Use pread/pwrite system calls in place of seek + read/write if possible define USE_PREAD [cc-check-functions pread] # Find tclsh for the test suite. # # We can't use jimsh for this: the test suite uses features of Tcl that # Jim doesn't support, either statically or due to the way it's built by # autosetup. For example, Jim supports `file normalize`, but only if # you build it with HAVE_REALPATH, which won't ever be defined in this # context because autosetup doesn't try to discover platform-specific # details like that before it decides to build jimsh0. Besides which, # autosetup won't build jimsh0 at all if it can find tclsh itself. # Ironically, this means we may right now be running under either jimsh0 # or a version of tclsh that we find unsuitable below! cc-check-progs tclsh set hbtd /usr/local/Cellar/tcl-tk if {[string equal false [get-define TCLSH]]} { msg-result "WARNING: 'make test' will not run here." } else { set v [exec /bin/sh -c "echo 'puts \$tcl_version' | tclsh"] if {[expr $v >= 8.6]} { msg-result "Found Tclsh version $v in the PATH." define TCLSH tclsh } elseif {[file isdirectory $hbtd]} { # This is a macOS system with the Homebrew version of Tcl/Tk # installed. Select the newest version. It won't normally be # in the PATH to avoid shadowing /usr/bin/tclsh, and even if it # were in the PATH, it's bad practice to put /usr/local/bin (the # Homebrew default) ahead of /usr/bin, especially given that # it's user-writeable by default with Homebrew. Thus, we can be # pretty sure the only way to call it is with an absolute path. set v [exec ls -tr $hbtd | tail -1] set path "$hbtd/$v/bin/tclsh" define TCLSH $path msg-result "Using Homebrew Tcl/Tk version $path." } else { msg-result "WARNING: tclsh $v found; need >= 8.6 for 'make test'." define TCLSH false ;# force "make test" failure via /usr/bin/false } } define EXTRA_CFLAGS "-Wall" define EXTRA_LDFLAGS "" define USE_SYSTEM_SQLITE 0 define USE_LINENOISE 0 define FOSSIL_ENABLE_MINIZ 0 define USE_MMAN_H 0 |
︙ | ︙ |
Changes to skins/ardoise/header.txt.
︙ | ︙ | |||
39 40 41 42 43 44 45 46 47 48 49 50 51 52 | } if {[hascap oh]} { menulink /dir?ci=tip Files } if {[hascap o]} { menulink /brlist Branches menulink /taglist Tags } if {[hascap r]} { menulink /ticket Tickets } if {[hascap j]} { menulink /wiki Wiki } | > > > | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | } if {[hascap oh]} { menulink /dir?ci=tip Files } if {[hascap o]} { menulink /brlist Branches menulink /taglist Tags } if {[anycap 23456] || [anoncap 2] || [anoncap 3]} { menulink /forum Forum } if {[hascap r]} { menulink /ticket Tickets } if {[hascap j]} { menulink /wiki Wiki } |
︙ | ︙ |
Changes to skins/black_and_white/header.txt.
︙ | ︙ | |||
20 21 22 23 24 25 26 27 28 29 30 31 32 33 | } if {[anoncap oh]} { html "<a href='$home/tree?ci=tip'>Files</a>\n" } if {[anoncap o]} { html "<a href='$home/brlist'>Branches</a>\n" html "<a href='$home/taglist'>Tags</a>\n" } if {[anoncap r]} { html "<a href='$home/ticket'>Tickets</a>\n" } if {[anoncap j]} { html "<a href='$home/wiki'>Wiki</a>\n" } | > > > | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | } if {[anoncap oh]} { html "<a href='$home/tree?ci=tip'>Files</a>\n" } if {[anoncap o]} { html "<a href='$home/brlist'>Branches</a>\n" html "<a href='$home/taglist'>Tags</a>\n" } if {[anycap 23456] || [anoncap 2] || [anoncap 3]} { html "<a href='$home/forum'>Forum</a>\n" } if {[anoncap r]} { html "<a href='$home/ticket'>Tickets</a>\n" } if {[anoncap j]} { html "<a href='$home/wiki'>Wiki</a>\n" } |
︙ | ︙ |
Changes to skins/blitz/header.txt.
︙ | ︙ | |||
43 44 45 46 47 48 49 50 51 52 53 54 55 56 | } if {[hascap oh]} { menulink /dir?ci=tip Files } if {[hascap o]} { menulink /brlist Branches menulink /taglist Tags } if {[hascap r]} { menulink /ticket Tickets } if {[hascap j]} { menulink /wiki Wiki } | > > > | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | } if {[hascap oh]} { menulink /dir?ci=tip Files } if {[hascap o]} { menulink /brlist Branches menulink /taglist Tags } if {[anycap 23456] || [anoncap 2] || [anoncap 3]} { menulink /forum Forum } if {[hascap r]} { menulink /ticket Tickets } if {[hascap j]} { menulink /wiki Wiki } |
︙ | ︙ |
Changes to skins/blitz_no_logo/header.txt.
︙ | ︙ | |||
40 41 42 43 44 45 46 47 48 49 50 51 52 53 | } if {[hascap oh]} { menulink /dir?ci=tip Files } if {[hascap o]} { menulink /brlist Branches menulink /taglist Tags } if {[hascap r]} { menulink /ticket Tickets } if {[hascap j]} { menulink /wiki Wiki } | > > > | 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | } if {[hascap oh]} { menulink /dir?ci=tip Files } if {[hascap o]} { menulink /brlist Branches menulink /taglist Tags } if {[anycap 23456] || [anoncap 2] || [anoncap 3]} { menulink /forum Forum } if {[hascap r]} { menulink /ticket Tickets } if {[hascap j]} { menulink /wiki Wiki } |
︙ | ︙ |
Changes to skins/bootstrap/header.txt.
︙ | ︙ | |||
75 76 77 78 79 80 81 82 83 84 85 86 87 88 | html "<li><a href='$home/brlist'>Branches</a></li>\n" } if {[string compare $current_page "taglist"] == 0} { html "<li class='active'><a href='$home/taglist'>Tags</a></li>\n" } else { html "<li><a href='$home/taglist'>Tags</a></li>\n" } } if {[hascap r]} { if {[string compare $current_page "reportlist"] == 0} { html "<li class='active'><a href='$home/reportlist'>Tickets</a></li>\n" } else { html "<li><a href='$home/reportlist'>Tickets</a></li>\n" } | > > > > > > > | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | html "<li><a href='$home/brlist'>Branches</a></li>\n" } if {[string compare $current_page "taglist"] == 0} { html "<li class='active'><a href='$home/taglist'>Tags</a></li>\n" } else { html "<li><a href='$home/taglist'>Tags</a></li>\n" } } if {[anycap 23456] || [anoncap 2] || [anoncap 3]} { if {[string compare $current_page "forum"] == 0} { html "<li class='active'><a href='$home/forum'>Forum</a></li>\n" } else { html "<li><a href='$home/forum'>Forum</a></li>\n" } } if {[hascap r]} { if {[string compare $current_page "reportlist"] == 0} { html "<li class='active'><a href='$home/reportlist'>Tickets</a></li>\n" } else { html "<li><a href='$home/reportlist'>Tickets</a></li>\n" } |
︙ | ︙ |
Changes to skins/default/css.txt.
1 2 | body { margin: 0 auto; | < > > > < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | body { margin: 0 auto; background-color: white; font-family: sans-serif; font-size:14pt; -moz-text-size-adjust: none; -webkit-text-size-adjust: none; -mx-text-size-adjust: none; } a { color: #4183C4; text-decoration: none; } a:hover { color: #4183C4; text-decoration: underline; } div.forumPosts a:visited { color: #6A7F94; } hr { color: #eee; } .title { color: #4183C4; float:left; } .title h1 { display:inline; } .title h1:after { content: " / "; color: #777; |
︙ | ︙ | |||
70 71 72 73 74 75 76 | display: inline-block; margin-right: 1em; } .status { float:right; font-size:.7em; | < < > > < > > > > > > > > > > > > > > < | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | display: inline-block; margin-right: 1em; } .status { float:right; font-size:.7em; } .mainmenu { font-size:.8em; clear:both; background:#eaeaea linear-gradient(#fafafa, #eaeaea) repeat-x; border:1px solid #eaeaea; border-radius:5px; overflow-x: auto; overflow-y: hidden; white-space: nowrap; z-index: 21; /* just above hbdrop */ } .mainmenu a { text-decoration:none; color: #777; border-right:1px solid #eaeaea; } .mainmenu a.active, .mainmenu a:hover { color: #000; border-bottom:2px solid #D26911; } div#hbdrop { background-color: white; border: 1px solid black; border-top: white; border-radius: 0 0 0.5em 0.5em; display: none; font-size: 80%; left: 2em; width: 90%; padding-right: 1em; position: absolute; z-index: 20; /* just below mainmenu, but above timeline bubbles */ } .submenu { font-size: .7em; padding: 10px; border-bottom: 1px solid #ccc; } .submenu a, .submenu label { padding: 10px 11px; text-decoration:none; |
︙ | ︙ | |||
205 206 207 208 209 210 211 | } span.submenuctrl { white-space: nowrap; } div.submenu label { white-space: nowrap; } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | } span.submenuctrl { white-space: nowrap; } div.submenu label { white-space: nowrap; } @media screen and (max-width: 600px) { /* Spacing for mobile */ body { padding-left: 4px; padding-right: 4px; } .title { padding-top: 0px; padding-bottom: 0px; } .status {padding-top: 0px;} .mainmenu a { padding: 10px 10px; } .mainmenu { padding: 10px; } .desktoponly { display: none; } } @media screen and (min-width: 600px) { /* Spacing for desktop */ body { padding-left: 20px; padding-right: 20px; } .title { padding-top: 10px; padding-bottom: 10px; } .status {padding-top: 30px;} .mainmenu a { padding: 10px 20px; } .mainmenu { padding: 10px; } } @media screen and (max-width: 1200px) { /* Special declarations for narrow desktop or wide mobile */ .wideonly { display: none; } } |
Changes to skins/default/footer.txt.
1 2 3 4 5 | <div class="footer"> This page was generated in about <th1>puts [expr {([utime]+[stime]+1000)/1000*0.001}]</th1>s by Fossil $release_version $manifest_version $manifest_date </div> | > > > | 1 2 3 4 5 6 7 8 | <div class="footer"> This page was generated in about <th1>puts [expr {([utime]+[stime]+1000)/1000*0.001}]</th1>s by Fossil $release_version $manifest_version $manifest_date </div> <script nonce="$nonce"> <th1>styleScript</th1> </script> |
Changes to skins/default/header.txt.
1 2 3 4 5 6 7 8 9 10 11 12 | <div class="header"> <div class="title"><h1>$<project_name></h1>$<title></div> <div class="status"><th1> if {[info exists login]} { html "$login — <a href='$home/login'>Logout</a>\n" } else { html "<a href='$home/login'>Login</a>\n" } </th1></div> </div> <div class="mainmenu"> <th1> | | | | > | | | | | > > > | | | | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | <div class="header"> <div class="title"><h1>$<project_name></h1>$<title></div> <div class="status"><th1> if {[info exists login]} { html "$login — <a href='$home/login'>Logout</a>\n" } else { html "<a href='$home/login'>Login</a>\n" } </th1></div> </div> <div class="mainmenu"> <th1> proc menulink {url name cls} { upvar current_page current upvar home home if {[string range $url 0 [string length $current]] eq "/$current"} { html "<a href='$home$url' class='active $cls'>$name</a>\n" } else { html "<a href='$home$url' class='$cls'>$name</a>\n" } } html "<a href='#'>☰</a>" menulink $index_page Home {} if {[anycap jor]} { menulink /timeline Timeline {} } if {[hascap oh]} { menulink /dir?ci=tip Files desktoponly } if {[hascap o]} { menulink /brlist Branches desktoponly menulink /taglist Tags wideonly } if {[anycap 23456] || [anoncap 2] || [anoncap 3]} { menulink /forum Forum wideonly } if {[hascap r]} { menulink /ticket Tickets wideonly } if {[hascap j]} { menulink /wiki Wiki wideonly } if {[hascap s]} { menulink /setup Admin {} } elseif {[hascap a]} { menulink /setup_ulist Users {} } </th1></div> <div id='hbdrop'></div> |
Added skins/default/js.txt.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | (function() { var home='$home'; var panel = document.getElementById("hbdrop"); if (!panel) return; // site admin might've nuked it var panelBorder = panel.style.border; var animate = panel.style.hasOwnProperty('transition'); var animMS = 400; // Calculate panel height despite its being hidden at call time. // Based on https://stackoverflow.com/a/29047447/142454 var panelHeight; // computed on sitemap load function calculatePanelHeight() { // Get initial panel styles so we can restore them below. var es = window.getComputedStyle(panel), edis = es.display, epos = es.position, evis = es.visibility; // Restyle the panel so we can measure its height while invisible. panel.style.visibility = 'hidden'; panel.style.position = 'absolute'; panel.style.display = 'block'; panelHeight = panel.offsetHeight + 'px'; // Revert styles now that job is done. panel.style.display = edis; panel.style.position = epos; panel.style.visibility = evis; } // Show the panel by changing the panel height, which kicks off the // slide-open/closed transition set up in the XHR onload handler. // // Schedule the change for a near-future time in case this is the // first call, where the div was initially invisible. That causes // the browser to consider the height change as part of the same // state change as the visibility change, so it doesn't see a state // *transition*, hence never kicks off the *CSS* transition: // // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions#JavaScript_examples function showPanel() { if (animate) { setTimeout(function() { panel.style.maxHeight = panelHeight; panel.style.border = panelBorder; }, 40); // 25ms is insufficient with Firefox 62 } else { panel.style.display = 'block'; } } // Return true if the panel is showing. function panelShowing() { if (animate) { return panel.style.maxHeight == panelHeight; } else { return panel.style.display == 'block'; } } // Click handler for the hamburger button. var needSitemapHTML = true; document.querySelector("div.mainmenu > a").onclick = function() { if (panelShowing()) { // Transition back to hidden state. if (animate) { panel.style.maxHeight = '0'; setTimeout(function() { // Browsers show a 1px high border line when maxHeight == 0, // our "hidden" state, so hide the borders in that state, too. panel.style.border = 'none'; }, animMS); } else { panel.style.display = 'none'; } } else if (needSitemapHTML) { // Only get it once per page load: it isn't likely to // change on us. var xhr = new XMLHttpRequest(); xhr.onload = function() { var doc = xhr.responseXML; if (doc) { var sm = doc.querySelector("ul#sitemap"); if (sm && xhr.status == 200) { // Got sitemap. Insert it into the drop-down panel. needSitemapHTML = false; panel.innerHTML = sm.outerHTML; if (window.setAllHrefs) { setAllHrefs(); // don't need anti-robot defense here } // Display the panel if (animate) { // Set up a CSS transition to animate the panel open and // closed. Only needs to be done once per page load. // Based on https://stackoverflow.com/a/29047447/142454 calculatePanelHeight(); panel.style.transition = 'max-height ' + (animMS / 1000) + 's ease-in-out'; panel.style.overflowY = 'hidden'; panel.style.maxHeight = '0'; showPanel(); } panel.style.display = 'block'; } } // else, can't parse response as HTML or XML } xhr.open("POST", home + "/sitemap"); xhr.responseType = "document"; xhr.send("popup=1"); } else { showPanel(); // just show what we built above } return false; // prevent browser from acting on <a> click } })(); |
Changes to skins/eagle/header.txt.
︙ | ︙ | |||
69 70 71 72 73 74 75 | if {[info exists login]} { puts "Logged in as $login" } else { puts "Not logged in" } </th1></nobr><small><div id="clock"></div></small></div> </div> | | | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | if {[info exists login]} { puts "Logged in as $login" } else { puts "Not logged in" } </th1></nobr><small><div id="clock"></div></small></div> </div> <th1>html "<script nonce='$nonce'>"</th1> function updateClock(){ var e = document.getElementById("clock"); if(e){ var d = new Date(); function f(n) { return n < 10 ? '0' + n : n; } |
︙ | ︙ | |||
104 105 106 107 108 109 110 111 112 113 114 115 116 117 | } if {[anoncap oh]} { menulink /dir?ci=tip Files } if {[anoncap o]} { menulink /brlist Branches menulink /taglist Tags } if {[anoncap r]} { menulink /ticket Tickets } if {[anoncap j]} { menulink /wiki Wiki } | > > > | 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | } if {[anoncap oh]} { menulink /dir?ci=tip Files } if {[anoncap o]} { menulink /brlist Branches menulink /taglist Tags } if {[anycap 23456] || [anoncap 2] || [anoncap 3]} { menulink /forum Forum } if {[anoncap r]} { menulink /ticket Tickets } if {[anoncap j]} { menulink /wiki Wiki } |
︙ | ︙ |
Changes to skins/enhanced1/header.txt.
︙ | ︙ | |||
69 70 71 72 73 74 75 | if {[info exists login]} { puts "Logged in as $login" } else { puts "Not logged in" } </th1></nobr><small><div id="clock"></div></small></div> </div> | | | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | if {[info exists login]} { puts "Logged in as $login" } else { puts "Not logged in" } </th1></nobr><small><div id="clock"></div></small></div> </div> <th1>html "<script nonce='$nonce'>"</th1> function updateClock(){ var e = document.getElementById("clock"); if(e){ var d = new Date(); function f(n) { return n < 10 ? '0' + n : n; } |
︙ | ︙ | |||
104 105 106 107 108 109 110 111 112 113 114 115 116 117 | } if {[anoncap oh]} { menulink /dir?ci=tip Files } if {[anoncap o]} { menulink /brlist Branches menulink /taglist Tags } if {[anoncap r]} { menulink /ticket Tickets } if {[anoncap j]} { menulink /wiki Wiki } | > > > | 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | } if {[anoncap oh]} { menulink /dir?ci=tip Files } if {[anoncap o]} { menulink /brlist Branches menulink /taglist Tags } if {[anycap 23456] || [anoncap 2] || [anoncap 3]} { menulink /forum Forum } if {[anoncap r]} { menulink /ticket Tickets } if {[anoncap j]} { menulink /wiki Wiki } |
︙ | ︙ |
Changes to skins/khaki/header.txt.
︙ | ︙ | |||
18 19 20 21 22 23 24 25 26 27 28 29 30 31 | } if {[anoncap oh]} { html "<a href='$home/tree?ci=tip'>Files</a>\n" } if {[anoncap o]} { html "<a href='$home/brlist'>Branches</a>\n" html "<a href='$home/taglist'>Tags</a>\n" } if {[anoncap r]} { html "<a href='$home/ticket'>Tickets</a>\n" } if {[anoncap j]} { html "<a href='$home/wiki'>Wiki</a>\n" } | > > > | 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | } if {[anoncap oh]} { html "<a href='$home/tree?ci=tip'>Files</a>\n" } if {[anoncap o]} { html "<a href='$home/brlist'>Branches</a>\n" html "<a href='$home/taglist'>Tags</a>\n" } if {[anycap 23456] || [anoncap 2] || [anoncap 3]} { html "<a href='$home/forum'>Forum</a>\n" } if {[anoncap r]} { html "<a href='$home/ticket'>Tickets</a>\n" } if {[anoncap j]} { html "<a href='$home/wiki'>Wiki</a>\n" } |
︙ | ︙ |
Changes to skins/original/header.txt.
︙ | ︙ | |||
19 20 21 22 23 24 25 26 27 28 29 30 31 32 | } if {[anoncap oh]} { html "<a href='$home/tree?ci=tip'>Files</a>\n" } if {[anoncap o]} { html "<a href='$home/brlist'>Branches</a>\n" html "<a href='$home/taglist'>Tags</a>\n" } if {[anoncap r]} { html "<a href='$home/ticket'>Tickets</a>\n" } if {[anoncap j]} { html "<a href='$home/wiki'>Wiki</a>\n" } | > > > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | } if {[anoncap oh]} { html "<a href='$home/tree?ci=tip'>Files</a>\n" } if {[anoncap o]} { html "<a href='$home/brlist'>Branches</a>\n" html "<a href='$home/taglist'>Tags</a>\n" } if {[anycap 23456] || [anoncap 2] || [anoncap 3]} { html "<a href='$home/forum'>Forum</a>\n" } if {[anoncap r]} { html "<a href='$home/ticket'>Tickets</a>\n" } if {[anoncap j]} { html "<a href='$home/wiki'>Wiki</a>\n" } |
︙ | ︙ |
Changes to skins/plain_gray/header.txt.
︙ | ︙ | |||
16 17 18 19 20 21 22 23 24 25 26 27 28 29 | } if {[anoncap oh]} { html "<a href='$home/tree?ci=tip'>Files</a>\n" } if {[anoncap o]} { html "<a href='$home/brlist'>Branches</a>\n" html "<a href='$home/taglist'>Tags</a>\n" } if {[anoncap r]} { html "<a href='$home/ticket'>Tickets</a>\n" } if {[anoncap j]} { html "<a href='$home/wiki'>Wiki</a>\n" } | > > > | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | } if {[anoncap oh]} { html "<a href='$home/tree?ci=tip'>Files</a>\n" } if {[anoncap o]} { html "<a href='$home/brlist'>Branches</a>\n" html "<a href='$home/taglist'>Tags</a>\n" } if {[anycap 23456] || [anoncap 2] || [anoncap 3]} { html "<a href='$home/forum'>Forum</a>\n" } if {[anoncap r]} { html "<a href='$home/ticket'>Tickets</a>\n" } if {[anoncap j]} { html "<a href='$home/wiki'>Wiki</a>\n" } |
︙ | ︙ |
Changes to skins/rounded1/header.txt.
︙ | ︙ | |||
20 21 22 23 24 25 26 27 28 29 30 31 32 33 | } if {[anoncap oh]} { html "<a href='$home/tree?ci=tip'>Files</a>\n" } if {[anoncap o]} { html "<a href='$home/brlist'>Branches</a>\n" html "<a href='$home/taglist'>Tags</a>\n" } if {[anoncap r]} { html "<a href='$home/ticket'>Tickets</a>\n" } if {[anoncap j]} { html "<a href='$home/wiki'>Wiki</a>\n" } | > > > | 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | } if {[anoncap oh]} { html "<a href='$home/tree?ci=tip'>Files</a>\n" } if {[anoncap o]} { html "<a href='$home/brlist'>Branches</a>\n" html "<a href='$home/taglist'>Tags</a>\n" } if {[anycap 23456] || [anoncap 2] || [anoncap 3]} { html "<a href='$home/forum'>Forum</a>\n" } if {[anoncap r]} { html "<a href='$home/ticket'>Tickets</a>\n" } if {[anoncap j]} { html "<a href='$home/wiki'>Wiki</a>\n" } |
︙ | ︙ |
Changes to skins/xekri/header.txt.
︙ | ︙ | |||
69 70 71 72 73 74 75 | if {[info exists login]} { puts "Logged in as $login" } else { puts "Not logged in" } </th1></nobr><small><div id="clock"></div></small></div> </div> | | | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | if {[info exists login]} { puts "Logged in as $login" } else { puts "Not logged in" } </th1></nobr><small><div id="clock"></div></small></div> </div> <th1>html "<script nonce='$nonce'>"</th1> function updateClock(){ var e = document.getElementById("clock"); if(e){ var d = new Date(); function f(n) { return n < 10 ? '0' + n : n; } |
︙ | ︙ | |||
108 109 110 111 112 113 114 115 116 117 118 119 120 121 | } if {[anoncap oh]} { menulink /dir?ci=tip Files } if {[anoncap o]} { menulink /brlist Branches menulink /taglist Tags } if {[anoncap r]} { menulink /ticket Tickets } if {[anoncap j]} { menulink /wiki Wiki } | > > > | 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | } if {[anoncap oh]} { menulink /dir?ci=tip Files } if {[anoncap o]} { menulink /brlist Branches menulink /taglist Tags } if {[anycap 23456] || [anoncap 2] || [anoncap 3]} { menulink /forum Forum } if {[anoncap r]} { menulink /ticket Tickets } if {[anoncap j]} { menulink /wiki Wiki } |
︙ | ︙ |
Name change from src/email.c to src/alerts.c.
︙ | ︙ | |||
19 20 21 22 23 24 25 | ** ** Are you looking for the code that reads and writes the internet ** email protocol? That is not here. See the "smtp.c" file instead. ** Yes, the choice of source code filenames is not the greatest, but ** it is not so bad that changing them seems justified. */ #include "config.h" | | | | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | ** ** Are you looking for the code that reads and writes the internet ** email protocol? That is not here. See the "smtp.c" file instead. ** Yes, the choice of source code filenames is not the greatest, but ** it is not so bad that changing them seems justified. */ #include "config.h" #include "alerts.h" #include <assert.h> #include <time.h> /* ** Maximum size of the subscriberCode blob, in bytes */ #define SUBSCRIBER_CODE_SZ 32 /* ** SQL code to implement the tables needed by the email notification ** system. */ static const char zAlertInit[] = @ DROP TABLE IF EXISTS repository.subscriber; @ -- Subscribers are distinct from users. A person can have a log-in in @ -- the USER table without being a subscriber. Or a person can be a @ -- subscriber without having a USER table entry. Or they can have both. @ -- In the last case the suname column points from the subscriber entry @ -- to the USER entry. @ -- |
︙ | ︙ | |||
80 81 82 83 84 85 86 | @ CREATE TABLE repository.pending_alert( @ eventid TEXT PRIMARY KEY, -- Object that changed @ sentSep BOOLEAN DEFAULT false, -- individual alert sent @ sentDigest BOOLEAN DEFAULT false, -- digest alert sent @ sentMod BOOLEAN DEFAULT false -- pending moderation alert sent @ ) WITHOUT ROWID; @ | | | | | | | | | | | | > | | | | | | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | @ CREATE TABLE repository.pending_alert( @ eventid TEXT PRIMARY KEY, -- Object that changed @ sentSep BOOLEAN DEFAULT false, -- individual alert sent @ sentDigest BOOLEAN DEFAULT false, -- digest alert sent @ sentMod BOOLEAN DEFAULT false -- pending moderation alert sent @ ) WITHOUT ROWID; @ @ DROP TABLE IF EXISTS repository.alert_bounce; @ -- Record bounced emails. If too many bounces are received within @ -- some defined time range, then cancel the subscription. Older @ -- entries are periodically purged. @ -- @ CREATE TABLE repository.alert_bounce( @ subscriberId INTEGER, -- to whom the email was sent. @ sendTime INTEGER, -- seconds since 1970 when email was sent @ rcvdTime INTEGER -- seconds since 1970 when bounce was received @ ); ; /* ** Return true if the email notification tables exist. */ int alert_tables_exist(void){ return db_table_exists("repository", "subscriber"); } /* ** Make sure the table needed for email notification exist in the repository. ** ** If the bOnlyIfEnabled option is true, then tables are only created ** if the email-send-method is something other than "off". */ void alert_schema(int bOnlyIfEnabled){ if( !alert_tables_exist() ){ if( bOnlyIfEnabled && fossil_strcmp(db_get("email-send-method","off"),"off")==0 ){ return; /* Don't create table for disabled email */ } db_multi_exec(zAlertInit/*works-like:""*/); alert_triggers_enable(); }else if( !db_table_has_column("repository","pending_alert","sentMod") ){ db_multi_exec( "ALTER TABLE repository.pending_alert" " ADD COLUMN sentMod BOOLEAN DEFAULT false;" ); } } /* ** Enable triggers that automatically populate the pending_alert ** table. */ void alert_triggers_enable(void){ if( !db_table_exists("repository","pending_alert") ) return; db_multi_exec( "CREATE TRIGGER IF NOT EXISTS repository.alert_trigger1\n" "AFTER INSERT ON event BEGIN\n" " INSERT INTO pending_alert(eventid)\n" " SELECT printf('%%.1c%%d',new.type,new.objid) WHERE true\n" " ON CONFLICT(eventId) DO NOTHING;\n" "END;" ); } /* ** Disable triggers the event_pending triggers. ** ** This must be called before rebuilding the EVENT table, for example ** via the "fossil rebuild" command. */ void alert_triggers_disable(void){ db_multi_exec( "DROP TRIGGER IF EXISTS repository.alert_trigger1;\n" "DROP TRIGGER IF EXISTS repository.email_trigger1;\n" // Legacy ); } /* ** Return true if email alerts are active. */ int alert_enabled(void){ if( !alert_tables_exist() ) return 0; if( fossil_strcmp(db_get("email-send-method","off"),"off")==0 ) return 0; return 1; } /* ** If the subscriber table does not exist, then paint an error message ** web page and return true. ** ** If the subscriber table does exist, return 0 without doing anything. */ static int alert_webpages_disabled(void){ if( alert_tables_exist() ) return 0; style_header("Email Alerts Are Disabled"); @ <p>Email alerts are disabled on this server</p> style_footer(); return 1; } /* ** Insert a "Subscriber List" submenu link if the current user ** is an administrator. */ void alert_submenu_common(void){ if( g.perm.Admin ){ if( fossil_strcmp(g.zPath,"subscribers") ){ style_submenu_element("List Subscribers","%R/subscribers"); } if( fossil_strcmp(g.zPath,"subscribe") ){ style_submenu_element("Add New Subscriber","%R/subscribe"); } |
︙ | ︙ | |||
210 211 212 213 214 215 216 | login_check_credentials(); if( !g.perm.Setup ){ login_needed(0); return; } db_begin_transaction(); | | | | 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | login_check_credentials(); if( !g.perm.Setup ){ login_needed(0); return; } db_begin_transaction(); alert_submenu_common(); style_submenu_element("Send Announcement","%R/announce"); style_header("Email Notification Setup"); @ <h1>Status</h1> @ <table class="label-value"> if( alert_enabled() ){ stats_for_email(); }else{ @ <th>Disabled</th> } @ </table> @ <hr> @ <h1> Configuration </h1> |
︙ | ︙ | |||
263 264 265 266 267 268 269 | multiple_choice_attribute("Email Send Method", "email-send-method", "esm", "off", count(azSendMethods)/2, azSendMethods); @ <p>How to send email. Requires auxiliary information from the fields @ that follow. Hint: Use the <a href="%R/announce">/announce</a> page @ to send test message to debug this setting. @ (Property: "email-send-method")</p> | | | 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 | multiple_choice_attribute("Email Send Method", "email-send-method", "esm", "off", count(azSendMethods)/2, azSendMethods); @ <p>How to send email. Requires auxiliary information from the fields @ that follow. Hint: Use the <a href="%R/announce">/announce</a> page @ to send test message to debug this setting. @ (Property: "email-send-method")</p> alert_schema(1); entry_attribute("Pipe Email Text Into This Command", 60, "email-send-command", "ecmd", "sendmail -ti", 0); @ <p>When the send method is "pipe to a command", this is the command @ that is run. Email messages are piped into the standard input of this @ command. The command is expected to extract the sender address, @ recepient addresses, and subject from the header of the piped email @ text. (Property: "email-send-command")</p> |
︙ | ︙ | |||
370 371 372 373 374 375 376 | # define pclose _pclose #endif #if INTERFACE /* ** An instance of the following object is used to send emails. */ | | | | | | | | | | | | | | | | 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 | # define pclose _pclose #endif #if INTERFACE /* ** An instance of the following object is used to send emails. */ struct AlertSender { sqlite3 *db; /* Database emails are sent to */ sqlite3_stmt *pStmt; /* Stmt to insert into the database */ const char *zDest; /* How to send email. */ const char *zDb; /* Name of database file */ const char *zDir; /* Directory in which to store as email files */ const char *zCmd; /* Command to run for each email */ const char *zFrom; /* Emails come from here */ SmtpSession *pSmtp; /* SMTP relay connection */ Blob out; /* For zDest=="blob" */ char *zErr; /* Error message */ u32 mFlags; /* Flags */ int bImmediateFail; /* On any error, call fossil_fatal() */ }; /* Allowed values for mFlags to alert_sender_new(). */ #define ALERT_IMMEDIATE_FAIL 0x0001 /* Call fossil_fatal() on any error */ #define ALERT_TRACE 0x0002 /* Log sending process on console */ #endif /* INTERFACE */ /* ** Shutdown an emailer. Clear all information other than the error message. */ static void emailerShutdown(AlertSender *p){ sqlite3_finalize(p->pStmt); p->pStmt = 0; sqlite3_close(p->db); p->db = 0; p->zDb = 0; p->zDir = 0; p->zCmd = 0; if( p->pSmtp ){ smtp_client_quit(p->pSmtp); smtp_session_free(p->pSmtp); p->pSmtp = 0; } blob_reset(&p->out); } /* ** Put the AlertSender into an error state. */ static void emailerError(AlertSender *p, const char *zFormat, ...){ va_list ap; fossil_free(p->zErr); va_start(ap, zFormat); p->zErr = vmprintf(zFormat, ap); va_end(ap); emailerShutdown(p); if( p->mFlags & ALERT_IMMEDIATE_FAIL ){ fossil_fatal("%s", p->zErr); } } /* ** Free an email sender object */ void alert_sender_free(AlertSender *p){ if( p ){ emailerShutdown(p); fossil_free(p->zErr); fossil_free(p); } } /* ** Get an email setting value. Report an error if not configured. ** Return 0 on success and one if there is an error. */ static int emailerGetSetting( AlertSender *p, /* Where to report the error */ const char **pzVal, /* Write the setting value here */ const char *zName /* Name of the setting */ ){ const char *z = db_get(zName, 0); int rc = 0; if( z==0 || z[0]==0 ){ emailerError(p, "missing \"%s\" setting", zName); rc = 1; }else{ *pzVal = z; } return rc; } /* ** Create a new AlertSender object. ** ** The method used for sending email is determined by various email-* ** settings, and especially email-send-method. The repository ** email-send-method can be overridden by the zAltDest argument to ** cause a different sending mechanism to be used. Pass "stdout" to ** zAltDest to cause all emails to be printed to the console for ** debugging purposes. ** ** The AlertSender object returned must be freed using alert_sender_free(). */ AlertSender *alert_sender_new(const char *zAltDest, u32 mFlags){ AlertSender *p; p = fossil_malloc(sizeof(*p)); memset(p, 0, sizeof(*p)); blob_init(&p->out, 0, 0); p->mFlags = mFlags; if( zAltDest ){ p->zDest = zAltDest; |
︙ | ︙ | |||
519 520 521 522 523 524 525 | }else if( fossil_strcmp(p->zDest, "blob")==0 ){ blob_init(&p->out, 0, 0); }else if( fossil_strcmp(p->zDest, "relay")==0 ){ const char *zRelay = 0; emailerGetSetting(p, &zRelay, "email-send-relayhost"); if( zRelay ){ u32 smtpFlags = SMTP_DIRECT; | | | 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 | }else if( fossil_strcmp(p->zDest, "blob")==0 ){ blob_init(&p->out, 0, 0); }else if( fossil_strcmp(p->zDest, "relay")==0 ){ const char *zRelay = 0; emailerGetSetting(p, &zRelay, "email-send-relayhost"); if( zRelay ){ u32 smtpFlags = SMTP_DIRECT; if( mFlags & ALERT_TRACE ) smtpFlags |= SMTP_TRACE_STDOUT; p->pSmtp = smtp_session_new(p->zFrom, zRelay, smtpFlags); smtp_client_startup(p->pSmtp); } } return p; } |
︙ | ︙ | |||
627 628 629 630 631 632 633 | /* ** Scan the input string for a valid email address enclosed in <...> ** If the string contains one or more email addresses, extract the first ** one into memory obtained from mprintf() and return a pointer to it. ** If no valid email address can be found, return NULL. */ | | | | | | | | | | 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 | /* ** Scan the input string for a valid email address enclosed in <...> ** If the string contains one or more email addresses, extract the first ** one into memory obtained from mprintf() and return a pointer to it. ** If no valid email address can be found, return NULL. */ char *alert_find_emailaddr(const char *zIn){ char *zOut = 0; while( zIn!=0 ){ zIn = (const char*)strchr(zIn, '<'); if( zIn==0 ) break; zIn++; zOut = email_copy_addr(zIn, '>'); if( zOut!=0 ) break; } return zOut; } /* ** SQL function: find_emailaddr(X) ** ** Return the first valid email address of the form <...> in input string ** X. Or return NULL if not found. */ void alert_find_emailaddr_func( sqlite3_context *context, int argc, sqlite3_value **argv ){ const char *zIn = (const char*)sqlite3_value_text(argv[0]); char *zOut = alert_find_emailaddr(zIn); if( zOut ){ sqlite3_result_text(context, zOut, -1, fossil_free); } } /* ** Return the hostname portion of an email address - the part following ** the @ */ char *alert_hostname(const char *zAddr){ char *z = strchr(zAddr, '@'); if( z ){ z++; }else{ z = (char*)zAddr; } return z; } /* ** Return a pointer to a fake email mailbox name that corresponds ** to human-readable name zFromName. The fake mailbox name is based ** on a hash. No huge problems arise if there is a hash collisions, ** but it is still better if collisions can be avoided. ** ** The returned string is held in a static buffer and is overwritten ** by each subsequent call to this routine. */ static char *alert_mailbox_name(const char *zFromName){ static char zHash[20]; unsigned int x = 0; int n = 0; while( zFromName[0] ){ n++; x = x*1103515245 + 12345 + ((unsigned char*)zFromName)[0]; zFromName++; } sqlite3_snprintf(sizeof(zHash), zHash, "noreply%x%08x", n, x); return zHash; } /* ** COMMAND: test-mailbox-hashname ** ** Usage: %fossil test-mailbox-hashname HUMAN-NAME ... ** ** Return the mailbox hash name corresponding to each human-readable ** name on the command line. This is a test interface for the ** alert_mailbox_name() function. */ void alert_test_mailbox_hashname(void){ int i; for(i=2; i<g.argc; i++){ fossil_print("%30s: %s\n", g.argv[i], alert_mailbox_name(g.argv[i])); } } /* ** Extract all To: header values from the email header supplied. ** Store them in the array list. */ |
︙ | ︙ | |||
777 778 779 780 781 782 783 | ** email address based on a hash of zFromName and the domain of email-self, ** and an additional "X-Fossil-From:" field is inserted with the email-self ** address. Downstream software might use the X-Fossil-From header to set ** the envelope-from address of the email. If zFromName is a NULL pointer, ** then the "From:" is set to the email-self value and X-Fossil-From is ** omitted. */ | | | | | | | 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 | ** email address based on a hash of zFromName and the domain of email-self, ** and an additional "X-Fossil-From:" field is inserted with the email-self ** address. Downstream software might use the X-Fossil-From header to set ** the envelope-from address of the email. If zFromName is a NULL pointer, ** then the "From:" is set to the email-self value and X-Fossil-From is ** omitted. */ void alert_send( AlertSender *p, /* Emailer context */ Blob *pHdr, /* Email header (incomplete) */ Blob *pBody, /* Email body */ const char *zFromName /* Optional human-readable name of sender */ ){ Blob all, *pOut; u64 r1, r2; if( p->mFlags & ALERT_TRACE ){ fossil_print("Sending email\n"); } if( fossil_strcmp(p->zDest, "off")==0 ){ return; } if( fossil_strcmp(p->zDest, "blob")==0 ){ pOut = &p->out; if( blob_size(pOut) ){ blob_appendf(pOut, "%.72c\n", '='); } }else{ blob_init(&all, 0, 0); pOut = &all; } blob_append(pOut, blob_buffer(pHdr), blob_size(pHdr)); if( zFromName ){ blob_appendf(pOut, "From: %s <%s@%s>\r\n", zFromName, alert_mailbox_name(zFromName), alert_hostname(p->zFrom)); blob_appendf(pOut, "X-Fossil-From: <%s>\r\n", p->zFrom); }else{ blob_appendf(pOut, "From: <%s>\r\n", p->zFrom); } blob_appendf(pOut, "Date: %z\r\n", cgi_rfc822_datestamp(time(0))); if( strstr(blob_str(pHdr), "\r\nMessage-Id:")==0 ){ /* Message-id format: "<$(date)x$(random)@$(from-host)>" where $(date) is ** the current unix-time in hex, $(random) is a 64-bit random number, ** and $(from) is the domain part of the email-self setting. */ sqlite3_randomness(sizeof(r1), &r1); r2 = time(0); blob_appendf(pOut, "Message-Id: <%llxx%016llx@%s>\r\n", r2, r1, alert_hostname(p->zFrom)); } blob_add_final_newline(pBody); blob_appendf(pOut, "MIME-Version: 1.0\r\n"); blob_appendf(pOut, "Content-Type: text/plain; charset=\"UTF-8\"\r\n"); #if 0 blob_appendf(pOut, "Content-Transfer-Encoding: base64\r\n\r\n"); append_base64(pOut, pBody); |
︙ | ︙ | |||
960 961 962 963 964 965 966 | ** --body FILENAME ** --smtp-trace ** --stdout ** --subject|-S SUBJECT ** ** unsubscribe EMAIL Remove a single subscriber with the given EMAIL. */ | | | | 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 | ** --body FILENAME ** --smtp-trace ** --stdout ** --subject|-S SUBJECT ** ** unsubscribe EMAIL Remove a single subscriber with the given EMAIL. */ void alert_cmd(void){ const char *zCmd; int nCmd; db_find_and_open_repository(0, 0); alert_schema(0); zCmd = g.argc>=3 ? g.argv[2] : "x"; nCmd = (int)strlen(zCmd); if( strncmp(zCmd, "pending", nCmd)==0 ){ Stmt q; verify_all_options(); if( g.argc!=3 ) usage("pending"); db_prepare(&q,"SELECT eventid, sentSep, sentDigest, sentMod" |
︙ | ︙ | |||
999 1000 1001 1002 1003 1004 1005 | "deleting all subscriber information. The information will be\n" "unrecoverable.\n"); prompt_user("Continue? (y/N) ", &yn); c = blob_str(&yn)[0]; blob_reset(&yn); } if( c=='y' ){ | | | | | | | 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 | "deleting all subscriber information. The information will be\n" "unrecoverable.\n"); prompt_user("Continue? (y/N) ", &yn); c = blob_str(&yn)[0]; blob_reset(&yn); } if( c=='y' ){ alert_triggers_disable(); db_multi_exec( "DROP TABLE IF EXISTS subscriber;\n" "DROP TABLE IF EXISTS pending_alert;\n" "DROP TABLE IF EXISTS alert_bounce;\n" /* Legacy */ "DROP TABLE IF EXISTS alert_pending;\n" "DROP TABLE IF EXISTS subscription;\n" ); alert_schema(0); } }else if( strncmp(zCmd, "send", nCmd)==0 ){ u32 eFlags = 0; if( find_option("digest",0,0)!=0 ) eFlags |= SENDALERT_DIGEST; if( find_option("test",0,0)!=0 ){ eFlags |= SENDALERT_PRESERVE|SENDALERT_STDOUT; } verify_all_options(); alert_send_alerts(eFlags); }else if( strncmp(zCmd, "settings", nCmd)==0 ){ int isGlobal = find_option("global",0,0)!=0; int nSetting; const Setting *pSetting = setting_info(&nSetting); db_open_config(1, 0); verify_all_options(); |
︙ | ︙ | |||
1090 1091 1092 1093 1094 1095 1096 | } db_finalize(&q); }else if( strncmp(zCmd, "test-message", nCmd)==0 ){ Blob prompt, body, hdr; const char *zDest = find_option("stdout",0,0)!=0 ? "stdout" : 0; int i; | | | | | | | | 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 | } db_finalize(&q); }else if( strncmp(zCmd, "test-message", nCmd)==0 ){ Blob prompt, body, hdr; const char *zDest = find_option("stdout",0,0)!=0 ? "stdout" : 0; int i; u32 mFlags = ALERT_IMMEDIATE_FAIL; const char *zSubject = find_option("subject", "S", 1); const char *zSource = find_option("body", 0, 1); AlertSender *pSender; if( find_option("smtp-trace",0,0)!=0 ) mFlags |= ALERT_TRACE; verify_all_options(); blob_init(&prompt, 0, 0); blob_init(&body, 0, 0); blob_init(&hdr, 0, 0); blob_appendf(&hdr,"To: "); for(i=3; i<g.argc; i++){ if( i>3 ) blob_append(&hdr, ", ", 2); blob_appendf(&hdr, "<%s>", g.argv[i]); } blob_append(&hdr,"\r\n",2); if( zSubject==0 ) zSubject = "fossil alerts test-message"; blob_appendf(&hdr, "Subject: %s\r\n", zSubject); if( zSource ){ blob_read_from_file(&body, zSource, ExtFILE); }else{ prompt_for_user_comment(&body, &prompt); } blob_add_final_newline(&body); pSender = alert_sender_new(zDest, mFlags); alert_send(pSender, &hdr, &body, 0); alert_sender_free(pSender); blob_reset(&hdr); blob_reset(&body); blob_reset(&prompt); }else if( strncmp(zCmd, "unsubscribe", nCmd)==0 ){ verify_all_options(); if( g.argc!=4 ) usage("unsubscribe EMAIL"); |
︙ | ︙ | |||
1230 1231 1232 1233 1234 1235 1236 | @ ; /* ** Append the text of an email confirmation message to the given ** Blob. The security code is in zCode. */ | | | > | | 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 | @ ; /* ** Append the text of an email confirmation message to the given ** Blob. The security code is in zCode. */ void alert_append_confirmation_message(Blob *pMsg, const char *zCode){ blob_appendf(pMsg, zConfirmMsg/*works-like:"%s%s%s"*/, g.zBaseURL, g.zBaseURL, zCode); } /* ** WEBPAGE: subscribe ** ** Allow users to subscribe to email notifications. ** ** This page is usually run by users who are not logged in. ** A logged-in user can add email notifications on the /alerts page. ** Access to this page by a logged in user (other than an ** administrator) results in a redirect to the /alerts page. ** ** Administrators can visit this page in order to sign up other ** users. ** ** The Alerts permission ("7") is required to access this ** page. To allow anonymous passers-by to sign up for email ** notification, set Email-Alerts on user "nobody" or "anonymous". */ void subscribe_page(void){ int needCaptcha; unsigned int uSeed; const char *zDecoded; char *zCaptcha = 0; char *zErr = 0; int eErr = 0; int di; if( alert_webpages_disabled() ) return; login_check_credentials(); if( !g.perm.EmailAlert ){ login_needed(g.anon.EmailAlert); return; } if( login_is_individual() && db_exists("SELECT 1 FROM subscriber WHERE suname=%Q",g.zLogin) |
︙ | ︙ | |||
1286 1287 1288 1289 1290 1291 1292 | }else{ /* Everybody else jumps to the page to administer their own ** account only. */ cgi_redirectf("%R/alerts"); return; } } | | | 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 | }else{ /* Everybody else jumps to the page to administer their own ** account only. */ cgi_redirectf("%R/alerts"); return; } } alert_submenu_common(); needCaptcha = !login_is_individual(); if( P("submit") && cgi_csrf_safe(1) && subscribe_error_check(&eErr,&zErr,needCaptcha) ){ /* A validated request for a new subscription has been received. */ char ssub[20]; |
︙ | ︙ | |||
1331 1332 1333 1334 1335 1336 1337 | ** No verification is required. Jump immediately to /alerts page. */ cgi_redirectf("%R/alerts/%s", zCode); return; }else{ /* We need to send a verification email */ Blob hdr, body; | | | | | | 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 | ** No verification is required. Jump immediately to /alerts page. */ cgi_redirectf("%R/alerts/%s", zCode); return; }else{ /* We need to send a verification email */ Blob hdr, body; AlertSender *pSender = alert_sender_new(0,0); blob_init(&hdr,0,0); blob_init(&body,0,0); blob_appendf(&hdr, "To: <%s>\n", zEAddr); blob_appendf(&hdr, "Subject: Subscription verification\n"); alert_append_confirmation_message(&body, zCode); alert_send(pSender, &hdr, &body, 0); style_header("Email Alert Verification"); if( pSender->zErr ){ @ <h1>Internal Error</h1> @ <p>The following internal error was encountered while trying @ to send the confirmation email: @ <blockquote><pre> @ %h(pSender->zErr) @ </pre></blockquote> }else{ @ <p>An email has been sent to "%h(zEAddr)". That email contains a @ hyperlink that you must click on in order to activate your @ subscription.</p> } alert_sender_free(pSender); style_footer(); } return; } style_header("Signup For Email Alerts"); if( P("submit")==0 ){ /* If this is the first visit to this page (if this HTTP request did not |
︙ | ︙ | |||
1374 1375 1376 1377 1378 1379 1380 1381 | @ <p>To receive email notifications for changes to this @ repository, fill out the form below and press "Submit" button.</p> form_begin(0, "%R/subscribe"); @ <table class="subscribe"> @ <tr> @ <td class="form_label">Email Address:</td> @ <td><input type="text" name="e" value="%h(PD("e",""))" size="30"></td> if( eErr==1 ){ | > | > | > | | > > > > | > | > > > > | < < | | | | 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 | @ <p>To receive email notifications for changes to this @ repository, fill out the form below and press "Submit" button.</p> form_begin(0, "%R/subscribe"); @ <table class="subscribe"> @ <tr> @ <td class="form_label">Email Address:</td> @ <td><input type="text" name="e" value="%h(PD("e",""))" size="30"></td> @ <tr> if( eErr==1 ){ @ <tr><td><td><span class='loginError'>↑ %h(zErr)</span></td></tr> } @ </tr> if( needCaptcha ){ uSeed = captcha_seed(); zDecoded = captcha_decode(uSeed); zCaptcha = captcha_render(zDecoded); @ <tr> @ <td class="form_label">Security Code:</td> @ <td><input type="text" name="captcha" value="" size="30"> @ <input type="hidden" name="captchaseed" value="%u(uSeed)"></td> @ </tr> if( eErr==2 ){ @ <tr><td><td><span class='loginError'>↑ %h(zErr)</span></td></tr> } @ </tr> } if( g.perm.Admin ){ @ <tr> @ <td class="form_label">User:</td> @ <td><input type="text" name="suname" value="%h(PD("suname",g.zLogin))" \ @ size="30"></td> @ </tr> if( eErr==3 ){ @ <tr><td><td><span class='loginError'>↑ %h(zErr)</span></td></tr> } @ </tr> } @ <tr> @ <td class="form_label">Topics:</td> @ <td><label><input type="checkbox" name="sa" %s(PCK("sa"))> \ @ Announcements</label><br> if( g.perm.Read ){ @ <label><input type="checkbox" name="sc" %s(PCK("sc"))> \ @ Check-ins</label><br> } if( g.perm.RdForum ){ @ <label><input type="checkbox" name="sf" %s(PCK("sf"))> \ @ Forum Posts</label><br> } if( g.perm.RdTkt ){ @ <label><input type="checkbox" name="st" %s(PCK("st"))> \ @ Ticket changes</label><br> } if( g.perm.RdWiki ){ @ <label><input type="checkbox" name="sw" %s(PCK("sw"))> \ @ Wiki</label><br> } di = PB("di"); @ </td></tr> @ <tr> @ <td class="form_label">Delivery:</td> @ <td><select size="1" name="di"> @ <option value="0" %s(di?"":"selected")>Individual Emails</option> @ <option value="1" %s(di?"selected":"")>Daily Digest</option> @ </select></td> @ </tr> if( g.perm.Admin ){ @ <tr> @ <td class="form_label">Admin Options:</td><td> @ <label><input type="checkbox" name="vi" %s(PCK("vi"))> \ @ Verified</label><br> @ <label><input type="checkbox" name="dnc" %s(PCK("dnc"))> \ @ Do not call</label></td></tr> } @ <tr> @ <td></td> if( needCaptcha && !alert_enabled() ){ @ <td><input type="submit" name="submit" value="Submit" disabled> @ (Email current disabled)</td> }else{ @ <td><input type="submit" name="submit" value="Submit"></td> } @ </tr> @ </table> if( needCaptcha ){ @ <div class="captcha"><table class="captcha"><tr><td><pre class="captcha"> @ %h(zCaptcha) @ </pre> @ Enter the 8 characters above in the "Security Code" box @ </td></tr></table></div> } @ </form> fossil_free(zErr); style_footer(); } /* ** Either shutdown or completely delete a subscription entry given ** by the hex value zName. Then paint a webpage that explains that ** the entry has been removed. */ static void alert_unsubscribe(const char *zName){ char *zEmail; zEmail = db_text(0, "SELECT semail FROM subscriber" " WHERE subscriberCode=hextoblob(%Q)", zName); if( zEmail==0 ){ style_header("Unsubscribe Fail"); @ <p>Unable to locate a subscriber with the requested key</p> }else{ |
︙ | ︙ | |||
1492 1493 1494 1495 1496 1497 1498 | ** (1) The name= query parameter contains the subscriberCode. ** ** (2) The user is logged into an account other than "nobody" or ** "anonymous". In that case the notification settings ** associated with that account can be edited without needing ** to know the subscriber code. */ | | | > > > > | | 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 | ** (1) The name= query parameter contains the subscriberCode. ** ** (2) The user is logged into an account other than "nobody" or ** "anonymous". In that case the notification settings ** associated with that account can be edited without needing ** to know the subscriber code. */ void alert_page(void){ const char *zName = P("name"); Stmt q; int sa, sc, sf, st, sw; int sdigest, sdonotcall, sverified; const char *ssub; const char *semail; const char *smip; const char *suname; const char *mtime; const char *sctime; int eErr = 0; char *zErr = 0; if( alert_webpages_disabled() ) return; login_check_credentials(); if( !g.perm.EmailAlert ){ login_needed(g.anon.EmailAlert); return; } if( zName==0 && login_is_individual() ){ zName = db_text(0, "SELECT hex(subscriberCode) FROM subscriber" " WHERE suname=%Q", g.zLogin); } if( zName==0 || !validate16(zName, -1) ){ cgi_redirect("subscribe"); return; } alert_submenu_common(); if( P("submit")!=0 && cgi_csrf_safe(1) ){ int sdonotcall = PB("sdonotcall"); int sdigest = PB("sdigest"); char ssub[10]; int nsub = 0; if( PB("sa") ) ssub[nsub++] = 'a'; if( g.perm.Read && PB("sc") ) ssub[nsub++] = 'c'; |
︙ | ︙ | |||
1570 1571 1572 1573 1574 1575 1576 | zName ); } } if( P("delete")!=0 && cgi_csrf_safe(1) ){ if( !PB("dodelete") ){ eErr = 9; | | | | 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 | zName ); } } if( P("delete")!=0 && cgi_csrf_safe(1) ){ if( !PB("dodelete") ){ eErr = 9; zErr = mprintf("Select this checkbox and press \"Unsubscribe\" again to" " unsubscribe"); }else{ alert_unsubscribe(zName); return; } } db_prepare(&q, "SELECT" " semail," /* 0 */ " sverified," /* 1 */ |
︙ | ︙ | |||
1648 1649 1650 1651 1652 1653 1654 | @ <tr> @ <td class="form_label">User:</td> @ <td><input type="text" name="suname" value="%h(suname?suname:"")" \ @ size="30"></td> @ </tr> } @ <tr> | | | > > > > > > > > > > > > | > > > | | < | < < | > | 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 | @ <tr> @ <td class="form_label">User:</td> @ <td><input type="text" name="suname" value="%h(suname?suname:"")" \ @ size="30"></td> @ </tr> } @ <tr> @ <td class="form_label">Topics:</td> @ <td><label><input type="checkbox" name="sa" %s(sa?"checked":"")>\ @ Announcements</label><br> if( g.perm.Read ){ @ <label><input type="checkbox" name="sc" %s(sc?"checked":"")>\ @ Check-ins</label><br> } if( g.perm.RdForum ){ @ <label><input type="checkbox" name="sf" %s(sf?"checked":"")>\ @ Forum Posts</label><br> } if( g.perm.RdTkt ){ @ <label><input type="checkbox" name="st" %s(st?"checked":"")>\ @ Ticket changes</label><br> } if( g.perm.RdWiki ){ @ <label><input type="checkbox" name="sw" %s(sw?"checked":"")>\ @ Wiki</label> } @ </td></tr> @ <tr> @ <td class="form_label">Delivery:</td> @ <td><select size="1" name="sdigest"> @ <option value="0" %s(sdigest?"":"selected")>Individual Emails</option> @ <option value="1" %s(sdigest?"selected":"")>Daily Digest</option> @ </select></td> @ </tr> #if 0 @ <label><input type="checkbox" name="sdigest" %s(sdigest?"checked":"")>\ @ Daily digest only</label><br> #endif if( g.perm.Admin ){ @ <tr> @ <td class="form_label">Admin Options:</td><td> @ <label><input type="checkbox" name="sdonotcall" \ @ %s(sdonotcall?"checked":"")> Do not call</label><br> @ <label><input type="checkbox" name="sverified" \ @ %s(sverified?"checked":"")>\ @ Verified</label></td></tr> } if( eErr==9 ){ @ <tr> @ <td class="form_label">Verify:</td><td> @ <label><input type="checkbox" name="dodelete"> @ Unsubscribe</label> @ <span class="loginError">← %h(zErr)</span> @ </td></tr> } @ <tr> @ <td></td> @ <td><input type="submit" name="submit" value="Submit"> @ <input type="submit" name="delete" value="Unsubscribe"> @ </tr> @ </table> @ </form> |
︙ | ︙ | |||
1741 1742 1743 1744 1745 1746 1747 | /* If a valid subscriber code is supplied, then unsubscribe immediately. */ if( zName && db_exists("SELECT 1 FROM subscriber WHERE subscriberCode=hextoblob(%Q)", zName) ){ | | | 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 | /* If a valid subscriber code is supplied, then unsubscribe immediately. */ if( zName && db_exists("SELECT 1 FROM subscriber WHERE subscriberCode=hextoblob(%Q)", zName) ){ alert_unsubscribe(zName); return; } /* Logged in users are redirected to the /alerts page */ login_check_credentials(); if( login_is_individual() ){ cgi_redirectf("%R/alerts"); |
︙ | ︙ | |||
1775 1776 1777 1778 1779 1780 1781 | bSubmit = 0; } } if( bSubmit ){ /* If we get this far, it means that a valid unsubscribe request has ** been submitted. Send the appropriate email. */ Blob hdr, body; | | | | | 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 | bSubmit = 0; } } if( bSubmit ){ /* If we get this far, it means that a valid unsubscribe request has ** been submitted. Send the appropriate email. */ Blob hdr, body; AlertSender *pSender = alert_sender_new(0,0); blob_init(&hdr,0,0); blob_init(&body,0,0); blob_appendf(&hdr, "To: <%s>\r\n", zEAddr); blob_appendf(&hdr, "Subject: Unsubscribe Instructions\r\n"); blob_appendf(&body, zUnsubMsg/*works-like:"%s%s%s%s%s%s"*/, g.zBaseURL, g.zBaseURL, zCode, g.zBaseURL, g.zBaseURL, zCode); alert_send(pSender, &hdr, &body, 0); style_header("Unsubscribe Instructions Sent"); if( pSender->zErr ){ @ <h1>Internal Error</h1> @ <p>The following error was encountered while trying to send an @ email to %h(zEAddr): @ <blockquote><pre> @ %h(pSender->zErr) @ </pre></blockquote> }else{ @ <p>An email has been sent to "%h(zEAddr)" that explains how to @ unsubscribe and/or modify your subscription settings</p> } alert_sender_free(pSender); style_footer(); return; } /* Non-logged-in users have to enter an email address to which is ** sent a message containing the unsubscribe link. */ |
︙ | ︙ | |||
1838 1839 1840 1841 1842 1843 1844 | @ <label><input type="radio" name="dx" value="1" %s(dx?"checked":"")>\ @ Completely unsubscribe</label><br> @ <tr> @ <td></td> @ <td><input type="submit" name="submit" value="Submit"></td> @ </tr> @ </table> | | | 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 | @ <label><input type="radio" name="dx" value="1" %s(dx?"checked":"")>\ @ Completely unsubscribe</label><br> @ <tr> @ <td></td> @ <td><input type="submit" name="submit" value="Submit"></td> @ </tr> @ </table> @ <div class="captcha"><table class="captcha"><tr><td><pre class="captcha"> @ %h(zCaptcha) @ </pre> @ Enter the 8 characters above in the "Security Code" box @ </td></tr></table></div> @ </form> fossil_free(zErr); style_footer(); |
︙ | ︙ | |||
1861 1862 1863 1864 1865 1866 1867 | ** for that email where the delivery settings can be ** modified. */ void subscriber_list_page(void){ Blob sql; Stmt q; sqlite3_int64 iNow; | | | | 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 | ** for that email where the delivery settings can be ** modified. */ void subscriber_list_page(void){ Blob sql; Stmt q; sqlite3_int64 iNow; if( alert_webpages_disabled() ) return; login_check_credentials(); if( !g.perm.Admin ){ login_needed(0); return; } alert_submenu_common(); style_header("Subscriber List"); blob_init(&sql, 0, 0); blob_append_sql(&sql, "SELECT hex(subscriberCode)," /* 0 */ " semail," /* 1 */ " ssub," /* 2 */ " suname," /* 3 */ |
︙ | ︙ | |||
1939 1940 1941 1942 1943 1944 1945 | EmailEvent *pNext; /* Next in chronological order */ }; #endif /* ** Free a linked list of EmailEvent objects */ | | | | 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 | EmailEvent *pNext; /* Next in chronological order */ }; #endif /* ** Free a linked list of EmailEvent objects */ void alert_free_eventlist(EmailEvent *p){ while( p ){ EmailEvent *pNext = p->pNext; blob_reset(&p->txt); blob_reset(&p->hdr); fossil_free(p->zFromName); fossil_free(p); p = pNext; } } /* ** Compute and return a linked list of EmailEvent objects ** corresponding to the current content of the temp.wantalert ** table which should be defined as follows: ** ** CREATE TEMP TABLE wantalert(eventId TEXT, needMod BOOLEAN); */ EmailEvent *alert_compute_event_text(int *pnEvent, int doDigest){ Stmt q; EmailEvent *p; EmailEvent anchor; EmailEvent *pLast; const char *zUrl = db_get("email-url","http://localhost:8080"); const char *zFrom; const char *zSub; |
︙ | ︙ | |||
2082 2083 2084 2085 2086 2087 2088 | zTitle = db_column_text(&q, 3); if( p->needMod ){ blob_appendf(&p->hdr, "Subject: %s Pending Moderation: %s\r\n", zSub, zTitle); }else{ blob_appendf(&p->hdr, "Subject: %s %s\r\n", zSub, zTitle); blob_appendf(&p->hdr, "Message-Id: <%.32s@%s>\r\n", | | | | 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 | zTitle = db_column_text(&q, 3); if( p->needMod ){ blob_appendf(&p->hdr, "Subject: %s Pending Moderation: %s\r\n", zSub, zTitle); }else{ blob_appendf(&p->hdr, "Subject: %s %s\r\n", zSub, zTitle); blob_appendf(&p->hdr, "Message-Id: <%.32s@%s>\r\n", zUuid, alert_hostname(zFrom)); zIrt = db_column_text(&q, 4); if( zIrt && zIrt[0] ){ blob_appendf(&p->hdr, "In-Reply-To: <%.32s@%s>\r\n", zIrt, alert_hostname(zFrom)); } } blob_init(&p->txt, 0, 0); if( p->needMod ){ blob_appendf(&p->txt, "** Pending moderator approval (%s/modreq) **\n", zUrl |
︙ | ︙ | |||
2124 2125 2126 2127 2128 2129 2130 | db_get("email-url","http://localhost:8080")); } /* ** Append the "unsubscribe" notification and other footer text to ** the end of an email alert being assemblied in pOut. */ | | | 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 | db_get("email-url","http://localhost:8080")); } /* ** Append the "unsubscribe" notification and other footer text to ** the end of an email alert being assemblied in pOut. */ void alert_footer(Blob *pOut){ blob_appendf(pOut, "\n-- \nTo unsubscribe: %s/unsubscribe\n", db_get("email-url","http://localhost:8080")); } /* ** COMMAND: test-alert ** |
︙ | ︙ | |||
2159 2160 2161 2162 2163 2164 2165 | EmailEvent *pEvent, *p; doDigest = find_option("digest",0,0)!=0; needMod = find_option("needmod",0,0)!=0; db_find_and_open_repository(0, 0); verify_all_options(); db_begin_transaction(); | | | | | | 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 | EmailEvent *pEvent, *p; doDigest = find_option("digest",0,0)!=0; needMod = find_option("needmod",0,0)!=0; db_find_and_open_repository(0, 0); verify_all_options(); db_begin_transaction(); alert_schema(0); db_multi_exec("CREATE TEMP TABLE wantalert(eventid TEXT, needMod BOOLEAN)"); if( g.argc==2 ){ db_multi_exec( "INSERT INTO wantalert(eventId,needMod)" " SELECT eventid, %d FROM pending_alert", needMod); }else{ int i; for(i=2; i<g.argc; i++){ db_multi_exec("INSERT INTO wantalert(eventId,needMod) VALUES(%Q,%d)", g.argv[i], needMod); } } blob_init(&out, 0, 0); email_header(&out); pEvent = alert_compute_event_text(&nEvent, doDigest); for(p=pEvent; p; p=p->pNext){ blob_append(&out, "\n", 1); if( blob_size(&p->hdr) ){ blob_append(&out, blob_buffer(&p->hdr), blob_size(&p->hdr)); blob_append(&out, "\n", 1); } blob_append(&out, blob_buffer(&p->txt), blob_size(&p->txt)); } alert_free_eventlist(pEvent); alert_footer(&out); fossil_print("%s", blob_str(&out)); blob_reset(&out); db_end_transaction(0); } /* ** COMMAND: test-add-alerts |
︙ | ︙ | |||
2206 2207 2208 2209 2210 2211 2212 | ** EVENTIDs are text. The first character is 'c', 'f', 't', or 'w' ** for check-in, forum, ticket, or wiki. The remaining text is a ** integer that references the EVENT.OBJID value for the event. ** Run /timeline?showid to see these OBJID values. ** ** Options: ** | | | 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 | ** EVENTIDs are text. The first character is 'c', 'f', 't', or 'w' ** for check-in, forum, ticket, or wiki. The remaining text is a ** integer that references the EVENT.OBJID value for the event. ** Run /timeline?showid to see these OBJID values. ** ** Options: ** ** --backoffice Run alert_backoffice() after all alerts have ** been added. This will cause the alerts to be ** sent out with the SENDALERT_TRACE option. ** ** --debug Like --backoffice, but add the SENDALERT_STDOUT ** so that emails are printed to standard output ** rather than being sent. ** |
︙ | ︙ | |||
2230 2231 2232 2233 2234 2235 2236 | } if( find_option("digest",0,0)!=0 ){ mFlags |= SENDALERT_DIGEST; } db_find_and_open_repository(0, 0); verify_all_options(); db_begin_write(); | | | | | 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 | } if( find_option("digest",0,0)!=0 ){ mFlags |= SENDALERT_DIGEST; } db_find_and_open_repository(0, 0); verify_all_options(); db_begin_write(); alert_schema(0); for(i=2; i<g.argc; i++){ db_multi_exec("REPLACE INTO pending_alert(eventId) VALUES(%Q)", g.argv[i]); } db_end_transaction(0); if( doAuto ){ alert_backoffice(SENDALERT_TRACE|mFlags); } } #if INTERFACE /* ** Flags for alert_send_alerts() */ #define SENDALERT_DIGEST 0x0001 /* Send a digest */ #define SENDALERT_PRESERVE 0x0002 /* Do not mark the task as done */ #define SENDALERT_STDOUT 0x0004 /* Print emails instead of sending */ #define SENDALERT_TRACE 0x0008 /* Trace operation for debugging */ #endif /* INTERFACE */ |
︙ | ︙ | |||
2266 2267 2268 2269 2270 2271 2272 | ** ** (1) Create a TEMP table wantalert(eventId,needMod) and fill it with ** all the events that we want to send alerts about. The needMod ** flags is set if and only if the event is still awaiting ** moderator approval. Events with the needMod flag are only ** shown to users that have moderator privileges. ** | | | | | | | | | | | | | 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 | ** ** (1) Create a TEMP table wantalert(eventId,needMod) and fill it with ** all the events that we want to send alerts about. The needMod ** flags is set if and only if the event is still awaiting ** moderator approval. Events with the needMod flag are only ** shown to users that have moderator privileges. ** ** (2) Call alert_compute_event_text() to compute a list of EmailEvent ** objects that describe all events about which we want to send ** alerts. ** ** (3) Loop over all subscribers. Compose and send one or more email ** messages to each subscriber that describe the events for ** which the subscriber has expressed interest and has ** appropriate privileges. ** ** (4) Update the pending_alerts table to indicate that alerts have been ** sent. ** ** Update 2018-08-09: Do step (3) before step (4). Update the ** pending_alerts table *before* the emails are sent. That way, if ** the process malfunctions or crashes, some notifications may never ** be sent. But that is better than some recurring bug causing ** subscribers to be flooded with repeated notifications every 60 ** seconds! */ void alert_send_alerts(u32 flags){ EmailEvent *pEvents, *p; int nEvent = 0; Stmt q; const char *zDigest = "false"; Blob hdr, body; const char *zUrl; const char *zRepoName; const char *zFrom; const char *zDest = (flags & SENDALERT_STDOUT) ? "stdout" : 0; AlertSender *pSender = 0; u32 senderFlags = 0; if( g.fSqlTrace ) fossil_trace("-- BEGIN alert_send_alerts(%u)\n", flags); alert_schema(0); if( !alert_enabled() ) goto send_alert_done; zUrl = db_get("email-url",0); if( zUrl==0 ) goto send_alert_done; zRepoName = db_get("email-subname",0); if( zRepoName==0 ) goto send_alert_done; zFrom = db_get("email-self",0); if( zFrom==0 ) goto send_alert_done; if( flags & SENDALERT_TRACE ){ senderFlags |= ALERT_TRACE; } pSender = alert_sender_new(zDest, senderFlags); /* Step (1): Compute the alerts that need sending */ db_multi_exec( "DROP TABLE IF EXISTS temp.wantalert;" "CREATE TEMP TABLE wantalert(eventId TEXT, needMod BOOLEAN, sentMod);" ); |
︙ | ︙ | |||
2345 2346 2347 2348 2349 2350 2351 | "DELETE FROM wantalert WHERE needMod AND sentMod;" ); } /* Step 2: compute EmailEvent objects for every notification that ** needs sending. */ | | | | 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 | "DELETE FROM wantalert WHERE needMod AND sentMod;" ); } /* Step 2: compute EmailEvent objects for every notification that ** needs sending. */ pEvents = alert_compute_event_text(&nEvent, (flags & SENDALERT_DIGEST)!=0); if( nEvent==0 ) goto send_alert_done; /* Step 4a: Update the pending_alerts table to designate the ** alerts as having all been sent. This is done *before* step (3) ** so that a crash will not cause alerts to be sent multiple times. ** Better a missed alert than being spammed with hundreds of alerts ** due to a bug. */ |
︙ | ︙ | |||
2427 2428 2429 2430 2431 2432 2433 | Blob fhdr, fbody; blob_init(&fhdr, 0, 0); blob_appendf(&fhdr, "To: <%s>\r\n", zEmail); blob_append(&fhdr, blob_buffer(&p->hdr), blob_size(&p->hdr)); blob_init(&fbody, blob_buffer(&p->txt), blob_size(&p->txt)); blob_appendf(&fbody, "\n-- \nSubscription info: %s/alerts/%s\n", zUrl, zCode); | | | 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 | Blob fhdr, fbody; blob_init(&fhdr, 0, 0); blob_appendf(&fhdr, "To: <%s>\r\n", zEmail); blob_append(&fhdr, blob_buffer(&p->hdr), blob_size(&p->hdr)); blob_init(&fbody, blob_buffer(&p->txt), blob_size(&p->txt)); blob_appendf(&fbody, "\n-- \nSubscription info: %s/alerts/%s\n", zUrl, zCode); alert_send(pSender,&fhdr,&fbody,p->zFromName); blob_reset(&fhdr); blob_reset(&fbody); }else{ /* Events other than forum posts are gathered together into ** a single email message */ if( nHit==0 ){ blob_appendf(&hdr,"To: <%s>\r\n", zEmail); |
︙ | ︙ | |||
2450 2451 2452 2453 2454 2455 2456 | blob_append(&body, "\n", 1); blob_append(&body, blob_buffer(&p->txt), blob_size(&p->txt)); } } if( nHit==0 ) continue; blob_appendf(&body,"\n-- \nSubscription info: %s/alerts/%s\n", zUrl, zCode); | | | | | | | | | | | 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 | blob_append(&body, "\n", 1); blob_append(&body, blob_buffer(&p->txt), blob_size(&p->txt)); } } if( nHit==0 ) continue; blob_appendf(&body,"\n-- \nSubscription info: %s/alerts/%s\n", zUrl, zCode); alert_send(pSender,&hdr,&body,0); blob_truncate(&hdr, 0); blob_truncate(&body, 0); } blob_reset(&hdr); blob_reset(&body); db_finalize(&q); alert_free_eventlist(pEvents); /* Step 4b: Update the pending_alerts table to remove all of the ** alerts that have been completely sent. */ db_multi_exec("DELETE FROM pending_alert WHERE sentDigest AND sentSep;"); send_alert_done: alert_sender_free(pSender); if( g.fSqlTrace ) fossil_trace("-- END alert_send_alerts(%u)\n", flags); } /* ** Do backoffice processing for email notifications. In other words, ** check to see if any email notifications need to occur, and then ** do them. ** ** This routine is intended to run in the background, after webpages. ** ** The mFlags option is zero or more of the SENDALERT_* flags. Normally ** this flag is zero, but the test-set-alert command sets it to ** SENDALERT_TRACE. */ void alert_backoffice(u32 mFlags){ int iJulianDay; if( !alert_tables_exist() ) return; alert_send_alerts(mFlags); iJulianDay = db_int(0, "SELECT julianday('now')"); if( iJulianDay>db_get_int("email-last-digest",0) ){ db_set_int("email-last-digest",iJulianDay,0); alert_send_alerts(SENDALERT_DIGEST|mFlags); } } /* ** WEBPAGE: contact_admin ** ** A web-form to send an email message to the repository administrator, |
︙ | ︙ | |||
2518 2519 2520 2521 2522 2523 2524 | && P("subject")!=0 && P("msg")!=0 && P("from")!=0 && cgi_csrf_safe(1) && captcha_is_correct(0) ){ Blob hdr, body; | | | | | 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 | && P("subject")!=0 && P("msg")!=0 && P("from")!=0 && cgi_csrf_safe(1) && captcha_is_correct(0) ){ Blob hdr, body; AlertSender *pSender = alert_sender_new(0,0); blob_init(&hdr, 0, 0); blob_appendf(&hdr, "To: <%s>\r\nSubject: %s administrator message\r\n", zAdminEmail, db_get("email-subname","Fossil Repo")); blob_init(&body, 0, 0); blob_appendf(&body, "Message from [%s]\n", PT("from")/*safe-for-%s*/); blob_appendf(&body, "Subject: [%s]\n\n", PT("subject")/*safe-for-%s*/); blob_appendf(&body, "%s", PT("msg")/*safe-for-%s*/); alert_send(pSender, &hdr, &body, 0); style_header("Message Sent"); if( pSender->zErr ){ @ <h1>Internal Error</h1> @ <p>The following error was reported by the system: @ <blockquote><pre> @ %h(pSender->zErr) @ </pre></blockquote> }else{ @ <p>Your message has been sent to the repository administrator. @ Thank you for your input.</p> } alert_sender_free(pSender); style_footer(); return; } if( captcha_needed() ){ uSeed = captcha_seed(); zDecoded = captcha_decode(uSeed); zCaptcha = captcha_render(zDecoded); |
︙ | ︙ | |||
2578 2579 2580 2581 2582 2583 2584 | @ </tr> @ <tr> @ <td></td> @ <td><input type="submit" name="submit" value="Send Message"> @ </tr> @ </table> if( zCaptcha ){ | | | | | | | | | 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 | @ </tr> @ <tr> @ <td></td> @ <td><input type="submit" name="submit" value="Send Message"> @ </tr> @ </table> if( zCaptcha ){ @ <div class="captcha"><table class="captcha"><tr><td><pre class="captcha"> @ %h(zCaptcha) @ </pre> @ Enter the 8 characters above in the "Security Code" box @ </td></tr></table></div> } @ </form> style_footer(); } /* ** Send an annoucement message described by query parameter. ** Permission to do this has already been verified. */ static char *alert_send_announcement(void){ AlertSender *pSender; char *zErr; const char *zTo = PT("to"); char *zSubject = PT("subject"); int bAll = PB("all"); int bAA = PB("aa"); const char *zSub = db_get("email-subname", "[Fossil Repo]"); int bTest2 = fossil_strcmp(P("name"),"test2")==0; Blob hdr, body; blob_init(&body, 0, 0); blob_init(&hdr, 0, 0); blob_appendf(&body, "%s", PT("msg")/*safe-for-%s*/); pSender = alert_sender_new(bTest2 ? "blob" : 0, 0); if( zTo[0] ){ blob_appendf(&hdr, "To: <%s>\r\nSubject: %s %s\r\n", zTo, zSub, zSubject); alert_send(pSender, &hdr, &body, 0); } if( bAll || bAA ){ Stmt q; int nUsed = blob_size(&body); const char *zURL = db_get("email-url",0); db_prepare(&q, "SELECT semail, hex(subscriberCode) FROM subscriber " " WHERE sverified AND NOT sdonotcall %s", bAll ? "" : " AND ssub LIKE '%a%'"); while( db_step(&q)==SQLITE_ROW ){ const char *zCode = db_column_text(&q, 1); zTo = db_column_text(&q, 0); blob_truncate(&hdr, 0); blob_appendf(&hdr, "To: <%s>\r\nSubject: %s %s\r\n", zTo, zSub, zSubject); if( zURL ){ blob_truncate(&body, nUsed); blob_appendf(&body,"\n-- \nSubscription info: %s/alerts/%s\n", zURL, zCode); } alert_send(pSender, &hdr, &body, 0); } db_finalize(&q); } if( bTest2 ){ /* If the URL is /announce/test2 instead of just /announce, then no ** email is actually sent. Instead, the text of the email that would ** have been sent is displayed in the result window. */ @ <pre style='border: 2px solid blue; padding: 1ex'> @ %h(blob_str(&pSender->out)) @ </pre> } zErr = pSender->zErr; pSender->zErr = 0; alert_sender_free(pSender); return zErr; } /* ** WEBPAGE: announce ** |
︙ | ︙ | |||
2669 2670 2671 2672 2673 2674 2675 | if( fossil_strcmp(P("name"),"test1")==0 ){ /* Visit the /announce/test1 page to see the CGI variables */ @ <p style='border: 1px solid black; padding: 1ex;'> cgi_print_all(0, 0); @ </p> }else if( P("submit")!=0 && cgi_csrf_safe(1) ){ | | | 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 | if( fossil_strcmp(P("name"),"test1")==0 ){ /* Visit the /announce/test1 page to see the CGI variables */ @ <p style='border: 1px solid black; padding: 1ex;'> cgi_print_all(0, 0); @ </p> }else if( P("submit")!=0 && cgi_csrf_safe(1) ){ char *zErr = alert_send_announcement(); style_header("Announcement Sent"); if( zErr ){ @ <h1>Internal Error</h1> @ <p>The following error was reported by the system: @ <blockquote><pre> @ %h(zErr) @ </pre></blockquote> |
︙ | ︙ |
Changes to src/backoffice.c.
︙ | ︙ | |||
517 518 519 520 521 522 523 | char *zDate = db_text(0, "SELECT datetime('now');"); fprintf(pLog, "%s (%d) backoffice running\n", zDate, GETPID()); fclose(pLog); } } /* Here is where the actual work of the backoffice happens */ | | | 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 | char *zDate = db_text(0, "SELECT datetime('now');"); fprintf(pLog, "%s (%d) backoffice running\n", zDate, GETPID()); fclose(pLog); } } /* Here is where the actual work of the backoffice happens */ alert_backoffice(0); smtp_cleanup(); } /* ** COMMAND: backoffice ** ** Usage: backoffice [-R repository] |
︙ | ︙ |
Changes to src/browse.c.
︙ | ︙ | |||
119 120 121 122 123 124 125 126 127 128 129 130 131 132 | ** type=TYPE TYPE=flat: use this display ** TYPE=tree: use the /tree display instead */ void page_dir(void){ char *zD = fossil_strdup(P("name")); int nD = zD ? strlen(zD)+1 : 0; int mxLen; char *zPrefix; Stmt q; const char *zCI = P("ci"); int rid = 0; char *zUuid = 0; Blob dirname; Manifest *pM = 0; | > | 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | ** type=TYPE TYPE=flat: use this display ** TYPE=tree: use the /tree display instead */ void page_dir(void){ char *zD = fossil_strdup(P("name")); int nD = zD ? strlen(zD)+1 : 0; int mxLen; int n; char *zPrefix; Stmt q; const char *zCI = P("ci"); int rid = 0; char *zUuid = 0; Blob dirname; Manifest *pM = 0; |
︙ | ︙ | |||
265 266 267 268 269 270 271 272 273 | ); } /* Generate a multi-column table listing the contents of zD[] ** directory. */ mxLen = db_int(12, "SELECT max(length(x)) FROM localfiles /*scan*/"); if( mxLen<12 ) mxLen = 12; db_prepare(&q, "SELECT x, u FROM localfiles ORDER BY x /*scan*/"); | > > | | 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 | ); } /* Generate a multi-column table listing the contents of zD[] ** directory. */ mxLen = db_int(12, "SELECT max(length(x)) FROM localfiles /*scan*/"); n = db_int(1,"SELECT count(*) FROM localfiles; /*scan*/"); if( mxLen<12 ) mxLen = 12; mxLen += (mxLen+9)/10; db_prepare(&q, "SELECT x, u FROM localfiles ORDER BY x /*scan*/"); @ <div class="columns" style="columns: %d(mxLen)ex %d(n);"> @ <ul class="browser"> while( db_step(&q)==SQLITE_ROW ){ const char *zFN; zFN = db_column_text(&q, 0); if( zFN[0]=='/' ){ zFN++; @ <li class="dir">%z(href("%s%T",zSubdirLink,zFN))%h(zFN)</a></li> |
︙ | ︙ |
Changes to src/capabilities.c.
︙ | ︙ | |||
203 204 205 206 207 208 209 210 211 212 213 214 | if( zIn==0 ) zIn = ""; p = capability_add(0, zIn); capability_expand(p); zOut = capability_string(p); sqlite3_result_text(context, zOut, -1, fossil_free); capability_free(p); } /* ** Generate HTML that lists all of the capability letters together with ** a brief summary of what each letter means. */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | | | < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < > | 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 | if( zIn==0 ) zIn = ""; p = capability_add(0, zIn); capability_expand(p); zOut = capability_string(p); sqlite3_result_text(context, zOut, -1, fossil_free); capability_free(p); } #if INTERFACE /* ** Capabilities are grouped into "classes" as follows: */ #define CAPCLASS_CODE 0x0001 #define CAPCLASS_WIKI 0x0002 #define CAPCLASS_TKT 0x0004 #define CAPCLASS_FORUM 0x0008 #define CAPCLASS_DATA 0x0010 #define CAPCLASS_ALERT 0x0020 #define CAPCLASS_OTHER 0x0040 #define CAPCLASS_SUPER 0x0080 #define CAPCLASS_ALL 0xffff #endif /* INTERFACE */ /* ** The following structure holds descriptions of the various capabilities. */ static struct Caps { char cCap; /* The capability letter */ unsigned short eClass; /* The "class" for this capability */ char *zAbbrev; /* Abbreviated mnemonic name */ char *zOneLiner; /* One-line summary */ } aCap[] = { { 'a', CAPCLASS_SUPER, "Admin", "Create and delete users" }, { 'b', CAPCLASS_WIKI|CAPCLASS_TKT, "Attach", "Add attchments to wiki or tickets" }, { 'c', CAPCLASS_TKT, "Append-Tkt", "Append to existing tickets" }, { 'd', CAPCLASS_WIKI|CAPCLASS_TKT, "Delete", "Delete wiki or tickets" }, { 'e', CAPCLASS_DATA, "View-PII", "View sensitive info such as email addresses" }, { 'f', CAPCLASS_WIKI, "New-Wiki", "Create new wiki pages" }, { 'g', CAPCLASS_DATA, "Clone", "Clone the repository" }, { 'h', CAPCLASS_OTHER, "Hyperlinks", "Show hyperlinks to detailed repository history" }, { 'i', CAPCLASS_CODE, "Check-In", "Check-in code changes" }, { 'j', CAPCLASS_WIKI, "Read-Wiki", "View wiki pages" }, { 'k', CAPCLASS_WIKI, "Write-Wiki", "Edit wiki pages" }, { 'l', CAPCLASS_WIKI|CAPCLASS_SUPER, "Mod-Wiki", "Moderator for wiki pages" }, { 'm', CAPCLASS_WIKI, "Append-Wiki", "Append to wiki pages" }, { 'n', CAPCLASS_TKT, "New-Tkt", "Create new tickets" }, { 'o', CAPCLASS_CODE, "Check-Out", "Check out code" }, { 'p', CAPCLASS_OTHER, "Password", "Change your own password" }, { 'q', CAPCLASS_TKT|CAPCLASS_SUPER, "Mod-Tkt", "Moderate tickets" }, { 'r', CAPCLASS_TKT, "Read-Tkt", "View tickets" }, { 's', CAPCLASS_SUPER, "Superuser", "Setup and configure the respository" }, { 't', CAPCLASS_TKT, "Reports", "Create new ticket report formats" }, { 'u', CAPCLASS_OTHER, "Reader", "Inherit all the capabilities of the \"reader\" user" }, { 'v', CAPCLASS_OTHER, "Developer", "Inherit all capabilities of the \"developer\" user" }, { 'w', CAPCLASS_TKT, "Write-Tkt", "Edit tickets" }, { 'x', CAPCLASS_DATA, "Private", "Push and/or pull private branches" }, { 'y', CAPCLASS_SUPER, "Write-UV", "Push unversioned content" }, { 'z', CAPCLASS_CODE, "Zip-Download", "Download a ZIP archive, tarball, or SQL archive" }, { '2', CAPCLASS_FORUM, "Forum-Read", "Read forum posts by others" }, { '3', CAPCLASS_FORUM, "Forum-Write", "Create new forum messages" }, { '4', CAPCLASS_FORUM, "Forum-Trusted", "Create forum messages that bypass moderation" }, { '5', CAPCLASS_FORUM|CAPCLASS_SUPER, "Forum-Mod", "Moderator for forum messages" }, { '6', CAPCLASS_FORUM|CAPCLASS_SUPER, "Forum-Admin", "Set or remove capability '4' from other users" }, { '7', CAPCLASS_ALERT, "Alerts", "Sign up for email alerts" }, { 'A', CAPCLASS_ALERT|CAPCLASS_SUPER, "Announce", "Send announcements to all subscribers" }, { 'D', CAPCLASS_OTHER, "Debug", "Enable debugging features" }, }; /* ** Generate HTML that lists all of the capability letters together with ** a brief summary of what each letter means. */ void capabilities_table(unsigned mClass){ int i; @ <table> for(i=0; i<sizeof(aCap)/sizeof(aCap[0]); i++){ if( (aCap[i].eClass & mClass)==0 ) continue; @ <tr><th valign="top">%c(aCap[i].cCap)</th> @ <td><i>%h(aCap[i].zAbbrev):</i> %h(aCap[i].zOneLiner)</td></tr> } @ </table> } /* ** Generate a "capability summary table" that shows the major capabilities ** against the various user categories. */ |
︙ | ︙ |
Changes to src/captcha.c.
︙ | ︙ | |||
537 538 539 540 541 542 543 | const char *zDecoded; char *zCaptcha; if( !captcha_needed() ) return; uSeed = captcha_seed(); zDecoded = captcha_decode(uSeed); zCaptcha = captcha_render(zDecoded); | | | 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 | const char *zDecoded; char *zCaptcha; if( !captcha_needed() ) return; uSeed = captcha_seed(); zDecoded = captcha_decode(uSeed); zCaptcha = captcha_render(zDecoded); @ <div class="captcha"><table class="captcha"><tr><td><pre class="captcha"> @ %h(zCaptcha) @ </pre> @ Enter security code shown above: @ <input type="hidden" name="captchaseed" value="%u(uSeed)" /> @ <input type="text" name="captcha" size=8 /> if( showButton ){ @ <input type="submit" value="Submit"> |
︙ | ︙ |
Changes to src/codecheck1.c.
︙ | ︙ | |||
396 397 398 399 400 401 402 403 404 405 406 407 408 409 | { "json_new_string_f", 1, 0 }, { "json_set_err", 2, 0 }, { "json_warn", 2, 0 }, { "mprintf", 1, 0 }, { "socket_set_errmsg", 1, 0 }, { "ssl_set_errmsg", 1, 0 }, { "style_header", 1, FMT_HTML }, { "style_set_current_page", 1, FMT_URL }, { "style_submenu_element", 2, FMT_URL }, { "style_submenu_sql", 3, FMT_SQL }, { "webpage_error", 1, FMT_SAFE }, { "xhref", 2, FMT_URL }, }; | > | 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 | { "json_new_string_f", 1, 0 }, { "json_set_err", 2, 0 }, { "json_warn", 2, 0 }, { "mprintf", 1, 0 }, { "socket_set_errmsg", 1, 0 }, { "ssl_set_errmsg", 1, 0 }, { "style_header", 1, FMT_HTML }, { "style_js_onload", 1, FMT_HTML }, { "style_set_current_page", 1, FMT_URL }, { "style_submenu_element", 2, FMT_URL }, { "style_submenu_sql", 3, FMT_SQL }, { "webpage_error", 1, FMT_SAFE }, { "xhref", 2, FMT_URL }, }; |
︙ | ︙ |
Changes to src/configure.c.
︙ | ︙ | |||
97 98 99 100 101 102 103 104 105 106 107 108 109 110 | { "background-image", CONFIGSET_SKIN }, { "timeline-block-markup", CONFIGSET_SKIN }, { "timeline-max-comment", CONFIGSET_SKIN }, { "timeline-plaintext", CONFIGSET_SKIN }, { "adunit", CONFIGSET_SKIN }, { "adunit-omit-if-admin", CONFIGSET_SKIN }, { "adunit-omit-if-user", CONFIGSET_SKIN }, #ifdef FOSSIL_ENABLE_TH1_DOCS { "th1-docs", CONFIGSET_TH1 }, #endif #ifdef FOSSIL_ENABLE_TH1_HOOKS { "th1-hooks", CONFIGSET_TH1 }, #endif | > > > > | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | { "background-image", CONFIGSET_SKIN }, { "timeline-block-markup", CONFIGSET_SKIN }, { "timeline-max-comment", CONFIGSET_SKIN }, { "timeline-plaintext", CONFIGSET_SKIN }, { "adunit", CONFIGSET_SKIN }, { "adunit-omit-if-admin", CONFIGSET_SKIN }, { "adunit-omit-if-user", CONFIGSET_SKIN }, { "sitemap-docidx", CONFIGSET_SKIN }, { "sitemap-download", CONFIGSET_SKIN }, { "sitemap-license", CONFIGSET_SKIN }, { "sitemap-contact", CONFIGSET_SKIN }, #ifdef FOSSIL_ENABLE_TH1_DOCS { "th1-docs", CONFIGSET_TH1 }, #endif #ifdef FOSSIL_ENABLE_TH1_HOOKS { "th1-hooks", CONFIGSET_TH1 }, #endif |
︙ | ︙ | |||
396 397 398 399 400 401 402 | thisMask = configure_is_exportable(azToken[1]); }else{ thisMask = configure_is_exportable(aType[ii].zName); } if( (thisMask & groupMask)==0 ) return; if( (thisMask & checkMask)!=0 ){ if( (thisMask & CONFIGSET_SCRIBER)!=0 ){ | | | | 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 | thisMask = configure_is_exportable(azToken[1]); }else{ thisMask = configure_is_exportable(aType[ii].zName); } if( (thisMask & groupMask)==0 ) return; if( (thisMask & checkMask)!=0 ){ if( (thisMask & CONFIGSET_SCRIBER)!=0 ){ alert_schema(1); } checkMask &= ~thisMask; } blob_zero(&sql); if( groupMask & CONFIGSET_OVERWRITE ){ if( (thisMask & configHasBeenReset)==0 && aType[ii].zName[0]!='/' ){ db_multi_exec("DELETE FROM \"%w\"", &aType[ii].zName[1]); configHasBeenReset |= thisMask; } blob_append_sql(&sql, "REPLACE INTO "); }else{ blob_append_sql(&sql, "INSERT OR IGNORE INTO "); } blob_append_sql(&sql, "\"%w\"(\"%w\",mtime", &zName[1], aType[ii].zPrimKey); if( fossil_stricmp(zName,"/subscriber") ) alert_schema(0); for(jj=2; jj<nToken; jj+=2){ blob_append_sql(&sql, ",\"%w\"", azToken[jj]); } blob_append_sql(&sql,") VALUES(%s,%s", azToken[1] /*safe-for-%s*/, azToken[0]/*safe-for-%s*/); for(jj=2; jj<nToken; jj+=2){ blob_append_sql(&sql, ",%s", azToken[jj+1] /*safe-for-%s*/); |
︙ | ︙ |
Changes to src/db.c.
︙ | ︙ | |||
999 1000 1001 1002 1003 1004 1005 | sqlite3_create_function(db, "hextoblob", 1, SQLITE_UTF8, 0, db_hextoblob, 0, 0); sqlite3_create_function(db, "capunion", 1, SQLITE_UTF8, 0, 0, capability_union_step, capability_union_finalize); sqlite3_create_function(db, "fullcap", 1, SQLITE_UTF8, 0, capability_fullcap, 0, 0); sqlite3_create_function(db, "find_emailaddr", 1, SQLITE_UTF8, 0, | | | 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 | sqlite3_create_function(db, "hextoblob", 1, SQLITE_UTF8, 0, db_hextoblob, 0, 0); sqlite3_create_function(db, "capunion", 1, SQLITE_UTF8, 0, 0, capability_union_step, capability_union_finalize); sqlite3_create_function(db, "fullcap", 1, SQLITE_UTF8, 0, capability_fullcap, 0, 0); sqlite3_create_function(db, "find_emailaddr", 1, SQLITE_UTF8, 0, alert_find_emailaddr_func, 0, 0); } #if USE_SEE /* ** This is a pointer to the saved database encryption key string. */ static char *zSavedKey = 0; |
︙ | ︙ |
Changes to src/default_css.txt.
︙ | ︙ | |||
186 187 188 189 190 191 192 | span.wikiTagCancelled { text-decoration: line-through; } div.columns { padding: 0 2em 0 2em; max-width: 1000px; } | | | | > > > | 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | span.wikiTagCancelled { text-decoration: line-through; } div.columns { padding: 0 2em 0 2em; max-width: 1000px; } div.columns > ul { margin: 0; padding: 0 0 0 1em; } div.columns > ul li:first-child { margin-top:0px; } div.columns li { break-inside: avoid; } .filetree { margin: 1em 0; line-height: 1.5; } .filetree > ul { display: inline-block; } |
︙ | ︙ | |||
301 302 303 304 305 306 307 308 309 310 311 312 313 314 | table.captcha { margin: auto; padding: 10px; border-width: 4px; border-style: double; border-color: black; } td.login_out_label { text-align: center; } span.loginError { color: red; } span.note { | > > > | 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 | table.captcha { margin: auto; padding: 10px; border-width: 4px; border-style: double; border-color: black; } pre.captcha { font-size: 50%; } td.login_out_label { text-align: center; } span.loginError { color: red; } span.note { |
︙ | ︙ |
Changes to src/doc.c.
︙ | ︙ | |||
465 466 467 468 469 470 471 472 473 474 475 476 477 478 | ** Look for a file named zName in the check-in with RID=vid. Load the content ** of that file into pContent and return the RID for the file. Or return 0 ** if the file is not found or could not be loaded. */ int doc_load_content(int vid, const char *zName, Blob *pContent){ int writable = db_is_writeable("repository"); int rid; /* The RID of the file being loaded */ if( !db_table_exists("repository", "vcache") || !writable ){ db_multi_exec( "CREATE %s TABLE IF NOT EXISTS vcache(\n" " vid INTEGER, -- check-in ID\n" " fname TEXT, -- filename\n" " rid INTEGER, -- artifact ID\n" " PRIMARY KEY(vid,fname)\n" | > > > > | 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 | ** Look for a file named zName in the check-in with RID=vid. Load the content ** of that file into pContent and return the RID for the file. Or return 0 ** if the file is not found or could not be loaded. */ int doc_load_content(int vid, const char *zName, Blob *pContent){ int writable = db_is_writeable("repository"); int rid; /* The RID of the file being loaded */ if( writable ){ db_end_transaction(0); db_begin_write(); } if( !db_table_exists("repository", "vcache") || !writable ){ db_multi_exec( "CREATE %s TABLE IF NOT EXISTS vcache(\n" " vid INTEGER, -- check-in ID\n" " fname TEXT, -- filename\n" " rid INTEGER, -- artifact ID\n" " PRIMARY KEY(vid,fname)\n" |
︙ | ︙ |
Changes to src/forum.c.
︙ | ︙ | |||
772 773 774 775 776 777 778 | ** Edit an existing forum message. ** Query parameters: ** ** fpid=X Hash of the post to be editted. REQUIRED */ void forumedit_page(void){ int fpid; | | | 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 | ** Edit an existing forum message. ** Query parameters: ** ** fpid=X Hash of the post to be editted. REQUIRED */ void forumedit_page(void){ int fpid; Manifest *pPost = 0; const char *zMimetype = 0; const char *zContent = 0; const char *zTitle = 0; int isCsrfSafe; int isDelete = 0; login_check_credentials(); |
︙ | ︙ | |||
862 863 864 865 866 867 868 | zTitle = fossil_strdup(pPost->zThreadTitle); } style_header("Edit %s", zTitle ? "Post" : "Reply"); @ <h1>Original Post:</h1> forum_render(pPost->zThreadTitle, pPost->zMimetype, pPost->zWiki, "forumEdit"); if( P("preview") ){ | | | 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 | zTitle = fossil_strdup(pPost->zThreadTitle); } style_header("Edit %s", zTitle ? "Post" : "Reply"); @ <h1>Original Post:</h1> forum_render(pPost->zThreadTitle, pPost->zMimetype, pPost->zWiki, "forumEdit"); if( P("preview") ){ @ <h1>Preview of Edited Post:</h1> forum_render(zTitle, zMimetype, zContent,"forumEdit"); } @ <h1>Revised Message:</h1> @ <form action="%R/forume2" method="POST"> @ <input type="hidden" name="fpid" value="%h(P("fpid"))"> @ <input type="hidden" name="edit" value="1"> forum_from_line(); |
︙ | ︙ | |||
926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 | ** ** n=N The number of threads to show on each page ** x=X Skip the first X threads */ void forum_main_page(void){ Stmt q; int iLimit, iOfst, iCnt; login_check_credentials(); if( !g.perm.RdForum ){ login_needed(g.anon.RdForum); return; } style_header("Forum"); if( g.perm.WrForum ){ style_submenu_element("New Message","%R/forumnew"); } if( g.perm.ModForum && moderation_needed() ){ style_submenu_element("Moderation Requests", "%R/modreq"); } | > > > | | | | > | 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 | ** ** n=N The number of threads to show on each page ** x=X Skip the first X threads */ void forum_main_page(void){ Stmt q; int iLimit, iOfst, iCnt; int srchFlags; login_check_credentials(); srchFlags = search_restrict(SRCH_FORUM); if( !g.perm.RdForum ){ login_needed(g.anon.RdForum); return; } style_header("Forum"); if( g.perm.WrForum ){ style_submenu_element("New Message","%R/forumnew"); } if( g.perm.ModForum && moderation_needed() ){ style_submenu_element("Moderation Requests", "%R/modreq"); } if( (srchFlags & SRCH_FORUM)!=0 ){ if( search_screen(SRCH_FORUM, 0) ){ style_submenu_element("Recent Threads","%R/forum"); style_footer(); return; } } iLimit = atoi(PD("n","25")); iOfst = atoi(PD("x","0")); iCnt = 0; if( db_table_exists("repository","forumpost") ){ db_prepare(&q, "WITH thread(age,duration,cnt,root,last) AS (" |
︙ | ︙ | |||
988 989 990 991 992 993 994 | const char *zTitle = db_column_text(&q, 4); if( iCnt==0 ){ if( iOfst>0 ){ @ <h1>Threads at least %s(zAge) old</h1> }else{ @ <h1>Most recent threads</h1> } | | | 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 | const char *zTitle = db_column_text(&q, 4); if( iCnt==0 ){ if( iOfst>0 ){ @ <h1>Threads at least %s(zAge) old</h1> }else{ @ <h1>Most recent threads</h1> } @ <div class='forumPosts fileage'><table width="100%%"> if( iOfst>0 ){ if( iOfst>iLimit ){ @ <tr><td colspan="3">\ @ %z(href("%R/forum?x=%d&n=%d",iOfst-iLimit,iLimit))\ @ ↑ Newer...</a></td></tr> }else{ @ <tr><td colspan="3">%z(href("%R/forum?n=%d",iLimit))\ |
︙ | ︙ |
Changes to src/json.c.
︙ | ︙ | |||
1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 | ADD(WrTkt,"editTicket"); ADD(ModTkt,"moderateTicket"); ADD(Attach,"attachFile"); ADD(TktFmt,"createTicketReport"); ADD(RdAddr,"readPrivate"); ADD(Zip,"zip"); ADD(Private,"xferPrivate"); #undef ADD return payload; } /* ** Implementation of the /json/stat page/command. ** | > > > > > > > > > | 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 | ADD(WrTkt,"editTicket"); ADD(ModTkt,"moderateTicket"); ADD(Attach,"attachFile"); ADD(TktFmt,"createTicketReport"); ADD(RdAddr,"readPrivate"); ADD(Zip,"zip"); ADD(Private,"xferPrivate"); ADD(WrUnver,"writeUnversioned"); ADD(RdForum,"readForum"); ADD(WrForum,"writeForum"); ADD(WrTForum,"writeTrustedForum"); ADD(ModForum,"moderateForum"); ADD(AdminForum,"adminForum"); ADD(EmailAlert,"emailAlert"); ADD(Announce,"announce"); ADD(Debug,"debug"); #undef ADD return payload; } /* ** Implementation of the /json/stat page/command. ** |
︙ | ︙ |
Changes to src/login.c.
︙ | ︙ | |||
727 728 729 730 731 732 733 734 | @ <tr> @ <td class="form_label">User ID:</td> if( anonFlag ){ @ <td><input type="text" id="u" name="u" value="anonymous" size="30"></td> }else{ @ <td><input type="text" id="u" name="u" value="" size="30" /></td> } if( P("HTTPS")==0 ){ | > > > > > | | | | < < < < < < < < < | > | | > | | | | | | | | | | | | | | > | 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 | @ <tr> @ <td class="form_label">User ID:</td> if( anonFlag ){ @ <td><input type="text" id="u" name="u" value="anonymous" size="30"></td> }else{ @ <td><input type="text" id="u" name="u" value="" size="30" /></td> } @ </tr> @ <tr> @ <td class="form_label">Password:</td> @ <td><input type="password" id="p" name="p" value="" size="30" /></td> @ </tr> if( P("HTTPS")==0 ){ @ <tr><td class="form_label">Warning:</td> @ <td><span class='securityWarning'> @ Your password will be sent in the clear over an @ unencrypted connection. if( g.sslNotAvailable ){ @ No encrypted connection is available on this server. }else{ @ Consider logging in at @ <a href='%s(g.zHttpsURL)'>%h(g.zHttpsURL)</a> instead. } @ </span></td></tr> } if( g.zLogin==0 && (anonFlag || zGoto==0) ){ zAnonPw = db_text(0, "SELECT pw FROM user" " WHERE login='anonymous'" " AND cap!=''"); } @ <tr> @ <td></td> @ <td><input type="submit" name="in" value="Login"></td> @ </tr> if( !noAnon && login_self_register_available(0) ){ @ <tr> @ <td></td> @ <td><input type="submit" name="self" value="Create A New Account"> @ </tr> } @ </table> if( zAnonPw && !noAnon ){ unsigned int uSeed = captcha_seed(); const char *zDecoded = captcha_decode(uSeed); int bAutoCaptcha = db_get_boolean("auto-captcha", 0); char *zCaptcha = captcha_render(zDecoded); @ <p><input type="hidden" name="cs" value="%u(uSeed)" /> @ Visitors may enter <b>anonymous</b> as the user-ID with @ the 8-character hexadecimal password shown below:</p> @ <div class="captcha"><table class="captcha"><tr><td>\ @ <pre class="captcha"> @ %h(zCaptcha) @ </pre></td></tr></table> if( bAutoCaptcha ) { @ <input type="button" value="Fill out captcha" id='autofillButton' \ @ data-af='%s(zDecoded)' /> style_load_one_js_file("login.js"); } @ </div> free(zCaptcha); } @ </form> } if( login_is_individual() ){ if( g.perm.EmailAlert && alert_enabled() ){ @ <hr> @ <p>Configure <a href="%R/alerts">Email Alerts</a> @ for user <b>%h(g.zLogin)</b></p> } if( g.perm.Password ){ @ <hr> @ <p>Change Password for user <b>%h(g.zLogin)</b>:</p> form_begin(0, "%R/login"); @ <table> @ <tr><td class="form_label">Old Password:</td> @ <td><input type="password" name="p" size="30" /></td></tr> @ <tr><td class="form_label">New Password:</td> @ <td><input type="password" name="n1" size="30" /></td></tr> @ <tr><td class="form_label">Repeat New Password:</td> @ <td><input type="password" name="n2" size="30" /></td></tr> @ <tr><td></td> @ <td><input type="submit" value="Change Password" /></td></tr> @ </table> @ </form> } } style_footer(); } /* ** Attempt to find login credentials for user zLogin on a peer repository ** with project code zCode. Transfer those credentials to the local |
︙ | ︙ | |||
1192 1193 1194 1195 1196 1197 1198 | /* If the public-pages glob pattern is defined and REQUEST_URI matches ** one of the globs in public-pages, then also add in all default-perms ** permissions. */ zPublicPages = db_get("public-pages",0); if( zPublicPages!=0 ){ Glob *pGlob = glob_create(zPublicPages); | > > | | 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 | /* If the public-pages glob pattern is defined and REQUEST_URI matches ** one of the globs in public-pages, then also add in all default-perms ** permissions. */ zPublicPages = db_get("public-pages",0); if( zPublicPages!=0 ){ Glob *pGlob = glob_create(zPublicPages); const char *zUri = PD("REQUEST_URI",""); zUri += (int)strlen(g.zTop); if( glob_match(pGlob, zUri) ){ login_set_capabilities(db_get("default-perms","u"), 0); } glob_free(pGlob); } } /* |
︙ | ︙ | |||
1260 1261 1262 1263 1264 1265 1266 | p->RdWiki = p->WrWiki = p->NewWiki = p->ApndWiki = p->Hyperlink = p->Clone = p->NewTkt = p->Password = p->RdAddr = p->TktFmt = p->Attach = p->ApndTkt = p->ModWiki = p->ModTkt = p->Delete = p->RdForum = p->WrForum = p->ModForum = p->WrTForum = p->AdminForum = | | | 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 | p->RdWiki = p->WrWiki = p->NewWiki = p->ApndWiki = p->Hyperlink = p->Clone = p->NewTkt = p->Password = p->RdAddr = p->TktFmt = p->Attach = p->ApndTkt = p->ModWiki = p->ModTkt = p->Delete = p->RdForum = p->WrForum = p->ModForum = p->WrTForum = p->AdminForum = p->EmailAlert = p->Announce = p->Debug = p->WrUnver = p->Private = 1; /* Fall thru into Read/Write */ case 'i': p->Read = p->Write = 1; break; case 'o': p->Read = 1; break; case 'z': p->Zip = 1; break; case 'd': p->Delete = 1; break; |
︙ | ︙ | |||
1540 1541 1542 1543 1544 1545 1546 | style_footer(); return; } zPerms = db_get("default-perms","u"); /* Prompt the user for email alerts if this repository is configured for ** email alerts and if the default permissions include "7" */ | | | 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 | style_footer(); return; } zPerms = db_get("default-perms","u"); /* Prompt the user for email alerts if this repository is configured for ** email alerts and if the default permissions include "7" */ canDoAlerts = alert_tables_exist() && db_int(0, "SELECT fullcap(%Q) GLOB '*7*'", zPerms ); doAlerts = canDoAlerts && atoi(PD("alerts","1"))!=0; zUserID = PDT("u",""); zPasswd = PDT("p",""); zConfirm = PDT("cp",""); |
︙ | ︙ | |||
1613 1614 1615 1616 1617 1618 1619 | fossil_free(zPass); db_multi_exec("%s", blob_sql_text(&sql)); uid = db_int(0, "SELECT uid FROM user WHERE login=%Q", zUserID); login_set_user_cookie(zUserID, uid, NULL); if( doAlerts ){ /* Also make the new user a subscriber. */ Blob hdr, body; | | | 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 | fossil_free(zPass); db_multi_exec("%s", blob_sql_text(&sql)); uid = db_int(0, "SELECT uid FROM user WHERE login=%Q", zUserID); login_set_user_cookie(zUserID, uid, NULL); if( doAlerts ){ /* Also make the new user a subscriber. */ Blob hdr, body; AlertSender *pSender; sqlite3_int64 id; /* New subscriber Id */ const char *zCode; /* New subscriber code (in hex) */ const char *zGoto = P("g"); int nsub = 0; char ssub[20]; ssub[nsub++] = 'a'; if( g.perm.Read ) ssub[nsub++] = 'c'; |
︙ | ︙ | |||
1651 1652 1653 1654 1655 1656 1657 | ** not necessary to repeat the verfication step */ redirect_to_g(); } zCode = db_text(0, "SELECT hex(subscriberCode) FROM subscriber WHERE subscriberId=%lld", id); /* A verification email */ | | | | | | 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 | ** not necessary to repeat the verfication step */ redirect_to_g(); } zCode = db_text(0, "SELECT hex(subscriberCode) FROM subscriber WHERE subscriberId=%lld", id); /* A verification email */ pSender = alert_sender_new(0,0); blob_init(&hdr,0,0); blob_init(&body,0,0); blob_appendf(&hdr, "To: <%s>\n", zEAddr); blob_appendf(&hdr, "Subject: Subscription verification\n"); alert_append_confirmation_message(&body, zCode); alert_send(pSender, &hdr, &body, 0); style_header("Email Verification"); if( pSender->zErr ){ @ <h1>Internal Error</h1> @ <p>The following internal error was encountered while trying @ to send the confirmation email: @ <blockquote><pre> @ %h(pSender->zErr) @ </pre></blockquote> }else{ @ <p>An email has been sent to "%h(zEAddr)". That email contains a @ hyperlink that you must click on in order to activate your @ subscription.</p> } alert_sender_free(pSender); if( zGoto ){ @ <p><a href='%h(zGoto)'>Continue</a> } style_footer(); return; } redirect_to_g(); |
︙ | ︙ | |||
1697 1698 1699 1700 1701 1702 1703 1704 | @ <input type="hidden" name="g" value="%h(P("g"))" /> } @ <p><input type="hidden" name="captchaseed" value="%u(uSeed)" /> @ <table class="login_out"> @ <tr> @ <td class="form_label" align="right">User ID:</td> @ <td><input type="text" name="u" value="%h(zUserID)" size="30"></td> if( iErrLine==1 ){ | > | < > | > | < | > | < < < | > | < | > | < | > > | | 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 | @ <input type="hidden" name="g" value="%h(P("g"))" /> } @ <p><input type="hidden" name="captchaseed" value="%u(uSeed)" /> @ <table class="login_out"> @ <tr> @ <td class="form_label" align="right">User ID:</td> @ <td><input type="text" name="u" value="%h(zUserID)" size="30"></td> @ if( iErrLine==1 ){ @ <tr><td><td><span class='loginError'>↑ %h(zErr)</span></td></tr> } @ <tr> @ <td class="form_label" align="right">Display Name:</td> @ <td><input type="text" name="dn" value="%h(zDName)" size="30"></td> @ </tr> if( iErrLine==2 ){ @ <tr><td><td><span class='loginError'>↑ %h(zErr)</span></td></tr> } @ </tr> @ <tr> @ <td class="form_label" align="right">Email Address:</td> @ <td><input type="text" name="ea" value="%h(zEAddr)" size="30"></td> @ </tr> if( iErrLine==3 ){ @ <tr><td><td><span class='loginError'>↑ %h(zErr)</span></td></tr> } if( canDoAlerts ){ int a = atoi(PD("alerts","1")); @ <tr> @ <td class="form_label" align="right">Email Alerts?</td> @ <td><select size='1' name='alerts'> @ <option value="1" %s(a?"selected":"")>Yes</option> @ <option value="0" %s(!a?"selected":"")>No</option> @ </select></td></tr> } @ <tr> @ <td class="form_label" align="right">Password:</td> @ <td><input type="password" name="p" value="%h(zPasswd)" size="30"></td> @ <tr> if( iErrLine==4 ){ @ <tr><td><td><span class='loginError'>↑ %h(zErr)</span></td></tr> } @ <tr> @ <td class="form_label" align="right">Confirm:</td> @ <td><input type="password" name="cp" value="%h(zConfirm)" size="30"></td> @ </tr> if( iErrLine==5 ){ @ <tr><td><td><span class='loginError'>↑ %h(zErr)</span></td></tr> } @ <tr> @ <td class="form_label" align="right">Captcha:</td> @ <td><input type="text" name="captcha" value="" size="30"></td> @ </tr> if( iErrLine==6 ){ @ <tr><td><td><span class='loginError'>↑ %h(zErr)</span></td></tr> } @ <tr><td></td> @ <td><input type="submit" name="new" value="Register" /></td></tr> @ </table> @ <div class="captcha"><table class="captcha"><tr><td><pre class="captcha"> @ %h(zCaptcha) @ </pre> @ Enter this 8-letter code in the "Captcha" box above. @ </td></tr></table></div> @ </form> style_footer(); free(zCaptcha); } /* |
︙ | ︙ |
Changes to src/main.mk.
︙ | ︙ | |||
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # # This file is included by primary Makefile. # XBCC = $(BCC) $(BCCFLAGS) XTCC = $(TCC) -I. -I$(SRCDIR) -I$(OBJDIR) $(TCCFLAGS) SRC = \ $(SRCDIR)/add.c \ $(SRCDIR)/allrepo.c \ $(SRCDIR)/attach.c \ $(SRCDIR)/backoffice.c \ $(SRCDIR)/bag.c \ $(SRCDIR)/bisect.c \ $(SRCDIR)/blob.c \ $(SRCDIR)/branch.c \ | > > | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | # # This file is included by primary Makefile. # XBCC = $(BCC) $(BCCFLAGS) XTCC = $(TCC) -I. -I$(SRCDIR) -I$(OBJDIR) $(TCCFLAGS) TESTFLAGS := -quiet SRC = \ $(SRCDIR)/add.c \ $(SRCDIR)/alerts.c \ $(SRCDIR)/allrepo.c \ $(SRCDIR)/attach.c \ $(SRCDIR)/backoffice.c \ $(SRCDIR)/bag.c \ $(SRCDIR)/bisect.c \ $(SRCDIR)/blob.c \ $(SRCDIR)/branch.c \ |
︙ | ︙ | |||
42 43 44 45 46 47 48 | $(SRCDIR)/delta.c \ $(SRCDIR)/deltacmd.c \ $(SRCDIR)/descendants.c \ $(SRCDIR)/diff.c \ $(SRCDIR)/diffcmd.c \ $(SRCDIR)/dispatch.c \ $(SRCDIR)/doc.c \ | < | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | $(SRCDIR)/delta.c \ $(SRCDIR)/deltacmd.c \ $(SRCDIR)/descendants.c \ $(SRCDIR)/diff.c \ $(SRCDIR)/diffcmd.c \ $(SRCDIR)/dispatch.c \ $(SRCDIR)/doc.c \ $(SRCDIR)/encode.c \ $(SRCDIR)/etag.c \ $(SRCDIR)/event.c \ $(SRCDIR)/export.c \ $(SRCDIR)/file.c \ $(SRCDIR)/finfo.c \ $(SRCDIR)/foci.c \ |
︙ | ︙ | |||
175 176 177 178 179 180 181 182 183 184 185 186 187 188 | $(SRCDIR)/../skins/bootstrap/details.txt \ $(SRCDIR)/../skins/bootstrap/footer.txt \ $(SRCDIR)/../skins/bootstrap/header.txt \ $(SRCDIR)/../skins/default/css.txt \ $(SRCDIR)/../skins/default/details.txt \ $(SRCDIR)/../skins/default/footer.txt \ $(SRCDIR)/../skins/default/header.txt \ $(SRCDIR)/../skins/eagle/css.txt \ $(SRCDIR)/../skins/eagle/details.txt \ $(SRCDIR)/../skins/eagle/footer.txt \ $(SRCDIR)/../skins/eagle/header.txt \ $(SRCDIR)/../skins/enhanced1/css.txt \ $(SRCDIR)/../skins/enhanced1/details.txt \ $(SRCDIR)/../skins/enhanced1/footer.txt \ | > | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | $(SRCDIR)/../skins/bootstrap/details.txt \ $(SRCDIR)/../skins/bootstrap/footer.txt \ $(SRCDIR)/../skins/bootstrap/header.txt \ $(SRCDIR)/../skins/default/css.txt \ $(SRCDIR)/../skins/default/details.txt \ $(SRCDIR)/../skins/default/footer.txt \ $(SRCDIR)/../skins/default/header.txt \ $(SRCDIR)/../skins/default/js.txt \ $(SRCDIR)/../skins/eagle/css.txt \ $(SRCDIR)/../skins/eagle/details.txt \ $(SRCDIR)/../skins/eagle/footer.txt \ $(SRCDIR)/../skins/eagle/header.txt \ $(SRCDIR)/../skins/enhanced1/css.txt \ $(SRCDIR)/../skins/enhanced1/details.txt \ $(SRCDIR)/../skins/enhanced1/footer.txt \ |
︙ | ︙ | |||
221 222 223 224 225 226 227 228 229 230 231 232 233 234 | $(SRCDIR)/sorttable.js \ $(SRCDIR)/tree.js \ $(SRCDIR)/useredit.js \ $(SRCDIR)/wiki.wiki TRANS_SRC = \ $(OBJDIR)/add_.c \ $(OBJDIR)/allrepo_.c \ $(OBJDIR)/attach_.c \ $(OBJDIR)/backoffice_.c \ $(OBJDIR)/bag_.c \ $(OBJDIR)/bisect_.c \ $(OBJDIR)/blob_.c \ $(OBJDIR)/branch_.c \ | > | 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | $(SRCDIR)/sorttable.js \ $(SRCDIR)/tree.js \ $(SRCDIR)/useredit.js \ $(SRCDIR)/wiki.wiki TRANS_SRC = \ $(OBJDIR)/add_.c \ $(OBJDIR)/alerts_.c \ $(OBJDIR)/allrepo_.c \ $(OBJDIR)/attach_.c \ $(OBJDIR)/backoffice_.c \ $(OBJDIR)/bag_.c \ $(OBJDIR)/bisect_.c \ $(OBJDIR)/blob_.c \ $(OBJDIR)/branch_.c \ |
︙ | ︙ | |||
251 252 253 254 255 256 257 | $(OBJDIR)/delta_.c \ $(OBJDIR)/deltacmd_.c \ $(OBJDIR)/descendants_.c \ $(OBJDIR)/diff_.c \ $(OBJDIR)/diffcmd_.c \ $(OBJDIR)/dispatch_.c \ $(OBJDIR)/doc_.c \ | < | 254 255 256 257 258 259 260 261 262 263 264 265 266 267 | $(OBJDIR)/delta_.c \ $(OBJDIR)/deltacmd_.c \ $(OBJDIR)/descendants_.c \ $(OBJDIR)/diff_.c \ $(OBJDIR)/diffcmd_.c \ $(OBJDIR)/dispatch_.c \ $(OBJDIR)/doc_.c \ $(OBJDIR)/encode_.c \ $(OBJDIR)/etag_.c \ $(OBJDIR)/event_.c \ $(OBJDIR)/export_.c \ $(OBJDIR)/file_.c \ $(OBJDIR)/finfo_.c \ $(OBJDIR)/foci_.c \ |
︙ | ︙ | |||
358 359 360 361 362 363 364 365 366 367 368 369 370 371 | $(OBJDIR)/wysiwyg_.c \ $(OBJDIR)/xfer_.c \ $(OBJDIR)/xfersetup_.c \ $(OBJDIR)/zip_.c OBJ = \ $(OBJDIR)/add.o \ $(OBJDIR)/allrepo.o \ $(OBJDIR)/attach.o \ $(OBJDIR)/backoffice.o \ $(OBJDIR)/bag.o \ $(OBJDIR)/bisect.o \ $(OBJDIR)/blob.o \ $(OBJDIR)/branch.o \ | > | 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 | $(OBJDIR)/wysiwyg_.c \ $(OBJDIR)/xfer_.c \ $(OBJDIR)/xfersetup_.c \ $(OBJDIR)/zip_.c OBJ = \ $(OBJDIR)/add.o \ $(OBJDIR)/alerts.o \ $(OBJDIR)/allrepo.o \ $(OBJDIR)/attach.o \ $(OBJDIR)/backoffice.o \ $(OBJDIR)/bag.o \ $(OBJDIR)/bisect.o \ $(OBJDIR)/blob.o \ $(OBJDIR)/branch.o \ |
︙ | ︙ | |||
388 389 390 391 392 393 394 | $(OBJDIR)/delta.o \ $(OBJDIR)/deltacmd.o \ $(OBJDIR)/descendants.o \ $(OBJDIR)/diff.o \ $(OBJDIR)/diffcmd.o \ $(OBJDIR)/dispatch.o \ $(OBJDIR)/doc.o \ | < | 391 392 393 394 395 396 397 398 399 400 401 402 403 404 | $(OBJDIR)/delta.o \ $(OBJDIR)/deltacmd.o \ $(OBJDIR)/descendants.o \ $(OBJDIR)/diff.o \ $(OBJDIR)/diffcmd.o \ $(OBJDIR)/dispatch.o \ $(OBJDIR)/doc.o \ $(OBJDIR)/encode.o \ $(OBJDIR)/etag.o \ $(OBJDIR)/event.o \ $(OBJDIR)/export.o \ $(OBJDIR)/file.o \ $(OBJDIR)/finfo.o \ $(OBJDIR)/foci.o \ |
︙ | ︙ | |||
544 545 546 547 548 549 550 | # -quiet Hide most output from the terminal # -strict Treat known bugs as failures # # TESTFLAGS can also include names of specific test files to limit # the run to just those test cases. # test: $(OBJDIR) $(APPNAME) | | | 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 | # -quiet Hide most output from the terminal # -strict Treat known bugs as failures # # TESTFLAGS can also include names of specific test files to limit # the run to just those test cases. # test: $(OBJDIR) $(APPNAME) $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME) $(TESTFLAGS) $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION $(OBJDIR)/mkversion $(OBJDIR)/mkversion $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h $(OBJDIR)/default_css.h: $(SRCDIR)/default_css.txt $(OBJDIR)/mkcss $(OBJDIR)/mkcss $(SRCDIR)/default_css.txt $(OBJDIR)/default_css.h |
︙ | ︙ | |||
693 694 695 696 697 698 699 700 701 702 703 704 705 706 | $(OBJDIR)/mkindex $(TRANS_SRC) >$@ $(OBJDIR)/builtin_data.h: $(OBJDIR)/mkbuiltin $(EXTRA_FILES) $(OBJDIR)/mkbuiltin --prefix $(SRCDIR)/ $(EXTRA_FILES) >$@ $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(OBJDIR)/default_css.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h \ $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \ $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \ $(OBJDIR)/backoffice_.c:$(OBJDIR)/backoffice.h \ $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \ $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \ $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \ $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \ | > | 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 | $(OBJDIR)/mkindex $(TRANS_SRC) >$@ $(OBJDIR)/builtin_data.h: $(OBJDIR)/mkbuiltin $(EXTRA_FILES) $(OBJDIR)/mkbuiltin --prefix $(SRCDIR)/ $(EXTRA_FILES) >$@ $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(OBJDIR)/default_css.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h \ $(OBJDIR)/alerts_.c:$(OBJDIR)/alerts.h \ $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \ $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \ $(OBJDIR)/backoffice_.c:$(OBJDIR)/backoffice.h \ $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \ $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \ $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \ $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \ |
︙ | ︙ | |||
723 724 725 726 727 728 729 | $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h \ $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h \ $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h \ $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h \ $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h \ $(OBJDIR)/dispatch_.c:$(OBJDIR)/dispatch.h \ $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h \ | < | 726 727 728 729 730 731 732 733 734 735 736 737 738 739 | $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h \ $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h \ $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h \ $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h \ $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h \ $(OBJDIR)/dispatch_.c:$(OBJDIR)/dispatch.h \ $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h \ $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h \ $(OBJDIR)/etag_.c:$(OBJDIR)/etag.h \ $(OBJDIR)/event_.c:$(OBJDIR)/event.h \ $(OBJDIR)/export_.c:$(OBJDIR)/export.h \ $(OBJDIR)/file_.c:$(OBJDIR)/file.h \ $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \ $(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \ |
︙ | ︙ | |||
841 842 843 844 845 846 847 848 849 850 851 852 853 854 | $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/add.c >$@ $(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/add.o -c $(OBJDIR)/add_.c $(OBJDIR)/add.h: $(OBJDIR)/headers $(OBJDIR)/allrepo_.c: $(SRCDIR)/allrepo.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/allrepo.c >$@ $(OBJDIR)/allrepo.o: $(OBJDIR)/allrepo_.c $(OBJDIR)/allrepo.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/allrepo.o -c $(OBJDIR)/allrepo_.c | > > > > > > > > | 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 | $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/add.c >$@ $(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/add.o -c $(OBJDIR)/add_.c $(OBJDIR)/add.h: $(OBJDIR)/headers $(OBJDIR)/alerts_.c: $(SRCDIR)/alerts.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/alerts.c >$@ $(OBJDIR)/alerts.o: $(OBJDIR)/alerts_.c $(OBJDIR)/alerts.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/alerts.o -c $(OBJDIR)/alerts_.c $(OBJDIR)/alerts.h: $(OBJDIR)/headers $(OBJDIR)/allrepo_.c: $(SRCDIR)/allrepo.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/allrepo.c >$@ $(OBJDIR)/allrepo.o: $(OBJDIR)/allrepo_.c $(OBJDIR)/allrepo.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/allrepo.o -c $(OBJDIR)/allrepo_.c |
︙ | ︙ | |||
1082 1083 1084 1085 1086 1087 1088 | $(OBJDIR)/translate $(SRCDIR)/doc.c >$@ $(OBJDIR)/doc.o: $(OBJDIR)/doc_.c $(OBJDIR)/doc.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/doc.o -c $(OBJDIR)/doc_.c $(OBJDIR)/doc.h: $(OBJDIR)/headers | < < < < < < < < | 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 | $(OBJDIR)/translate $(SRCDIR)/doc.c >$@ $(OBJDIR)/doc.o: $(OBJDIR)/doc_.c $(OBJDIR)/doc.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/doc.o -c $(OBJDIR)/doc_.c $(OBJDIR)/doc.h: $(OBJDIR)/headers $(OBJDIR)/encode_.c: $(SRCDIR)/encode.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/encode.c >$@ $(OBJDIR)/encode.o: $(OBJDIR)/encode_.c $(OBJDIR)/encode.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/encode.o -c $(OBJDIR)/encode_.c $(OBJDIR)/encode.h: $(OBJDIR)/headers |
︙ | ︙ |
Changes to src/makemake.tcl.
︙ | ︙ | |||
24 25 26 27 28 29 30 31 32 33 34 35 36 37 | # project, simply add the basename to this list and rerun this script. # # Set the separate extra_files variable further down for how to add non-C # files, such as string and BLOB resources. # set src { add allrepo attach backoffice bag bisect blob branch | > | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | # project, simply add the basename to this list and rerun this script. # # Set the separate extra_files variable further down for how to add non-C # files, such as string and BLOB resources. # set src { add alerts allrepo attach backoffice bag bisect blob branch |
︙ | ︙ | |||
54 55 56 57 58 59 60 | delta deltacmd descendants diff diffcmd dispatch doc | < | 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | delta deltacmd descendants diff diffcmd dispatch doc encode etag event export file finfo foci |
︙ | ︙ | |||
284 285 286 287 288 289 290 291 292 293 294 295 296 297 | # # This file is included by primary Makefile. # XBCC = $(BCC) $(BCCFLAGS) XTCC = $(TCC) -I. -I$(SRCDIR) -I$(OBJDIR) $(TCCFLAGS) } writeln -nonewline "SRC =" foreach s [lsort $src] { writeln -nonewline " \\\n \$(SRCDIR)/$s.c" } writeln "\n" writeln -nonewline "EXTRA_FILES =" | > | 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 | # # This file is included by primary Makefile. # XBCC = $(BCC) $(BCCFLAGS) XTCC = $(TCC) -I. -I$(SRCDIR) -I$(OBJDIR) $(TCCFLAGS) TESTFLAGS := -quiet } writeln -nonewline "SRC =" foreach s [lsort $src] { writeln -nonewline " \\\n \$(SRCDIR)/$s.c" } writeln "\n" writeln -nonewline "EXTRA_FILES =" |
︙ | ︙ | |||
359 360 361 362 363 364 365 | # -quiet Hide most output from the terminal # -strict Treat known bugs as failures # # TESTFLAGS can also include names of specific test files to limit # the run to just those test cases. # test: $(OBJDIR) $(APPNAME) | | | 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 | # -quiet Hide most output from the terminal # -strict Treat known bugs as failures # # TESTFLAGS can also include names of specific test files to limit # the run to just those test cases. # test: $(OBJDIR) $(APPNAME) $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME) $(TESTFLAGS) $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION $(OBJDIR)/mkversion $(OBJDIR)/mkversion $(SRCDIR)/../manifest.uuid \ $(SRCDIR)/../manifest \ $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h $(OBJDIR)/default_css.h: $(SRCDIR)/default_css.txt $(OBJDIR)/mkcss |
︙ | ︙ | |||
693 694 695 696 697 698 699 | ZLIBCONFIG = ZLIBTARGETS = endif #### Disable creation of the OpenSSL shared libraries. Also, disable support # for SSLv3 (i.e. thereby forcing the use of TLS). # | | | 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 | ZLIBCONFIG = ZLIBTARGETS = endif #### Disable creation of the OpenSSL shared libraries. Also, disable support # for SSLv3 (i.e. thereby forcing the use of TLS). # SSLCONFIG += no-ssl3 no-weak-ssl-ciphers no-shared #### When using zlib, make sure that OpenSSL is configured to use the zlib # that Fossil knows about (i.e. the one within the source tree). # ifndef FOSSIL_ENABLE_MINIZ SSLCONFIG += --with-zlib-lib=$(PWD)/$(ZLIBDIR) --with-zlib-include=$(PWD)/$(ZLIBDIR) zlib endif |
︙ | ︙ | |||
1575 1576 1577 1578 1579 1580 1581 | SSLLIBDIR = $(SSLDIR)\out32 !endif SSLLFLAGS = /nologo /opt:ref /debug SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib crypt32.lib !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64" !message Using 'x64' platform for OpenSSL... # BUGBUG (OpenSSL): Using "no-ssl*" here breaks the build. | | | | | | | | 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 | SSLLIBDIR = $(SSLDIR)\out32 !endif SSLLFLAGS = /nologo /opt:ref /debug SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib crypt32.lib !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64" !message Using 'x64' platform for OpenSSL... # BUGBUG (OpenSSL): Using "no-ssl*" here breaks the build. # SSLCONFIG = VC-WIN64A no-asm no-ssl3 no-weak-ssl-ciphers SSLCONFIG = VC-WIN64A no-asm !if $(FOSSIL_DYNAMIC_BUILD)!=0 SSLCONFIG = $(SSLCONFIG) shared !else SSLCONFIG = $(SSLCONFIG) no-shared !endif SSLSETUP = ms\do_win64a.bat !if $(FOSSIL_DYNAMIC_BUILD)!=0 SSLNMAKE = ms\ntdll.mak all !else SSLNMAKE = ms\nt.mak all !endif # BUGBUG (OpenSSL): Using "OPENSSL_NO_SSL*" here breaks dynamic builds. !if $(FOSSIL_DYNAMIC_BUILD)==0 SSLCFLAGS = -DOPENSSL_NO_SSL3 -DOPENSSL_NO_WEAK_SSL_CIPHERS !endif !elseif "$(PLATFORM)"=="ia64" !message Using 'ia64' platform for OpenSSL... # BUGBUG (OpenSSL): Using "no-ssl*" here breaks the build. # SSLCONFIG = VC-WIN64I no-asm no-ssl3 no-weak-ssl-ciphers SSLCONFIG = VC-WIN64I no-asm !if $(FOSSIL_DYNAMIC_BUILD)!=0 SSLCONFIG = $(SSLCONFIG) shared !else SSLCONFIG = $(SSLCONFIG) no-shared !endif SSLSETUP = ms\do_win64i.bat !if $(FOSSIL_DYNAMIC_BUILD)!=0 SSLNMAKE = ms\ntdll.mak all !else SSLNMAKE = ms\nt.mak all !endif # BUGBUG (OpenSSL): Using "OPENSSL_NO_SSL*" here breaks dynamic builds. !if $(FOSSIL_DYNAMIC_BUILD)==0 SSLCFLAGS = -DOPENSSL_NO_SSL3 -DOPENSSL_NO_WEAK_SSL_CIPHERS !endif !else !message Assuming 'x86' platform for OpenSSL... # BUGBUG (OpenSSL): Using "no-ssl*" here breaks the build. # SSLCONFIG = VC-WIN32 no-asm no-ssl3 no-weak-ssl-ciphers SSLCONFIG = VC-WIN32 no-asm !if $(FOSSIL_DYNAMIC_BUILD)!=0 SSLCONFIG = $(SSLCONFIG) shared !else SSLCONFIG = $(SSLCONFIG) no-shared !endif SSLSETUP = ms\do_ms.bat !if $(FOSSIL_DYNAMIC_BUILD)!=0 SSLNMAKE = ms\ntdll.mak all !else SSLNMAKE = ms\nt.mak all !endif # BUGBUG (OpenSSL): Using "OPENSSL_NO_SSL*" here breaks dynamic builds. !if $(FOSSIL_DYNAMIC_BUILD)==0 SSLCFLAGS = -DOPENSSL_NO_SSL3 -DOPENSSL_NO_WEAK_SSL_CIPHERS !endif !endif !endif !if $(FOSSIL_ENABLE_TCL)!=0 TCLDIR = $(B)\compat\tcl-8.6 TCLSRCDIR = $(TCLDIR) |
︙ | ︙ |
Changes to src/markdown.md.
︙ | ︙ | |||
91 92 93 94 95 96 97 | > The first row is a header if followed by a horizontal rule or a blank line. > Placing **:** at the left, both, or right sides of a cell gives left-aligned, > centered, or right-aligned text, respectively. By default, header cells are > centered, and body cells are left-aligned. | | | | 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | > The first row is a header if followed by a horizontal rule or a blank line. > Placing **:** at the left, both, or right sides of a cell gives left-aligned, > centered, or right-aligned text, respectively. By default, header cells are > centered, and body cells are left-aligned. > The leftmost or rightmost **\|** is required only if the first or last column, > respectively, contains at least one blank cell. ## Miscellaneous ## > * In-line images are made using **\!\[alt-text\]\(image-URL\)**. > * Use HTML for advanced formatting such as forms. > * **\<!--** HTML-style comments **-->** are supported. > * Escape special characters (ex: **\[** **\(** **\|** **\***) |
︙ | ︙ |
Changes to src/rebuild.c.
︙ | ︙ | |||
356 357 358 359 360 361 362 | bag_init(&bagDone); ttyOutput = doOut; processCnt = 0; if (ttyOutput && !g.fQuiet) { percent_complete(0); } | | | | 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 | bag_init(&bagDone); ttyOutput = doOut; processCnt = 0; if (ttyOutput && !g.fQuiet) { percent_complete(0); } alert_triggers_disable(); rebuild_update_schema(); blob_init(&sql, 0, 0); db_prepare(&q, "SELECT name FROM sqlite_master /*scan*/" " WHERE type='table'" " AND name NOT IN ('admin_log', 'blob','delta','rcvfrom','user','alias'," "'config','shun','private','reportfmt'," "'concealed','accesslog','modreq'," "'purgeevent','purgeitem','unversioned'," "'subscriber','pending_alert','alert_bounce')" " AND name NOT GLOB 'sqlite_*'" " AND name NOT GLOB 'fx_*'" ); while( db_step(&q)==SQLITE_ROW ){ blob_appendf(&sql, "DROP TABLE IF EXISTS \"%w\";\n", db_column_text(&q,0)); } db_finalize(&q); |
︙ | ︙ | |||
447 448 449 450 451 452 453 | percent_complete((processCnt*1000)/totalSize); } if( doClustering ) create_cluster(); if( ttyOutput && !g.fQuiet && totalSize>0 ){ processCnt += incrSize; percent_complete((processCnt*1000)/totalSize); } | | | 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 | percent_complete((processCnt*1000)/totalSize); } if( doClustering ) create_cluster(); if( ttyOutput && !g.fQuiet && totalSize>0 ){ processCnt += incrSize; percent_complete((processCnt*1000)/totalSize); } alert_triggers_enable(); if(!g.fQuiet && ttyOutput ){ percent_complete(1000); fossil_print("\n"); } return errCnt; } |
︙ | ︙ |
Changes to src/security_audit.c.
︙ | ︙ | |||
388 389 390 391 392 393 394 | @ %,lld(file_size(g.zErrlog, ExtFILE)) bytes in size. } } @ <li><p> User capability summary: capability_summary(); | | | 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 | @ %,lld(file_size(g.zErrlog, ExtFILE)) bytes in size. } } @ <li><p> User capability summary: capability_summary(); if( alert_enabled() ){ @ <li><p> Email alert configuration summary: @ <table class="label-value"> stats_for_email(); @ </table> }else{ @ <li><p> Email alerts are disabled } |
︙ | ︙ |
Changes to src/setup.c.
︙ | ︙ | |||
884 885 886 887 888 889 890 891 892 893 894 895 896 897 | @ to a documentation page (ex: "/doc/tip/index.wiki") or to "/timeline".</p> @ @ <p>Note: To avoid a redirect loop or other problems, this entry must @ begin with "/" and it must specify a valid page. For example, @ "<b>/home</b>" will work but "<b>home</b>" will not, since it omits the @ leading "/".</p> @ <p>(Property: "index-page") @ <hr /> onoff_attribute("Use HTML as wiki markup language", "wiki-use-html", "wiki-use-html", 0, 0); @ <p>Use HTML as the wiki markup language. Wiki links will still be parsed @ but all other wiki formatting will be ignored. This option is helpful @ if you have chosen to use a rich HTML editor for wiki markup such as @ TinyMCE.</p> | > > > > > > > > > > > > > > > > > > > > | 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 | @ to a documentation page (ex: "/doc/tip/index.wiki") or to "/timeline".</p> @ @ <p>Note: To avoid a redirect loop or other problems, this entry must @ begin with "/" and it must specify a valid page. For example, @ "<b>/home</b>" will work but "<b>home</b>" will not, since it omits the @ leading "/".</p> @ <p>(Property: "index-page") @ <hr> @ <p>Extra links to appear on the <a href="%R/sitemap">/sitemap</a> page. @ Often these are filled in with links like @ "/doc/trunk/doc/<i>filename</i>.md" so that they refer to @ embedded documentation, or like "/wiki/<i>pagename</i>" to refer @ to wiki pages. @ Leave blank to omit. @ <p> entry_attribute("Documentation Index", 40, "sitemap-docidx", "smdocidx", "", 0); @ (Property: sitemap-docidx)<br> entry_attribute("Download", 40, "sitemap-download", "smdownload", "", 0); @ (Property: sitemap-download)<br> entry_attribute("License", 40, "sitemap-license", "smlicense", "", 0); @ (Property: sitemap-license)<br> entry_attribute("Contact", 40, "sitemap-contact", "smcontact", "", 0); @ (Property: sitemap-contact) @ <hr /> onoff_attribute("Use HTML as wiki markup language", "wiki-use-html", "wiki-use-html", 0, 0); @ <p>Use HTML as the wiki markup language. Wiki links will still be parsed @ but all other wiki formatting will be ignored. This option is helpful @ if you have chosen to use a rich HTML editor for wiki markup such as @ TinyMCE.</p> |
︙ | ︙ | |||
1341 1342 1343 1344 1345 1346 1347 | const char *zQ = P("q"); int go = P("go")!=0; login_check_credentials(); if( !g.perm.Setup ){ login_needed(0); return; } | < | 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 | const char *zQ = P("q"); int go = P("go")!=0; login_check_credentials(); if( !g.perm.Setup ){ login_needed(0); return; } style_header("Raw TH1 Commands"); @ <p><b>Caution:</b> There are no restrictions on the TH1 that can be @ run by this page. If Tcl integration was enabled at compile-time and @ the "tcl" setting is enabled, Tcl commands may be run as well.</p> @ @ <form method="post" action="%s(g.zTop)/admin_th1"> login_insert_csrf_secret(); |
︙ | ︙ |
Changes to src/setupuser.c.
︙ | ︙ | |||
197 198 199 200 201 202 203 | @ Users with privilege <span class="capability">v</span> inherit the combined @ privileges of <span class="usertype">developer</span>, @ <span class="usertype">anonymous</span>, and @ <span class="usertype">nobody</span>. @ </p></li> @ @ <li><p>The permission flags are as follows:</p> | | > > > > > > > | > > > > > > > > | 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 | @ Users with privilege <span class="capability">v</span> inherit the combined @ privileges of <span class="usertype">developer</span>, @ <span class="usertype">anonymous</span>, and @ <span class="usertype">nobody</span>. @ </p></li> @ @ <li><p>The permission flags are as follows:</p> capabilities_table(CAPCLASS_ALL); @ </li> @ </ol> style_footer(); } /* ** WEBPAGE: setup_ucap_list ** ** A documentation page showing the meaning of the various user capabilities ** code letters. */ void setup_ucap_list(void){ style_header("User Capability Codes"); @ <h1>All capabilities</h1> capabilities_table(CAPCLASS_ALL); @ <h1>Capabilities associated with checked-in content</h1> capabilities_table(CAPCLASS_CODE); @ <h1>Capabilities associated with data transfer and sync</h1> capabilities_table(CAPCLASS_DATA); @ <h1>Capabilities associated with the forum</h1> capabilities_table(CAPCLASS_FORUM); @ <h1>Capabilities associated with tickets</h1> capabilities_table(CAPCLASS_TKT); @ <h1>Capabilities associated with wiki</h1> capabilities_table(CAPCLASS_WIKI); @ <h1>Administrative capabilities</h1> capabilities_table(CAPCLASS_SUPER); @ <h1>Miscellaneous capabilities</h1> capabilities_table(CAPCLASS_OTHER); style_footer(); } /* ** Return true if zPw is a valid password string. A valid ** password string is: ** |
︙ | ︙ | |||
239 240 241 242 243 244 245 | ** Edit information about a user or create a new user. ** Requires Admin privileges. */ void user_edit(void){ const char *zId, *zLogin, *zInfo, *zCap, *zPw; const char *zGroup; const char *zOldLogin; | < > | 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | ** Edit information about a user or create a new user. ** Requires Admin privileges. */ void user_edit(void){ const char *zId, *zLogin, *zInfo, *zCap, *zPw; const char *zGroup; const char *zOldLogin; int uid, i; char *zDeleteVerify = 0; /* Delete user verification text */ int higherUser = 0; /* True if user being edited is SETUP and the */ /* user doing the editing is ADMIN. Disallow editing */ const char *inherit[128]; int a[128]; const char *oa[128]; /* Must have ADMIN privileges to access this page |
︙ | ︙ | |||
268 269 270 271 272 273 274 275 276 277 278 279 | } if( P("can") ){ /* User pressed the cancel button */ cgi_redirect(cgi_referer("setup_ulist")); return; } /* If we have all the necessary information, write the new or ** modified user record. After writing the user record, redirect ** to the page that displays a list of users. */ | > > > > > > > > > > > > > > > > > > > > > > | > > | > > > > > > > | 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 | } if( P("can") ){ /* User pressed the cancel button */ cgi_redirect(cgi_referer("setup_ulist")); return; } /* Check for requests to delete the user */ if( P("delete") && cgi_csrf_safe(1) ){ int n; if( P("verifydelete") ){ /* Verified delete user request */ db_multi_exec("DELETE FROM user WHERE uid=%d", uid); cgi_redirect(cgi_referer("setup_ulist")); return; } n = db_int(0, "SELECT count(*) FROM event" " WHERE user=%Q AND objid NOT IN private", P("login")); if( n==0 ){ zDeleteVerify = mprintf("Check this box and press \"Delete User\" again"); }else{ zDeleteVerify = mprintf( "User \"%s\" has %d or more artifacts in the block-chain. " "Delete anyhow?", P("login")/*safe-for-%s*/, n); } } /* If we have all the necessary information, write the new or ** modified user record. After writing the user record, redirect ** to the page that displays a list of users. */ if( !cgi_all("login","info","pw","apply") ){ /* need all of the above properties to make a change. Since one or ** more are missing, no-op */ }else if( higherUser ){ /* An Admin (a) user cannot edit a Superuser (s) */ }else if( zDeleteVerify!=0 ){ /* Need to verify a delete request */ }else if( !cgi_csrf_safe(1) ){ /* This might be a cross-site request forgery, so ignore it */ }else{ /* We have all the information we need to make the change to the user */ char c; char zCap[70], zNm[4]; zNm[0] = 'a'; zNm[2] = 0; for(i=0, c='a'; c<='z'; c++){ zNm[1] = c; a[c&0x7f] = (c!='s' || g.perm.Setup) && P(zNm)!=0; |
︙ | ︙ | |||
558 559 560 561 562 563 564 | @ Send Announcements%s(B('A'))</label> @ <li><label><input type="checkbox" name="aD"%s(oa['D']) /> @ Enable Debug%s(B('D'))</label> @ </ul></div> @ </td> @ </tr> @ <tr> | | | 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 | @ Send Announcements%s(B('A'))</label> @ <li><label><input type="checkbox" name="aD"%s(oa['D']) /> @ Enable Debug%s(B('D'))</label> @ </ul></div> @ </td> @ </tr> @ <tr> @ <td class="usetupEditLabel">Selected Cap:</td> @ <td> @ <span id="usetupEditCapability">(missing JS?)</span> @ <a href="%R/setup_ucap_list">(key)</a> @ </td> @ </tr> if( !login_is_special(zLogin) ){ @ <tr> |
︙ | ︙ | |||
588 589 590 591 592 593 594 | @ <input type="radio" name="all" checked value="0"> @ Apply changes to this repository only.<br /> @ <input type="radio" name="all" value="1"> @ Apply changes to all repositories in the "<b>%h(zGroup)</b>" @ login group.</td></tr> } if( !higherUser ){ | > | > > > > > > > > | > > > > | 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 | @ <input type="radio" name="all" checked value="0"> @ Apply changes to this repository only.<br /> @ <input type="radio" name="all" value="1"> @ Apply changes to all repositories in the "<b>%h(zGroup)</b>" @ login group.</td></tr> } if( !higherUser ){ if( zDeleteVerify ){ @ <tr> @ <td valign="top" align="right">Verify:</td> @ <td><label><input type="checkbox" name="verifydelete">\ @ Confirm Delete \ @ <span class="loginError">← %h(zDeleteVerify)</span> @ </label></td> @ <tr> } @ <tr> @ <td> </td> @ <td><input type="submit" name="apply" value="Apply Changes"> if( !login_is_special(zLogin) ){ @ <input type="submit" name="delete" value="Delete User"> } @ <input type="submit" name="can" value="Cancel"></td> @ </tr> } @ </table> @ </div></form> @ </div> style_load_one_js_file("useredit.js"); @ <hr> |
︙ | ︙ |
Changes to src/shell.c.
︙ | ︙ | |||
2222 2223 2224 2225 2226 2227 2228 | ){ HANDLE hFindFile; WIN32_FIND_DATAW fd; LPWSTR zUnicodeName; extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*); zUnicodeName = sqlite3_win32_utf8_to_unicode(zPath); if( zUnicodeName ){ | | | 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 | ){ HANDLE hFindFile; WIN32_FIND_DATAW fd; LPWSTR zUnicodeName; extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*); zUnicodeName = sqlite3_win32_utf8_to_unicode(zPath); if( zUnicodeName ){ memset(&fd, 0, sizeof(WIN32_FIND_DATAW)); hFindFile = FindFirstFileW(zUnicodeName, &fd); if( hFindFile!=NULL ){ pStatBuf->st_ctime = (time_t)fileTimeToUnixTime(&fd.ftCreationTime); pStatBuf->st_atime = (time_t)fileTimeToUnixTime(&fd.ftLastAccessTime); pStatBuf->st_mtime = (time_t)fileTimeToUnixTime(&fd.ftLastWriteTime); FindClose(hFindFile); } |
︙ | ︙ | |||
3311 3312 3313 3314 3315 3316 3317 | completionCursorReset(pCur); if( idxNum & 1 ){ pCur->nPrefix = sqlite3_value_bytes(argv[iArg]); if( pCur->nPrefix>0 ){ pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg])); if( pCur->zPrefix==0 ) return SQLITE_NOMEM; } | | < | 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 | completionCursorReset(pCur); if( idxNum & 1 ){ pCur->nPrefix = sqlite3_value_bytes(argv[iArg]); if( pCur->nPrefix>0 ){ pCur->zPrefix = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg])); if( pCur->zPrefix==0 ) return SQLITE_NOMEM; } iArg = 1; } if( idxNum & 2 ){ pCur->nLine = sqlite3_value_bytes(argv[iArg]); if( pCur->nLine>0 ){ pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg])); if( pCur->zLine==0 ) return SQLITE_NOMEM; } } if( pCur->zLine!=0 && pCur->zPrefix==0 ){ int i = pCur->nLine; while( i>0 && (isalnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){ i--; } pCur->nPrefix = pCur->nLine - i; |
︙ | ︙ |
Changes to src/sitemap.c.
︙ | ︙ | |||
27 28 29 30 31 32 33 34 35 | ** List some of the web pages offered by the Fossil web engine. This ** page is intended as a supplement to the menu bar on the main screen. ** That is, this page is designed to hold links that are omitted from ** the main menu due to lack of space. */ void sitemap_page(void){ int srchFlags; login_check_credentials(); srchFlags = search_restrict(SRCH_ALL); | > > > > > > > > > > > > > > > > > > > > > | | < > > | < < < < > > > | | > > > | > > > > > | > > | > > | > | > | > | > < < < < | | | > | > | < < < < | < < < | | > > > | > > > > > > > | > | > > > > | > | > > > > > > > > > > > > > > > > > > > > > > > | > > | 27 28 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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 | ** List some of the web pages offered by the Fossil web engine. This ** page is intended as a supplement to the menu bar on the main screen. ** That is, this page is designed to hold links that are omitted from ** the main menu due to lack of space. */ void sitemap_page(void){ int srchFlags; int inSublist = 0; int i; int isPopup = 0; /* This is an XMLHttpRequest() for /sitemap */ const struct { const char *zTitle; const char *zProperty; } aExtra[] = { { "Documentation", "sitemap-docidx" }, { "Download", "sitemap-download" }, { "License", "sitemap-license" }, { "Contact", "sitemap-contact" }, }; login_check_credentials(); if( P("popup")!=0 && cgi_csrf_safe(1) ){ /* If this is a POST from the same origin with the popup=1 parameter, ** then disable anti-robot defenses */ isPopup = 1; g.perm.Hyperlink = 1; g.javascriptHyperlink = 0; } srchFlags = search_restrict(SRCH_ALL); if( !isPopup ){ style_header("Site Map"); style_adunit_config(ADUNIT_RIGHT_OK); } @ <ul id="sitemap" class="columns" style="column-width:20em"> @ <li>%z(href("%R/home"))Home Page</a> for(i=0; i<sizeof(aExtra)/sizeof(aExtra[0]); i++){ char *z = db_get(aExtra[i].zProperty,0); if( z==0 || z[0]==0 ) continue; if( !inSublist ){ @ <ul> inSublist = 1; } if( z[0]=='/' ){ @ <li>%z(href("%R%s",z))%s(aExtra[i].zTitle)</a></li> }else{ @ <li>%z(href("%s",z))%s(aExtra[i].zTitle)</a></li> } } if( srchFlags & SRCH_DOC ){ if( !inSublist ){ @ <ul> inSublist = 1; } @ <li>%z(href("%R/docsrch"))Documentation Search</a></li> } if( inSublist ){ @ </ul> inSublist = 0; } @ </li> if( g.perm.Read ){ @ <li>%z(href("%R/tree"))File Browser</a> @ <ul> @ <li>%z(href("%R/tree?type=tree&ci=trunk"))Tree-view, @ Trunk Check-in</a></li> @ <li>%z(href("%R/tree?type=flat"))Flat-view</a></li> @ <li>%z(href("%R/fileage?name=trunk"))File ages for Trunk</a></li> @ <li>%z(href("%R/uvlist"))Unversioned Files</a> @ </ul> } if( g.perm.Read ){ @ <li>%z(href("%R/timeline"))Project Timeline</a> @ <ul> @ <li>%z(href("%R/reports"))Activity Reports</a></li> @ <li>%z(href("%R/timeline?n=all&namechng"))File name changes</a></li> @ <li>%z(href("%R/timeline?n=all&forks"))Forks</a></li> @ <li>%z(href("%R/timeline?a=1970-01-01&y=ci&n=10"))First 10 @ check-ins</a></li> @ </ul> @ </li> } if( g.perm.Read ){ @ <li>%z(href("%R/brlist"))Branches</a> @ <ul> @ <li>%z(href("%R/taglist"))Tags</a></li> @ <li>%z(href("%R/leaves"))Leaf Check-ins</a></li> @ </ul> @ </li> } if( srchFlags ){ @ <li>%z(href("%R/search"))Search</a></li> } if( g.perm.RdForum ){ @ <li>%z(href("%R/forum"))Forum</a> @ <ul> @ <li>%z(href("%R/timeline?y=f"))Recent activity</a></li> @ </ul> @ </li> } if( g.perm.RdTkt ){ @ <li>%z(href("%R/reportlist"))Tickets</a> @ <ul> if( srchFlags & SRCH_TKT ){ @ <li>%z(href("%R/tktsrch"))Ticket Search</a></li> } @ <li>%z(href("%R/timeline?y=t"))Recent activity</a></li> @ <li>%z(href("%R/attachlist"))List of Attachments</a></li> @ </ul> @ </li> } if( g.perm.RdWiki ){ @ <li>%z(href("%R/wikihelp"))Wiki</a> @ <ul> if( srchFlags & SRCH_WIKI ){ @ <li>%z(href("%R/wikisrch"))Wiki Search</a></li> } @ <li>%z(href("%R/wcontent"))List of Wiki Pages</a></li> @ <li>%z(href("%R/timeline?y=w"))Recent activity</a></li> @ <li>%z(href("%R/wiki?name=Sandbox"))Sandbox</a></li> @ <li>%z(href("%R/attachlist"))List of Attachments</a></li> @ </ul> @ </li> } if( !g.zLogin ){ @ <li>%z(href("%R/login"))Login</a> if( login_self_register_available(0) ){ @ <ul> @ <li>%z(href("%R/register"))Create a new account</a></li> inSublist = 1; } }else { @ <li>%z(href("%R/logout"))Logout</a> if( g.perm.Password ){ @ <ul> @ <li>%z(href("%R/logout"))Change Password</a></li> inSublist = 1; } } if( alert_enabled() && g.perm.EmailAlert ){ if( !inSublist ){ inSublist = 1; @ <ul> } if( login_is_individual() ){ @ <li>%z(href("%R/alerts"))Email Alerts</a></li> }else{ @ <li>%z(href("%R/subscribe"))Subscribe to Email Alerts</a></li> } } if( inSublist ){ @ </ul> inSublist = 0; } @ </li> if( g.perm.Read ){ @ <li>%z(href("%R/stat"))Repository Status</a> @ <ul> @ <li>%z(href("%R/hash-collisions"))Collisions on hash prefixes</a></li> if( g.perm.Admin ){ @ <li>%z(href("%R/urllist"))List of URLs used to access @ this repository</a></li> } @ <li>%z(href("%R/bloblist"))List of Artifacts</a></li> @ <li>%z(href("%R/timewarps"))List of "Timewarp" Check-ins</a></li> @ </ul> @ </li> } @ <li>Help @ <ul> @ <li>%z(href("%R/wiki_rules"))Wiki Formatting Rules</a></li> @ <li>%z(href("%R/md_rules"))Markdown Formatting Rules</a></li> @ <li>%z(href("%R/help"))List of All Commands and Web Pages</a></li> @ <li>%z(href("%R/test-all-help"))All "help" text on a single page</a></li> @ <li>%z(href("%R/mimetype_list"))Filename suffix to mimetype map</a></li> @ </ul></li> if( g.perm.Admin ){ @ <li>%z(href("%R/setup"))Administration Pages</a> @ <ul> |
︙ | ︙ | |||
148 149 150 151 152 153 154 | if( g.perm.Read ){ @ <li>%z(href("%R/test-rename-list"))List of file renames</a></li> } @ <li>%z(href("%R/hash-color-test"))Page to experiment with the automatic @ colors assigned to branch names</a> @ <li>%z(href("%R/test-captcha"))Random ASCII-art Captcha image</a></li> @ </ul></li> | | > | | > | 217 218 219 220 221 222 223 224 225 226 227 228 | if( g.perm.Read ){ @ <li>%z(href("%R/test-rename-list"))List of file renames</a></li> } @ <li>%z(href("%R/hash-color-test"))Page to experiment with the automatic @ colors assigned to branch names</a> @ <li>%z(href("%R/test-captcha"))Random ASCII-art Captcha image</a></li> @ </ul></li> @ </ul> if( !isPopup ){ style_footer(); } } |
Changes to src/skins.c.
︙ | ︙ | |||
53 54 55 56 57 58 59 | { "Black & White, Menu on Left", "black_and_white", 0 }, { "Plain Gray, No Logo", "plain_gray", 0 }, { "Khaki, No Logo", "khaki", 0 }, { "Ardoise", "ardoise", 0 }, }; /* | | | > > | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | { "Black & White, Menu on Left", "black_and_white", 0 }, { "Plain Gray, No Logo", "plain_gray", 0 }, { "Khaki, No Logo", "khaki", 0 }, { "Ardoise", "ardoise", 0 }, }; /* ** A skin consists of five "files" named here: */ static const char *azSkinFile[] = { "css", "header", "footer", "details", "js" }; /* ** Alternative skins can be specified in the CGI script or by options ** on the "http", "ui", and "server" commands. The alternative skin ** name must be one of the aBuiltinSkin[].zLabel names. If there is ** a match, that alternative is used. ** |
︙ | ︙ | |||
147 148 149 150 151 152 153 | iDraftSkin = i; } /* ** The following routines return the various components of the skin ** that should be used for the current run. ** | | | 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | iDraftSkin = i; } /* ** The following routines return the various components of the skin ** that should be used for the current run. ** ** zWhat is one of: "css", "header", "footer", "details", "js" */ const char *skin_get(const char *zWhat){ const char *zOut; char *z; if( iDraftSkin ){ z = mprintf("draft%d-%s", iDraftSkin, zWhat); zOut = db_get(z, 0); |
︙ | ︙ | |||
478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 | @ be undone. Please confirm that this is what you want to do:</p> @ <input type="hidden" name="sn" value="%h(P("sn"))" /> @ <input type="submit" name="del2" value="Confirm - Delete The Skin" /> @ <input type="submit" name="cancel" value="Cancel - Do Not Delete" /> login_insert_csrf_secret(); @ </div></form> style_footer(); return; } if( P("del2")!=0 && (zName = skinVarName(P("sn"), 1))!=0 ){ db_multi_exec("DELETE FROM config WHERE name=%Q", zName); } if( P("draftdel")!=0 ){ const char *zDraft = P("name"); if( sqlite3_strglob("draft[1-9]",zDraft)==0 ){ db_multi_exec("DELETE FROM config WHERE name GLOB '%q-*'", zDraft); } } | > | > | > | 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 | @ be undone. Please confirm that this is what you want to do:</p> @ <input type="hidden" name="sn" value="%h(P("sn"))" /> @ <input type="submit" name="del2" value="Confirm - Delete The Skin" /> @ <input type="submit" name="cancel" value="Cancel - Do Not Delete" /> login_insert_csrf_secret(); @ </div></form> style_footer(); db_end_transaction(1); return; } if( P("del2")!=0 && (zName = skinVarName(P("sn"), 1))!=0 ){ db_multi_exec("DELETE FROM config WHERE name=%Q", zName); } if( P("draftdel")!=0 ){ const char *zDraft = P("name"); if( sqlite3_strglob("draft[1-9]",zDraft)==0 ){ db_multi_exec("DELETE FROM config WHERE name GLOB '%q-*'", zDraft); } } if( skinRename() || skinSave(zCurrent) ){ db_end_transaction(0); return; } /* The user pressed one of the "Install" buttons. */ if( P("load") && (z = P("sn"))!=0 && z[0] ){ int seen = 0; /* Check to see if the current skin is already saved. If it is, there ** is no need to create a backup */ |
︙ | ︙ | |||
686 687 688 689 690 691 692 | /* ** WEBPAGE: setup_skinedit ** ** Edit aspects of a skin determined by the w= query parameter. ** Requires Setup privileges. ** | | > > > > | 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 | /* ** WEBPAGE: setup_skinedit ** ** Edit aspects of a skin determined by the w= query parameter. ** Requires Setup privileges. ** ** w=NUM -- 0=CSS, 1=footer, 2=header, 3=details, 4=js ** sk=NUM -- the draft skin number */ void setup_skinedit(void){ static const struct sSkinAddr { const char *zFile; const char *zTitle; const char *zSubmenu; } aSkinAttr[] = { /* 0 */ { "css", "CSS", "CSS", }, /* 1 */ { "footer", "Page Footer", "Footer", }, /* 2 */ { "header", "Page Header", "Header", }, /* 3 */ { "details", "Display Details", "Details", }, /* 4 */ { "js", "JavaScript", "Script", }, }; const char *zBasis; /* The baseline file */ const char *zOrig; /* Original content prior to editing */ const char *zContent; /* Content after editing */ const char *zDflt; /* Default content */ char *zDraft; /* Which draft: "draft%d" */ char *zKey; /* CONFIG table key name: "draft%d-%s" */ char *zTitle; /* Title of this page */ const char *zFile; /* One of "css", "footer", "header", "details" */ int iSkin; /* draft number. 1..9 */ int ii; /* Index in aSkinAttr[] of this file */ int j; /* Loop counter */ int isRevert = 0; /* True if Revert-to-Baseline was pressed */ login_check_credentials(); /* Figure out which skin we are editing */ iSkin = atoi(PD("sk","1")); if( iSkin<1 || iSkin>9 ) iSkin = 1; |
︙ | ︙ | |||
743 744 745 746 747 748 749 750 751 752 753 | ii = atoi(PD("w","0")); if( ii<0 || ii>count(aSkinAttr) ) ii = 0; zFile = aSkinAttr[ii].zFile; zDraft = mprintf("draft%d", iSkin); zKey = mprintf("draft%d-%s", iSkin, zFile); zTitle = mprintf("%s for Draft%d", aSkinAttr[ii].zTitle, iSkin); zBasis = PD("basis","current"); db_begin_transaction(); style_header("%s", zTitle); for(j=0; j<count(aSkinAttr); j++){ | > > > > > > > < > | < < > | < | < < > > > > > | 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 | ii = atoi(PD("w","0")); if( ii<0 || ii>count(aSkinAttr) ) ii = 0; zFile = aSkinAttr[ii].zFile; zDraft = mprintf("draft%d", iSkin); zKey = mprintf("draft%d-%s", iSkin, zFile); zTitle = mprintf("%s for Draft%d", aSkinAttr[ii].zTitle, iSkin); zBasis = PD("basis","current"); zDflt = skin_file_content(zBasis, zFile); zOrig = db_get(zKey, zDflt); zContent = PD(zFile,zOrig); if( P("revert")!=0 && cgi_csrf_safe(0) ){ zContent = zDflt; isRevert = 1; } db_begin_transaction(); style_header("%s", zTitle); for(j=0; j<count(aSkinAttr); j++){ style_submenu_element(aSkinAttr[j].zSubmenu, "%R/setup_skinedit?w=%d&basis=%h&sk=%d",j,zBasis,iSkin); } @ <form action="%s(g.zTop)/setup_skinedit" method="post"><div> login_insert_csrf_secret(); @ <input type='hidden' name='w' value='%d(ii)'> @ <input type='hidden' name='sk' value='%d(iSkin)'> @ <h2>Edit %s(zTitle):</h2> if( P("submit") && cgi_csrf_safe(0) && strcmp(zOrig,zContent)!=0 ){ db_set(zKey, zContent, 0); } @ <textarea name="%s(zFile)" rows="10" cols="80">\ @ %h(zContent)</textarea> @ <br /> @ <input type="submit" name="submit" value="Apply Changes" /> if( isRevert ){ @ ← Press to complete reversion to "%s(zBasis)" }else if( fossil_strcmp(zContent,zDflt)!=0 ){ @ <input type="submit" name="revert" value='Revert To "%s(zBasis)"' /> } @ <hr /> @ Baseline: \ skin_emit_skin_selector("basis", zBasis, zDraft); @ <input type="submit" name="diff" value="Unified Diff" /> @ <input type="submit" name="sbsdiff" value="Side-by-Side Diff" /> if( P("diff")!=0 || P("sbsdiff")!=0 ){ u64 diffFlags = construct_diff_flags(1) | DIFF_STRIP_EOLCR; |
︙ | ︙ | |||
1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 | @ <li><a href='%R/setup_skinedit?w=0&sk=%d(iSkin)' target='_blank'>CSS</a> @ <li><a href='%R/setup_skinedit?w=2&sk=%d(iSkin)' target='_blank'>\ @ Header</a> @ <li><a href='%R/setup_skinedit?w=1&sk=%d(iSkin)' target='_blank'>\ @ Footer</a> @ <li><a href='%R/setup_skinedit?w=3&sk=%d(iSkin)' target='_blank'>\ @ Details</a> @ </ul> } @ @ <a name='step5'></a> @ <h1>Step 5: Verify The Draft Skin</h1> @ @ <p>To test this draft skin, insert text "/draft%d(iSkin)/" just before the | > > | 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 | @ <li><a href='%R/setup_skinedit?w=0&sk=%d(iSkin)' target='_blank'>CSS</a> @ <li><a href='%R/setup_skinedit?w=2&sk=%d(iSkin)' target='_blank'>\ @ Header</a> @ <li><a href='%R/setup_skinedit?w=1&sk=%d(iSkin)' target='_blank'>\ @ Footer</a> @ <li><a href='%R/setup_skinedit?w=3&sk=%d(iSkin)' target='_blank'>\ @ Details</a> @ <li><a href='%R/setup_skinedit?w=4&sk=%d(iSkin)' target='_blank'>\ @ Javascript</a> (optional) @ </ul> } @ @ <a name='step5'></a> @ <h1>Step 5: Verify The Draft Skin</h1> @ @ <p>To test this draft skin, insert text "/draft%d(iSkin)/" just before the |
︙ | ︙ |
Changes to src/sqlite3.c.
more than 10,000 changes
Changes to src/sqlite3.h.
︙ | ︙ | |||
121 122 123 124 125 126 127 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.25.0" #define SQLITE_VERSION_NUMBER 3025000 | | | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.25.0" #define SQLITE_VERSION_NUMBER 3025000 #define SQLITE_SOURCE_ID "2018-09-10 19:34:06 74c381b573817d0212153278b5ee5d2238a27a727dcf7ee769365c47bb9fc40d" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
︙ | ︙ | |||
468 469 470 471 472 473 474 475 476 477 478 479 480 481 | ** on a per database connection basis using the ** [sqlite3_extended_result_codes()] API. Or, the extended code for ** the most recent error can be obtained using ** [sqlite3_extended_errcode()]. */ #define SQLITE_ERROR_MISSING_COLLSEQ (SQLITE_ERROR | (1<<8)) #define SQLITE_ERROR_RETRY (SQLITE_ERROR | (2<<8)) #define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) #define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) #define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) #define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) #define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) #define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8)) #define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8)) | > | 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 | ** on a per database connection basis using the ** [sqlite3_extended_result_codes()] API. Or, the extended code for ** the most recent error can be obtained using ** [sqlite3_extended_errcode()]. */ #define SQLITE_ERROR_MISSING_COLLSEQ (SQLITE_ERROR | (1<<8)) #define SQLITE_ERROR_RETRY (SQLITE_ERROR | (2<<8)) #define SQLITE_ERROR_SNAPSHOT (SQLITE_ERROR | (3<<8)) #define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8)) #define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8)) #define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8)) #define SQLITE_IOERR_FSYNC (SQLITE_IOERR | (4<<8)) #define SQLITE_IOERR_DIR_FSYNC (SQLITE_IOERR | (5<<8)) #define SQLITE_IOERR_TRUNCATE (SQLITE_IOERR | (6<<8)) #define SQLITE_IOERR_FSTAT (SQLITE_IOERR | (7<<8)) |
︙ | ︙ | |||
6436 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 | #define SQLITE_INDEX_CONSTRAINT_GLOB 66 #define SQLITE_INDEX_CONSTRAINT_REGEXP 67 #define SQLITE_INDEX_CONSTRAINT_NE 68 #define SQLITE_INDEX_CONSTRAINT_ISNOT 69 #define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70 #define SQLITE_INDEX_CONSTRAINT_ISNULL 71 #define SQLITE_INDEX_CONSTRAINT_IS 72 /* ** CAPI3REF: Register A Virtual Table Implementation ** METHOD: sqlite3 ** ** ^These routines are used to register a new [virtual table module] name. ** ^Module names must be registered before | > | 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 | #define SQLITE_INDEX_CONSTRAINT_GLOB 66 #define SQLITE_INDEX_CONSTRAINT_REGEXP 67 #define SQLITE_INDEX_CONSTRAINT_NE 68 #define SQLITE_INDEX_CONSTRAINT_ISNOT 69 #define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70 #define SQLITE_INDEX_CONSTRAINT_ISNULL 71 #define SQLITE_INDEX_CONSTRAINT_IS 72 #define SQLITE_INDEX_CONSTRAINT_FUNCTION 150 /* ** CAPI3REF: Register A Virtual Table Implementation ** METHOD: sqlite3 ** ** ^These routines are used to register a new [virtual table module] name. ** ^Module names must be registered before |
︙ | ︙ | |||
9048 9049 9050 9051 9052 9053 9054 | ** must have no active statements (SELECT statements that have been passed ** to sqlite3_step() but not sqlite3_reset() or sqlite3_finalize()). ** SQLITE_ERROR is returned if either of these conditions is violated, or ** if schema S does not exist, or if the snapshot object is invalid. ** ** ^A call to sqlite3_snapshot_open() will fail to open if the specified ** snapshot has been overwritten by a [checkpoint]. In this case | | | | 9050 9051 9052 9053 9054 9055 9056 9057 9058 9059 9060 9061 9062 9063 9064 9065 9066 9067 9068 | ** must have no active statements (SELECT statements that have been passed ** to sqlite3_step() but not sqlite3_reset() or sqlite3_finalize()). ** SQLITE_ERROR is returned if either of these conditions is violated, or ** if schema S does not exist, or if the snapshot object is invalid. ** ** ^A call to sqlite3_snapshot_open() will fail to open if the specified ** snapshot has been overwritten by a [checkpoint]. In this case ** SQLITE_ERROR_SNAPSHOT is returned. ** ** If there is already a read transaction open when this function is ** invoked, then the same read transaction remains open (on the same ** database snapshot) if SQLITE_ERROR, SQLITE_BUSY or SQLITE_ERROR_SNAPSHOT ** is returned. If another error code - for example SQLITE_PROTOCOL or an ** SQLITE_IOERR error code - is returned, then the final state of the ** read transaction is undefined. If SQLITE_OK is returned, then the ** read transaction is now open on database snapshot P. ** ** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the ** database connection D does not know that the database file for |
︙ | ︙ |
Changes to src/stat.c.
︙ | ︙ | |||
268 269 270 271 272 273 274 | } @ </td></tr> } if( g.perm.Admin ){ @ <tr><th>Backoffice:</th> @ <td>Last run: %z(backoffice_last_run())</td></tr> } | | | 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 | } @ </td></tr> } if( g.perm.Admin ){ @ <tr><th>Backoffice:</th> @ <td>Last run: %z(backoffice_last_run())</td></tr> } if( g.perm.Admin && alert_enabled() ){ stats_for_email(); } @ </table> style_footer(); } |
︙ | ︙ |
Changes to src/style.c.
︙ | ︙ | |||
84 85 86 87 88 89 90 91 92 93 94 95 96 97 | /* ** Flags for various javascript files needed prior to </body> */ static int needHrefJs = 0; /* href.js */ static int needSortJs = 0; /* sorttable.js */ static int needGraphJs = 0; /* graph.js */ /* ** Generate and return a anchor tag like this: ** ** <a href="URL"> ** or <a id="ID"> ** ** The form of the anchor tag is determined by the g.javascriptHyperlink | > > > > > | 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | /* ** Flags for various javascript files needed prior to </body> */ static int needHrefJs = 0; /* href.js */ static int needSortJs = 0; /* sorttable.js */ static int needGraphJs = 0; /* graph.js */ /* ** Extra JS added to the end of the file. */ static Blob blobOnLoad = BLOB_INITIALIZER; /* ** Generate and return a anchor tag like this: ** ** <a href="URL"> ** or <a id="ID"> ** ** The form of the anchor tag is determined by the g.javascriptHyperlink |
︙ | ︙ | |||
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 | static void image_url_var(const char *zImageName){ char *zVarPrefix = mprintf("%s_image", zImageName); char *zConfigName = mprintf("%s-image", zImageName); url_var(zVarPrefix, zConfigName, zImageName); free(zVarPrefix); free(zConfigName); } /* ** Default HTML page header text through <body>. If the repository-specific ** header template lacks a <body> tag, then all of the following is ** prepended. */ static char zDfltHeader[] = @ <html> @ <head> @ <base href="$baseurl/$current_page" /> @ <meta http-equiv="Content-Security-Policy" \ | > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 | static void image_url_var(const char *zImageName){ char *zVarPrefix = mprintf("%s_image", zImageName); char *zConfigName = mprintf("%s-image", zImageName); url_var(zVarPrefix, zConfigName, zImageName); free(zVarPrefix); free(zConfigName); } /* ** Return a random nonce that is stored in static space. For a particular ** run, the same nonce is always returned. */ char *style_nonce(void){ static char zNonce[52]; if( zNonce[0]==0 ){ unsigned char zSeed[24]; sqlite3_randomness(24, zSeed); encode16(zSeed,(unsigned char*)zNonce,24); } return zNonce; } /* ** Default HTML page header text through <body>. If the repository-specific ** header template lacks a <body> tag, then all of the following is ** prepended. */ static char zDfltHeader[] = @ <html> @ <head> @ <base href="$baseurl/$current_page" /> @ <meta http-equiv="Content-Security-Policy" \ @ content="default-src 'self' data: ; \ @ script-src 'self' 'nonce-$<nonce>' ;\ @ style-src 'self' 'unsafe-inline'" /> @ <meta name="viewport" content="width=device-width, initial-scale=1.0"> @ <title>$<project_name>: $<title></title> @ <link rel="alternate" type="application/rss+xml" title="RSS Feed" \ @ href="$home/timeline.rss" /> @ <link rel="stylesheet" href="$stylesheet_url" type="text/css" \ @ media="screen" /> @ </head> @ <body> ; /* ** Initialize all the default TH1 variables */ static void style_init_th1_vars(const char *zTitle){ Th_Store("nonce", style_nonce()); Th_Store("project_name", db_get("project-name","Unnamed Fossil Project")); Th_Store("project_description", db_get("project-description","")); if( zTitle ) Th_Store("title", zTitle); Th_Store("baseurl", g.zBaseURL); Th_Store("secureurl", login_wants_https_redirect()? g.zHttpsURL: g.zBaseURL); Th_Store("home", g.zTop); Th_Store("index_page", db_get("index-page","/home")); if( local_zCurrentPage==0 ) style_set_current_page("%T", g.zPath); Th_Store("current_page", local_zCurrentPage); Th_Store("csrf_token", g.zCsrfToken); Th_Store("release_version", RELEASE_VERSION); Th_Store("manifest_version", MANIFEST_VERSION); Th_Store("manifest_date", MANIFEST_DATE); Th_Store("compiler_name", COMPILER_NAME); url_var("stylesheet", "css", "style.css"); image_url_var("logo"); image_url_var("background"); if( !login_is_nobody() ){ Th_Store("login", g.zLogin); } } /* ** Draw the header. */ void style_header(const char *zTitleFormat, ...){ va_list ap; char *zTitle; |
︙ | ︙ | |||
400 401 402 403 404 405 406 | cgi_destination(CGI_HEADER); @ <!DOCTYPE html> if( g.thTrace ) Th_Trace("BEGIN_HEADER<br />\n", -1); /* Generate the header up through the main menu */ | < < | < < < < < < < < < < < < < < < < < | 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 | cgi_destination(CGI_HEADER); @ <!DOCTYPE html> if( g.thTrace ) Th_Trace("BEGIN_HEADER<br />\n", -1); /* Generate the header up through the main menu */ style_init_th1_vars(zTitle); if( sqlite3_strlike("%<body%", zHeader, 0)!=0 ){ Th_Render(zDfltHeader); } if( g.thTrace ) Th_Trace("BEGIN_HEADER_SCRIPT<br />\n", -1); Th_Render(zHeader); if( g.thTrace ) Th_Trace("END_HEADER<br />\n", -1); Th_Unstore("title"); /* Avoid collisions with ticket field names */ |
︙ | ︙ | |||
521 522 523 524 525 526 527 | */ void style_load_js(const char *zName){ int i; for(i=0; i<nJsToLoad; i++){ if( fossil_strcmp(zName, azJsToLoad[i])==0 ) return; } if( nJsToLoad>=sizeof(azJsToLoad)/sizeof(azJsToLoad[0]) ){ | | > > > | | | | > > > > > > > > > > > > > > > > | 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 | */ void style_load_js(const char *zName){ int i; for(i=0; i<nJsToLoad; i++){ if( fossil_strcmp(zName, azJsToLoad[i])==0 ) return; } if( nJsToLoad>=sizeof(azJsToLoad)/sizeof(azJsToLoad[0]) ){ fossil_panic("too many JS files"); } azJsToLoad[nJsToLoad++] = zName; } /* ** Generate code to load all required javascript files. */ static void style_load_all_js_files(void){ int i; if( needHrefJs ){ int nDelay = db_get_int("auto-hyperlink-delay",0); int bMouseover; /* Load up the page data */ bMouseover = (!g.isHuman || db_get_boolean("auto-hyperlink-ishuman",0)) && db_get_boolean("auto-hyperlink-mouseover",0); @ <script id='href-data' type='application/json'>\ @ {"delay":%d(nDelay),"mouseover":%d(bMouseover)}</script> } @ <script nonce="%h(style_nonce())"> if( needHrefJs ){ cgi_append_content(builtin_text("href.js"),-1); } if( needSortJs ){ cgi_append_content(builtin_text("sorttable.js"),-1); } if( needGraphJs ){ cgi_append_content(builtin_text("graph.js"),-1); } for(i=0; i<nJsToLoad; i++){ cgi_append_content(builtin_text(azJsToLoad[i]),-1); } if( blob_size(&blobOnLoad)>0 ){ @ window.onload = function(){ cgi_append_content(blob_buffer(&blobOnLoad), blob_size(&blobOnLoad)); cgi_append_content("\n}\n", -1); } @ </script> } /* ** Extra JS to run after all content is loaded. */ void style_js_onload(const char *zFormat, ...){ va_list ap; va_start(ap, zFormat); blob_vappendf(&blobOnLoad, zFormat, ap); va_end(ap); } /* ** Draw the footer at the bottom of the page. */ void style_footer(void){ const char *zFooter; |
︙ | ︙ | |||
805 806 807 808 809 810 811 812 813 814 815 816 817 818 | if( g.argc!=4 ) usage("FILENAME SELECTOR"); blob_read_from_file(&css, g.argv[2], ExtFILE); zSelector = g.argv[3]; found = containsSelector(blob_str(&css), zSelector); fossil_print("%s %s\n", zSelector, found ? "found" : "not found"); blob_reset(&css); } /* ** WEBPAGE: style.css ** ** Return the style sheet. */ | > > > > > > > > > > > > > > > > > > > | 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 | if( g.argc!=4 ) usage("FILENAME SELECTOR"); blob_read_from_file(&css, g.argv[2], ExtFILE); zSelector = g.argv[3]; found = containsSelector(blob_str(&css), zSelector); fossil_print("%s %s\n", zSelector, found ? "found" : "not found"); blob_reset(&css); } /* ** WEBPAGE: script.js ** ** Return the "Javascript" content for the current skin (if there is any) */ void page_script_js(void){ const char *zScript = skin_get("js"); if( P("test") ){ /* Render the script as plain-text for testing purposes, if the "test" ** query parameter is present */ cgi_set_content_type("text/plain"); }else{ /* Default behavior is to return javascript */ cgi_set_content_type("application/javascript"); } style_init_th1_vars(0); Th_Render(zScript?zScript:""); } /* ** WEBPAGE: style.css ** ** Return the style sheet. */ |
︙ | ︙ |
Changes to src/th_main.c.
︙ | ︙ | |||
1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 | Th_SetResult(interp, 0, 0); return TH_OK; }else{ Th_SetResult(interp, "repository unavailable", -1); return TH_ERROR; } } /* ** TH1 command: artifact ID ?FILENAME? ** ** Attempts to locate the specified artifact and return its contents. An ** error is generated if the repository is not open or the artifact cannot ** be found. | > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 | Th_SetResult(interp, 0, 0); return TH_OK; }else{ Th_SetResult(interp, "repository unavailable", -1); return TH_ERROR; } } /* ** TH1 command: styleScript ** ** Render the configured javascript for the selected skin */ static int styleScriptCmd( Th_Interp *interp, void *p, int argc, const char **argv, int *argl ){ if( argc!=1 ){ return Th_WrongNumArgs(interp, "styleScript"); } if( Th_IsRepositoryOpen() ){ const char *zScript = skin_get("js"); if( zScript==0 ) zScript = ""; Th_Render(zScript); Th_SetResult(interp, 0, 0); return TH_OK; }else{ Th_SetResult(interp, "repository unavailable", -1); return TH_ERROR; } } /* ** TH1 command: artifact ID ?FILENAME? ** ** Attempts to locate the specified artifact and return its contents. An ** error is generated if the repository is not open or the artifact cannot ** be found. |
︙ | ︙ | |||
1982 1983 1984 1985 1986 1987 1988 1989 | {"regexp", regexpCmd, 0}, {"reinitialize", reinitializeCmd, 0}, {"render", renderCmd, 0}, {"repository", repositoryCmd, 0}, {"searchable", searchableCmd, 0}, {"setParameter", setParameterCmd, 0}, {"setting", settingCmd, 0}, {"styleHeader", styleHeaderCmd, 0}, | > | | 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 | {"regexp", regexpCmd, 0}, {"reinitialize", reinitializeCmd, 0}, {"render", renderCmd, 0}, {"repository", repositoryCmd, 0}, {"searchable", searchableCmd, 0}, {"setParameter", setParameterCmd, 0}, {"setting", settingCmd, 0}, {"styleFooter", styleFooterCmd, 0}, {"styleHeader", styleHeaderCmd, 0}, {"styleScript", styleScriptCmd, 0}, {"tclReady", tclReadyCmd, 0}, {"trace", traceCmd, 0}, {"stime", stimeCmd, 0}, {"unversioned", unversionedCmd, 0}, {"utime", utimeCmd, 0}, {"verifyCsrf", verifyCsrfCmd, 0}, {"wiki", wikiCmd, (void*)&aFlags[0]}, |
︙ | ︙ |
Changes to test/commit-warning.test.
︙ | ︙ | |||
159 160 161 162 163 164 165 | # TODO: Change to a collection of test-case crafted files # rather than depend on this list of files that will # be fragile as development progresses. # # Unless the real goal of this test is to document a collection # of source files that MUST NEVER BE TEXT. # | | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 | # TODO: Change to a collection of test-case crafted files # rather than depend on this list of files that will # be fragile as development progresses. # # Unless the real goal of this test is to document a collection # of source files that MUST NEVER BE TEXT. # test_block_in_checkout pre-commit-warnings-fossil-1 { fossil test-commit-warning --no-settings } { test pre-commit-warnings-fossil-1 {[normalize_result] eq \ [subst -nocommands -novariables [string trim { 1\tart/branching.odp\tbinary data 1\tart/concept1.dia\tbinary data 1\tart/concept2.dia\tbinary data 1\tcompat/zlib/contrib/blast/test.pk\tbinary data 1\tcompat/zlib/contrib/dotzlib/DotZLib.build\tCR/LF line endings 1\tcompat/zlib/contrib/dotzlib/DotZLib.chm\tbinary data 1\tcompat/zlib/contrib/dotzlib/DotZLib.sln\tCR/LF line endings 1\tcompat/zlib/contrib/dotzlib/DotZLib/AssemblyInfo.cs\tCR/LF line endings 1\tcompat/zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs\tinvalid UTF-8 1\tcompat/zlib/contrib/dotzlib/DotZLib/CircularBuffer.cs\tinvalid UTF-8 1\tcompat/zlib/contrib/dotzlib/DotZLib/CodecBase.cs\tinvalid UTF-8 1\tcompat/zlib/contrib/dotzlib/DotZLib/Deflater.cs\tinvalid UTF-8 1\tcompat/zlib/contrib/dotzlib/DotZLib/DotZLib.cs\tinvalid UTF-8 1\tcompat/zlib/contrib/dotzlib/DotZLib/DotZLib.csproj\tCR/LF line endings 1\tcompat/zlib/contrib/dotzlib/DotZLib/GZipStream.cs\tinvalid UTF-8 1\tcompat/zlib/contrib/dotzlib/DotZLib/Inflater.cs\tinvalid UTF-8 1\tcompat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs\tCR/LF line endings 1\tcompat/zlib/contrib/dotzlib/LICENSE_1_0.txt\tCR/LF line endings 1\tcompat/zlib/contrib/dotzlib/readme.txt\tCR/LF line endings 1\tcompat/zlib/contrib/gcc_gvmat64/gvmat64.S\tCR/LF line endings 1\tcompat/zlib/contrib/masmx64/bld_ml64.bat\tCR/LF line endings 1\tcompat/zlib/contrib/masmx64/gvmat64.asm\tCR/LF line endings 1\tcompat/zlib/contrib/masmx64/inffas8664.c\tCR/LF line endings 1\tcompat/zlib/contrib/masmx64/inffasx64.asm\tCR/LF line endings 1\tcompat/zlib/contrib/masmx64/readme.txt\tCR/LF line endings 1\tcompat/zlib/contrib/masmx86/bld_ml32.bat\tCR/LF line endings 1\tcompat/zlib/contrib/masmx86/inffas32.asm\tCR/LF line endings 1\tcompat/zlib/contrib/masmx86/match686.asm\tCR/LF line endings 1\tcompat/zlib/contrib/masmx86/readme.txt\tCR/LF line endings 1\tcompat/zlib/contrib/puff/zeros.raw\tbinary data 1\tcompat/zlib/contrib/testzlib/testzlib.c\tCR/LF line endings 1\tcompat/zlib/contrib/testzlib/testzlib.txt\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/readme.txt\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc10/miniunz.vcxproj\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc10/miniunz.vcxproj.filters\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc10/minizip.vcxproj\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc10/minizip.vcxproj.filters\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc10/testzlib.vcxproj\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc10/testzlib.vcxproj.filters\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj.filters\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc10/zlib.rc\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc10/zlibstat.vcxproj\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc10/zlibstat.vcxproj.filters\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc10/zlibvc.def\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc10/zlibvc.sln\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc10/zlibvc.vcxproj\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc10/zlibvc.vcxproj.filters\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc11/miniunz.vcxproj\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc11/minizip.vcxproj\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc11/testzlib.vcxproj\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc11/testzlibdll.vcxproj\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc11/zlib.rc\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc11/zlibstat.vcxproj\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc11/zlibvc.def\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc11/zlibvc.sln\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc11/zlibvc.vcxproj\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc12/zlibvc.def\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc14/zlibvc.def\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc9/miniunz.vcproj\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc9/minizip.vcproj\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc9/testzlib.vcproj\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc9/testzlibdll.vcproj\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc9/zlib.rc\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc9/zlibstat.vcproj\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc9/zlibvc.def\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc9/zlibvc.sln\tCR/LF line endings 1\tcompat/zlib/contrib/vstudio/vc9/zlibvc.vcproj\tCR/LF line endings 1\tcompat/zlib/win32/zlib.def\tCR/LF line endings 1\tcompat/zlib/zlib.3.pdf\tbinary data 1\tcompat/zlib/zlib.map\tCR/LF line endings 1\tsetup/fossil.iss\tCR/LF line endings 1\tskins/blitz/arrow_project.png\tbinary data 1\tskins/blitz/dir.png\tbinary data 1\tskins/blitz/file.png\tbinary data 1\tskins/blitz/fossil_100.png\tbinary data 1\tskins/blitz/fossil_80_reversed_darkcyan.png\tbinary data 1\tskins/blitz/fossil_80_reversed_darkcyan_text.png\tbinary data 1\tskins/blitz/rss_20.png\tbinary data 1\tskins/bootstrap/css.txt\tlong lines 1\ttest/th1-docs-input.txt\tCR/LF line endings 1\ttest/th1-hooks-input.txt\tCR/LF line endings 1\ttest/utf16be.txt\tUnicode 1\ttest/utf16le.txt\tUnicode 1\twin/buildmsvc.bat\tCR/LF line endings 1\twin/fossil.ico\tbinary data 1\twin/fossil.rc\tinvalid UTF-8 1\twww/CollRev1.gif\tbinary data 1\twww/CollRev2.gif\tbinary data 1\twww/CollRev3.gif\tbinary data 1\twww/CollRev4.gif\tbinary data 1\twww/apple-touch-icon.png\tbinary data 1\twww/background.jpg\tbinary data 1\twww/branch01.gif\tbinary data 1\twww/branch02.gif\tbinary data 1\twww/branch03.gif\tbinary data 1\twww/branch04.gif\tbinary data 1\twww/branch05.gif\tbinary data 1\twww/build-icons/linux.gif\tbinary data 1\twww/build-icons/linux64.gif\tbinary data 1\twww/build-icons/mac.gif\tbinary data 1\twww/build-icons/openbsd.gif\tbinary data 1\twww/build-icons/src.gif\tbinary data 1\twww/build-icons/win32.gif\tbinary data 1\twww/concept1.gif\tbinary data 1\twww/concept2.gif\tbinary data 1\twww/copyright-release.pdf\tbinary data 1\twww/delta1.gif\tbinary data 1\twww/delta2.gif\tbinary data 1\twww/delta3.gif\tbinary data 1\twww/delta4.gif\tbinary data 1\twww/delta5.gif\tbinary data 1\twww/delta6.gif\tbinary data 1\twww/encode1.gif\tbinary data 1\twww/encode10.gif\tbinary data 1\twww/encode2.gif\tbinary data 1\twww/encode3.gif\tbinary data 1\twww/encode4.gif\tbinary data 1\twww/encode5.gif\tbinary data 1\twww/encode6.gif\tbinary data 1\twww/encode7.gif\tbinary data 1\twww/encode8.gif\tbinary data 1\twww/encode9.gif\tbinary data 1\twww/fossil.gif\tbinary data 1\twww/fossil2.gif\tbinary data 1\twww/fossil3.gif\tbinary data 1\twww/fossil_logo_small.gif\tbinary data 1\twww/fossil_logo_small2.gif\tbinary data 1\twww/fossil_logo_small3.gif\tbinary data 1\twww/xkcd-git.gif\tbinary data 1}]]} } ############################################################################### test_cleanup |
Changes to test/tester.tcl.
︙ | ︙ | |||
18 19 20 21 22 23 24 25 26 27 28 29 30 | # This is the main test script. To run a regression test, do this: # # tclsh ../test/tester.tcl ../bld/fossil # # Where ../test/tester.tcl is the name of this file and ../bld/fossil # is the name of the executable to be tested. # set testfiledir [file normalize [file dirname [info script]]] set testrundir [pwd] set testdir [file normalize [file dirname $argv0]] set fossilexe [file normalize [lindex $argv 0]] | > > > > > | | | | > > > > > > > | 18 19 20 21 22 23 24 25 26 27 28 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 | # This is the main test script. To run a regression test, do this: # # tclsh ../test/tester.tcl ../bld/fossil # # Where ../test/tester.tcl is the name of this file and ../bld/fossil # is the name of the executable to be tested. # # We use some things introduced in 8.6 such as lmap. auto.def should # have found us a suitable Tcl installation. package require Tcl 8.6 set testfiledir [file normalize [file dirname [info script]]] set testrundir [pwd] set testdir [file normalize [file dirname $argv0]] set fossilexe [file normalize [lindex $argv 0]] set is_windows [expr {$::tcl_platform(platform) eq "windows"}] if {$::is_windows} { if {[string length [file extension $fossilexe]] == 0} { append fossilexe .exe } set outside_fossil_repo [expr ![file exists "$::testfiledir\\..\\_FOSSIL_"]] } else { set outside_fossil_repo [expr ![file exists "$::testfiledir/../.fslckout"]] } catch {exec $::fossilexe changes --changed} res set dirty_ckout [string length $res] set argv [lrange $argv 1 end] set i [lsearch $argv -keep] if {$i>=0} { set KEEP 1 set argv [lreplace $argv $i $i] |
︙ | ︙ | |||
437 438 439 440 441 442 443 | # Finally, attempt to gracefully delete the temporary home directory, # unless forbidden by external forces. if {![info exists ::tempKeepHome]} {delete_temporary_home} } proc delete_temporary_home {} { if {$::KEEP} {return}; # All cleanup disabled? | | | 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 | # Finally, attempt to gracefully delete the temporary home directory, # unless forbidden by external forces. if {![info exists ::tempKeepHome]} {delete_temporary_home} } proc delete_temporary_home {} { if {$::KEEP} {return}; # All cleanup disabled? if {$::is_windows} { robust_delete [file join $::tempHomePath _fossil] } else { robust_delete [file join $::tempHomePath .fossil] } robust_delete $::tempHomePath } |
︙ | ︙ | |||
510 511 512 513 514 515 516 | fossil test-th-eval "setting th1-hooks" if {[normalize_result] eq "1"} {return 1} fossil test-th-eval --open-config "setting th1-hooks" if {[normalize_result] eq "1"} {return 1} return [info exists ::env(TH1_ENABLE_HOOKS)] } | < | > > > > | | < > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 | fossil test-th-eval "setting th1-hooks" if {[normalize_result] eq "1"} {return 1} fossil test-th-eval --open-config "setting th1-hooks" if {[normalize_result] eq "1"} {return 1} return [info exists ::env(TH1_ENABLE_HOOKS)] } # Run the given command script inside the Fossil source repo checkout. # # Callers of this function must ensure two things: # # 1. This test run is in fact being done from within a Fossil repo # checkout directory. If you are unsure, test $::outside_fossil_repo # or call one of the test_* wrappers below which do that for you. # # As a rule, you should not be calling this function directly! # # 2. This test run is being done from a repo checkout directory that # doesn't have any uncommitted changes. If it does, that affects the # output of any test based on the output of "fossil status", # "... diff", etc., which is likely to make the test appear to fail. # If you must call this function directly, test $::dirty_ckout and # skip the call if it's true. The test_* wrappers do this for you. # # 3. The test does NOT modify the Fossil checkout tree in any way. proc run_in_checkout { script {dir ""} } { if {[string length $dir] == 0} {set dir $::testfiledir} set savedPwd [pwd]; cd $dir set code [catch { uplevel 1 $script } result] cd $savedPwd; unset savedPwd return -code $code $result } # Wrapper for the above function pair. The tscript parameter is an # optional post-run test script. Some callers choose instead to put # the tests inline with the rscript commands. # # Be sure to adhere to the requirements of run_in_checkout! proc test_block_in_checkout { name rscript {tscript ""} } { if {$::outside_fossil_repo || $::dirty_ckout} { set $::CODE 0 set $::RESULT "" } else { run_in_checkout $rscript if {[string length $tscript] == 0} { return "" } else { set code [catch { uplevel 1 $tscript } result] return -code $code $result } } } # Single-test wrapper for the above. proc test_in_checkout { name rscript tscript } { return test_block_in_checkout name rscript { test $name $tscript } } # Normalize file status lists (like those returned by 'fossil changes') # so they can be compared using simple string comparison # proc normalize_status_list {list} { set normalized [list] set matches [regexp -all -inline -line {^\s*([A-Z_]+:?)\x20+(\S.*)$} $list] |
︙ | ︙ | |||
622 623 624 625 626 627 628 | } } } # # NOTE: On non-Windows systems, fallback to /tmp if it is usable. # | | | 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 | } } } # # NOTE: On non-Windows systems, fallback to /tmp if it is usable. # if {!$::is_windows} { set value /tmp if {[file exists $value] && [file isdirectory $value]} { return $value } } |
︙ | ︙ | |||
794 795 796 797 798 799 800 | # passed to the [test_stop_server] procedure. proc test_start_server { repository {varName ""} } { global fossilexe tempPath set command [list exec $fossilexe server --localhost] if {[string length $varName] > 0} { upvar 1 $varName stopArg } | | | | | 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 | # passed to the [test_stop_server] procedure. proc test_start_server { repository {varName ""} } { global fossilexe tempPath set command [list exec $fossilexe server --localhost] if {[string length $varName] > 0} { upvar 1 $varName stopArg } if {$::is_windows} { set stopArg [file join [getTemporaryPath] [appendArgs \ [string trim [clock seconds] -] _ [getSeqNo] .stopper]] lappend command --stopper $stopArg } set outFileName [file join $tempPath [appendArgs \ fossil_server_ [string trim [clock seconds] -] _ \ [getSeqNo]]].out lappend command $repository >&$outFileName & set pid [eval $command] if {!$::is_windows} { set stopArg $pid } after 1000; # output might not be there yet set output [read_file $outFileName] if {![regexp {Listening.*TCP port (\d+)} $output dummy port]} { puts stdout "Could not detect Fossil server port, using default..." set port 8080; # return the default port just in case } return [list $pid $port $outFileName] } # This procedure stops a Fossil server instance that was previously started # by the [test_start_server] procedure. The value of the "stop argument" # will vary by platform as will the exact method used to stop the server. # The fileName argument is the name of a temporary output file to delete. proc test_stop_server { stopArg pid fileName } { if {$::is_windows} { # # NOTE: On Windows, the "stop argument" must be the name of a file # that does NOT already exist. # if {[string length $stopArg] > 0 && \ ![file exists $stopArg] && \ [catch {write_file $stopArg [clock seconds]}] == 0} { |
︙ | ︙ | |||
948 949 950 951 952 953 954 | # returns the third to last line of the normalized result. proc third_to_last_data_line {} { return [lindex [split [normalize_result] \n] end-2] } set tempPath [getTemporaryPath] | | | 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 | # returns the third to last line of the normalized result. proc third_to_last_data_line {} { return [lindex [split [normalize_result] \n] end-2] } set tempPath [getTemporaryPath] if {$is_windows} { set tempPath [string map [list \\ /] $tempPath] } if {[catch { set tempFile [file join $tempPath temporary.txt] write_file $tempFile [clock seconds]; file delete $tempFile } error] != 0} { |
︙ | ︙ |
Changes to test/th1-docs.test.
︙ | ︙ | |||
27 28 29 30 31 32 33 34 35 36 37 38 39 40 | fossil test-th-eval "hasfeature tcl" if {[normalize_result] ne "1"} { puts "Fossil was not compiled with Tcl support." test_cleanup_then_return } ############################################################################### test_setup "" ############################################################################### | > > > > > > > > | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | fossil test-th-eval "hasfeature tcl" if {[normalize_result] ne "1"} { puts "Fossil was not compiled with Tcl support." test_cleanup_then_return } if {$::outside_fossil_repo} { puts "Skipping th1-docs-* tests: not in Fossil repo checkout." test_cleanup_then_return } elseif ($::dirty_ckout) { puts "Skipping th1-docs-* tests: uncommitted changes in Fossil checkout." test_cleanup_then_return } ############################################################################### test_setup "" ############################################################################### |
︙ | ︙ |
Changes to test/th1.test.
︙ | ︙ | |||
551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 | ############################################################################### fossil test-th-eval "lindex list -0x" test th1-expr-49 {$RESULT eq {TH_ERROR: expected integer, got: "-0x"}} ############################################################################### foreach perm [list a b c d e f g h i j k l m n o p q r s t u v w x y z] { if {$perm eq "u"} continue; # NOTE: Skip "reader" meta-permission. if {$perm eq "v"} continue; # NOTE: Skip "developer" meta-permission. fossil test-th-eval "anycap $perm" test th1-anycap-no-$perm-1 {$RESULT eq {0}} fossil test-th-eval "hascap $perm" test th1-hascap-no-$perm-1 {$RESULT eq {0}} fossil test-th-eval "anoncap $perm" test th1-anoncap-no-$perm-1 {$RESULT eq {0}} run_in_checkout { fossil test-th-eval --set-user-caps "anycap $perm" test th1-anycap-yes-$perm-1 {$RESULT eq {1}} set ::env(TH1_TEST_USER_CAPS) 1; # NOTE: Bad permission. fossil test-th-eval --set-user-caps "anycap $perm" | > > > > > > > > > > > | 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 | ############################################################################### fossil test-th-eval "lindex list -0x" test th1-expr-49 {$RESULT eq {TH_ERROR: expected integer, got: "-0x"}} ############################################################################### set skip_anycap 1 if {$::outside_fossil_repo} { puts "Skipping th1-anycap-*-1 perm tests: not in Fossil repo checkout." } elseif ($::dirty_ckout) { puts "Skipping th1-anycap-*-1 perm tests: uncommitted changes in Fossil checkout." } else { set skip_anycap 0 } foreach perm [list a b c d e f g h i j k l m n o p q r s t u v w x y z] { if {$perm eq "u"} continue; # NOTE: Skip "reader" meta-permission. if {$perm eq "v"} continue; # NOTE: Skip "developer" meta-permission. fossil test-th-eval "anycap $perm" test th1-anycap-no-$perm-1 {$RESULT eq {0}} fossil test-th-eval "hascap $perm" test th1-hascap-no-$perm-1 {$RESULT eq {0}} fossil test-th-eval "anoncap $perm" test th1-anoncap-no-$perm-1 {$RESULT eq {0}} if {$skip_anycap} { continue } run_in_checkout { fossil test-th-eval --set-user-caps "anycap $perm" test th1-anycap-yes-$perm-1 {$RESULT eq {1}} set ::env(TH1_TEST_USER_CAPS) 1; # NOTE: Bad permission. fossil test-th-eval --set-user-caps "anycap $perm" |
︙ | ︙ | |||
619 620 621 622 623 624 625 | ############################################################################### fossil test-th-eval "anoncap o h" test th1-anoncap-no-multiple-2 {$RESULT eq {0}} ############################################################################### | | | 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 | ############################################################################### fossil test-th-eval "anoncap o h" test th1-anoncap-no-multiple-2 {$RESULT eq {0}} ############################################################################### test_block_in_checkout "test-anoncap-*" { fossil test-th-eval --set-user-caps "anycap oh" test th1-anycap-yes-multiple-1 {$RESULT eq {1}} set ::env(TH1_TEST_USER_CAPS) o fossil test-th-eval --set-user-caps "anycap oh" test th1-anycap-yes-multiple-2 {$RESULT eq {1}} unset ::env(TH1_TEST_USER_CAPS) |
︙ | ︙ | |||
663 664 665 666 667 668 669 | fossil test-th-eval --set-anon-caps "anoncap o h" test th1-anoncap-no-multiple-4 {$RESULT eq {0}} unset ::env(TH1_TEST_ANON_CAPS) } ############################################################################### | | < < | | < < | | 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 | fossil test-th-eval --set-anon-caps "anoncap o h" test th1-anoncap-no-multiple-4 {$RESULT eq {0}} unset ::env(TH1_TEST_ANON_CAPS) } ############################################################################### test_in_checkout th1-checkout-1 { # NOTE: The "1" here forces the checkout to be opened. fossil test-th-eval "checkout 1" } {[string length $RESULT] > 0} ############################################################################### test_in_checkout th1-checkout-2 { if {$th1Hooks} { fossil test-th-eval "checkout" } else { # NOTE: No TH1 hooks, force checkout to be populated. fossil test-th-eval --open-config "checkout" } } {[string length $RESULT] > 0} ############################################################################### set savedPwd [pwd]; cd / fossil test-th-eval "checkout 1" cd $savedPwd; unset savedPwd test th1-checkout-3 {[string length $RESULT] == 0} |
︙ | ︙ | |||
760 761 762 763 764 765 766 | ############################################################################### fossil test-th-eval "styleHeader {Page Title Here}" test th1-header-1 {$RESULT eq {TH_ERROR: repository unavailable}} ############################################################################### | | < < | | 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 | ############################################################################### fossil test-th-eval "styleHeader {Page Title Here}" test th1-header-1 {$RESULT eq {TH_ERROR: repository unavailable}} ############################################################################### test_in_checkout th1-header-2 { fossil test-th-eval --open-config "styleHeader {Page Title Here}" } {[regexp -- {<title>Fossil: Page Title Here</title>} $RESULT]} ############################################################################### fossil test-th-eval "styleFooter" test th1-footer-1 {$RESULT eq {TH_ERROR: repository unavailable}} ############################################################################### |
︙ | ︙ | |||
846 847 848 849 850 851 852 | ############################################################################### fossil test-th-eval "artifact tip" test th1-artifact-2 {$RESULT eq {TH_ERROR: repository unavailable}} ############################################################################### | | < < | | < < | | < < | | | 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 | ############################################################################### fossil test-th-eval "artifact tip" test th1-artifact-2 {$RESULT eq {TH_ERROR: repository unavailable}} ############################################################################### test_in_checkout th1-artifact-3 { fossil test-th-eval --open-config "artifact tip" } {[regexp -- {F test/th1\.test [0-9a-f]{40,64}} $RESULT]} ############################################################################### fossil test-th-eval "artifact 0000000000" test th1-artifact-4 {$RESULT eq {TH_ERROR: repository unavailable}} ############################################################################### fossil test-th-eval --open-config "artifact 0000000000" test th1-artifact-5 {$RESULT eq {TH_ERROR: name not found}} ############################################################################### fossil test-th-eval "artifact tip test/th1.test" test th1-artifact-6 {$RESULT eq {TH_ERROR: repository unavailable}} ############################################################################### test_in_checkout th1-artifact-7 { fossil test-th-eval --open-config "artifact tip test/th1.test" } {[regexp -- {th1-artifact-7} $RESULT]} ############################################################################### fossil test-th-eval "artifact 0000000000 test/th1.test" test th1-artifact-8 {$RESULT eq {TH_ERROR: repository unavailable}} ############################################################################### fossil test-th-eval --open-config "artifact 0000000000 test/th1.test" test th1-artifact-9 {$RESULT eq {TH_ERROR: manifest not found}} ############################################################################### test_in_checkout th1-globalState-1 { if {$th1Hooks} { fossil test-th-eval "globalState checkout" } else { # NOTE: No TH1 hooks, force checkout to be populated. fossil test-th-eval --open-config "globalState checkout" } } {[string length $RESULT] > 0} ############################################################################### test_block_in_checkout th1-globalState-2 { if {$th1Hooks} { fossil test-th-eval "globalState checkout" test th1-globalState-2 {$RESULT eq [fossil test-th-eval checkout]} } else { # NOTE: No TH1 hooks, force checkout to be populated. fossil test-th-eval --open-config "globalState checkout" |
︙ | ︙ | |||
940 941 942 943 944 945 946 | ############################################################################### fossil test-th-eval --errorlog foserrors.log "globalState log" test th1-globalState-7 {$RESULT eq "foserrors.log"} ############################################################################### | | < < | | | 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 | ############################################################################### fossil test-th-eval --errorlog foserrors.log "globalState log" test th1-globalState-7 {$RESULT eq "foserrors.log"} ############################################################################### test_in_checkout th1-globalState-8 { if {$th1Hooks} { fossil test-th-eval "globalState repository" } else { # NOTE: No TH1 hooks, force repository to be populated. fossil test-th-eval --open-config "globalState repository" } } {[string length $RESULT] > 0} ############################################################################### test_block_in_checkout th1-globalState-9 { if {$th1Hooks} { fossil test-th-eval "globalState repository" test th1-globalState-9 {$RESULT eq [fossil test-th-eval repository]} } else { # NOTE: No TH1 hooks, force repository to be populated. fossil test-th-eval --open-config "globalState repository" |
︙ | ︙ | |||
1601 1602 1603 1604 1605 1606 1607 | fossil test-th-eval {encode64 test\x00} test th1-encode64-2 {$RESULT eq "dGVzdAA="} ############################################################################### # | | | | | > | < < | 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 | fossil test-th-eval {encode64 test\x00} test th1-encode64-2 {$RESULT eq "dGVzdAA="} ############################################################################### # # This test will fail if the Fossil source file named below changes. Update # the expected result string below if that happens. # test_in_checkout th1-encode64-3 { fossil test-th-eval --open-config \ {encode64 [artifact trunk ajax/cgi-bin/fossil-json.cgi.example]} } { $RESULT eq "IyEvcGF0aC90by9mb3NzaWwvYmluYXJ5CnJlcG9zaXRvcnk6IC9wYXRoL3RvL3JlcG8uZnNsCg==" } ############################################################################### fossil test-th-eval {array exists tcl_platform} test th1-platform-1 {$RESULT eq "1"} ############################################################################### |
︙ | ︙ |
Changes to win/Makefile.dmc.
︙ | ︙ | |||
26 27 28 29 30 31 32 | TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL) LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 dnsapi SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen | | | | | 26 27 28 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 | TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL) LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 dnsapi SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS3_PARENTHESIS -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen SRC = add_.c alerts_.c allrepo_.c attach_.c backoffice_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c capabilities_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c file_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c glob_.c graph_.c gzip_.c hname_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c piechart_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c security_audit_.c setup_.c setupuser_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c smtp_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c webmail_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c OBJ = $(OBJDIR)\add$O $(OBJDIR)\alerts$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\backoffice$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\capabilities$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\etag$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\setupuser$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\smtp$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\webmail$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O RC=$(DMDIR)\bin\rcc RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__ APPNAME = $(OBJDIR)\fossil$(E) all: $(APPNAME) $(APPNAME) : translate$E mkindex$E codecheck1$E headers $(OBJ) $(OBJDIR)\link cd $(OBJDIR) codecheck1$E $(SRC) $(DMDIR)\bin\link @link $(OBJDIR)\fossil.res: $B\win\fossil.rc $(RC) $(RCFLAGS) -o$@ $** $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res +echo add alerts allrepo attach backoffice bag bisect blob branch browse builtin bundle cache capabilities captcha cgi checkin checkout clearsign clone comformat configure content cookies db delta deltacmd descendants diff diffcmd dispatch doc encode etag event export file finfo foci forum fshell fusefs glob graph gzip hname http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path piechart pivot popen pqueue printf publish purge rebuild regexp report rss schema search security_audit setup setupuser sha1 sha1hard sha3 shun sitemap skins smtp sqlcmd stash stat statrep style sync tag tar th_main timeline tkt tktsetup undo unicode unversioned update url user utf8 util verify vfile webmail wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@ +echo fossil >> $@ +echo fossil >> $@ +echo $(LIBS) >> $@ +echo. >> $@ +echo fossil >> $@ translate$E: $(SRCDIR)\translate.c |
︙ | ︙ | |||
132 133 134 135 136 137 138 139 140 141 142 143 144 145 | $(OBJDIR)\add$O : add_.c add.h $(TCC) -o$@ -c add_.c add_.c : $(SRCDIR)\add.c +translate$E $** > $@ $(OBJDIR)\allrepo$O : allrepo_.c allrepo.h $(TCC) -o$@ -c allrepo_.c allrepo_.c : $(SRCDIR)\allrepo.c +translate$E $** > $@ | > > > > > > | 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | $(OBJDIR)\add$O : add_.c add.h $(TCC) -o$@ -c add_.c add_.c : $(SRCDIR)\add.c +translate$E $** > $@ $(OBJDIR)\alerts$O : alerts_.c alerts.h $(TCC) -o$@ -c alerts_.c alerts_.c : $(SRCDIR)\alerts.c +translate$E $** > $@ $(OBJDIR)\allrepo$O : allrepo_.c allrepo.h $(TCC) -o$@ -c allrepo_.c allrepo_.c : $(SRCDIR)\allrepo.c +translate$E $** > $@ |
︙ | ︙ | |||
313 314 315 316 317 318 319 | $(OBJDIR)\doc$O : doc_.c doc.h $(TCC) -o$@ -c doc_.c doc_.c : $(SRCDIR)\doc.c +translate$E $** > $@ | < < < < < < | 319 320 321 322 323 324 325 326 327 328 329 330 331 332 | $(OBJDIR)\doc$O : doc_.c doc.h $(TCC) -o$@ -c doc_.c doc_.c : $(SRCDIR)\doc.c +translate$E $** > $@ $(OBJDIR)\encode$O : encode_.c encode.h $(TCC) -o$@ -c encode_.c encode_.c : $(SRCDIR)\encode.c +translate$E $** > $@ $(OBJDIR)\etag$O : etag_.c etag.h |
︙ | ︙ | |||
938 939 940 941 942 943 944 | $(OBJDIR)\zip$O : zip_.c zip.h $(TCC) -o$@ -c zip_.c zip_.c : $(SRCDIR)\zip.c +translate$E $** > $@ headers: makeheaders$E page_index.h builtin_data.h default_css.h VERSION.h | | | 938 939 940 941 942 943 944 945 946 | $(OBJDIR)\zip$O : zip_.c zip.h $(TCC) -o$@ -c zip_.c zip_.c : $(SRCDIR)\zip.c +translate$E $** > $@ headers: makeheaders$E page_index.h builtin_data.h default_css.h VERSION.h +makeheaders$E add_.c:add.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backoffice_.c:backoffice.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h capabilities_.c:capabilities.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h etag_.c:etag.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h foci_.c:foci.h forum_.c:forum.h fshell_.c:fshell.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h piechart_.c:piechart.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h setupuser_.c:setupuser.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h smtp_.c:smtp.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h webmail_.c:webmail.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h @copy /Y nul: headers |
Changes to win/Makefile.mingw.
︙ | ︙ | |||
158 159 160 161 162 163 164 | ZLIBCONFIG = ZLIBTARGETS = endif #### Disable creation of the OpenSSL shared libraries. Also, disable support # for SSLv3 (i.e. thereby forcing the use of TLS). # | | | 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | ZLIBCONFIG = ZLIBTARGETS = endif #### Disable creation of the OpenSSL shared libraries. Also, disable support # for SSLv3 (i.e. thereby forcing the use of TLS). # SSLCONFIG += no-ssl3 no-weak-ssl-ciphers no-shared #### When using zlib, make sure that OpenSSL is configured to use the zlib # that Fossil knows about (i.e. the one within the source tree). # ifndef FOSSIL_ENABLE_MINIZ SSLCONFIG += --with-zlib-lib=$(PWD)/$(ZLIBDIR) --with-zlib-include=$(PWD)/$(ZLIBDIR) zlib endif |
︙ | ︙ | |||
435 436 437 438 439 440 441 442 443 444 445 446 447 448 | # You should not need to change anything below this line #-------------------------------------------------------- XBCC = $(BCC) $(CFLAGS) XTCC = $(TCC) $(CFLAGS) -I. -I$(SRCDIR) SRC = \ $(SRCDIR)/add.c \ $(SRCDIR)/allrepo.c \ $(SRCDIR)/attach.c \ $(SRCDIR)/backoffice.c \ $(SRCDIR)/bag.c \ $(SRCDIR)/bisect.c \ $(SRCDIR)/blob.c \ $(SRCDIR)/branch.c \ | > | 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 | # You should not need to change anything below this line #-------------------------------------------------------- XBCC = $(BCC) $(CFLAGS) XTCC = $(TCC) $(CFLAGS) -I. -I$(SRCDIR) SRC = \ $(SRCDIR)/add.c \ $(SRCDIR)/alerts.c \ $(SRCDIR)/allrepo.c \ $(SRCDIR)/attach.c \ $(SRCDIR)/backoffice.c \ $(SRCDIR)/bag.c \ $(SRCDIR)/bisect.c \ $(SRCDIR)/blob.c \ $(SRCDIR)/branch.c \ |
︙ | ︙ | |||
465 466 467 468 469 470 471 | $(SRCDIR)/delta.c \ $(SRCDIR)/deltacmd.c \ $(SRCDIR)/descendants.c \ $(SRCDIR)/diff.c \ $(SRCDIR)/diffcmd.c \ $(SRCDIR)/dispatch.c \ $(SRCDIR)/doc.c \ | < | 466 467 468 469 470 471 472 473 474 475 476 477 478 479 | $(SRCDIR)/delta.c \ $(SRCDIR)/deltacmd.c \ $(SRCDIR)/descendants.c \ $(SRCDIR)/diff.c \ $(SRCDIR)/diffcmd.c \ $(SRCDIR)/dispatch.c \ $(SRCDIR)/doc.c \ $(SRCDIR)/encode.c \ $(SRCDIR)/etag.c \ $(SRCDIR)/event.c \ $(SRCDIR)/export.c \ $(SRCDIR)/file.c \ $(SRCDIR)/finfo.c \ $(SRCDIR)/foci.c \ |
︙ | ︙ | |||
598 599 600 601 602 603 604 605 606 607 608 609 610 611 | $(SRCDIR)/../skins/bootstrap/details.txt \ $(SRCDIR)/../skins/bootstrap/footer.txt \ $(SRCDIR)/../skins/bootstrap/header.txt \ $(SRCDIR)/../skins/default/css.txt \ $(SRCDIR)/../skins/default/details.txt \ $(SRCDIR)/../skins/default/footer.txt \ $(SRCDIR)/../skins/default/header.txt \ $(SRCDIR)/../skins/eagle/css.txt \ $(SRCDIR)/../skins/eagle/details.txt \ $(SRCDIR)/../skins/eagle/footer.txt \ $(SRCDIR)/../skins/eagle/header.txt \ $(SRCDIR)/../skins/enhanced1/css.txt \ $(SRCDIR)/../skins/enhanced1/details.txt \ $(SRCDIR)/../skins/enhanced1/footer.txt \ | > | 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 | $(SRCDIR)/../skins/bootstrap/details.txt \ $(SRCDIR)/../skins/bootstrap/footer.txt \ $(SRCDIR)/../skins/bootstrap/header.txt \ $(SRCDIR)/../skins/default/css.txt \ $(SRCDIR)/../skins/default/details.txt \ $(SRCDIR)/../skins/default/footer.txt \ $(SRCDIR)/../skins/default/header.txt \ $(SRCDIR)/../skins/default/js.txt \ $(SRCDIR)/../skins/eagle/css.txt \ $(SRCDIR)/../skins/eagle/details.txt \ $(SRCDIR)/../skins/eagle/footer.txt \ $(SRCDIR)/../skins/eagle/header.txt \ $(SRCDIR)/../skins/enhanced1/css.txt \ $(SRCDIR)/../skins/enhanced1/details.txt \ $(SRCDIR)/../skins/enhanced1/footer.txt \ |
︙ | ︙ | |||
644 645 646 647 648 649 650 651 652 653 654 655 656 657 | $(SRCDIR)/sorttable.js \ $(SRCDIR)/tree.js \ $(SRCDIR)/useredit.js \ $(SRCDIR)/wiki.wiki TRANS_SRC = \ $(OBJDIR)/add_.c \ $(OBJDIR)/allrepo_.c \ $(OBJDIR)/attach_.c \ $(OBJDIR)/backoffice_.c \ $(OBJDIR)/bag_.c \ $(OBJDIR)/bisect_.c \ $(OBJDIR)/blob_.c \ $(OBJDIR)/branch_.c \ | > | 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 | $(SRCDIR)/sorttable.js \ $(SRCDIR)/tree.js \ $(SRCDIR)/useredit.js \ $(SRCDIR)/wiki.wiki TRANS_SRC = \ $(OBJDIR)/add_.c \ $(OBJDIR)/alerts_.c \ $(OBJDIR)/allrepo_.c \ $(OBJDIR)/attach_.c \ $(OBJDIR)/backoffice_.c \ $(OBJDIR)/bag_.c \ $(OBJDIR)/bisect_.c \ $(OBJDIR)/blob_.c \ $(OBJDIR)/branch_.c \ |
︙ | ︙ | |||
674 675 676 677 678 679 680 | $(OBJDIR)/delta_.c \ $(OBJDIR)/deltacmd_.c \ $(OBJDIR)/descendants_.c \ $(OBJDIR)/diff_.c \ $(OBJDIR)/diffcmd_.c \ $(OBJDIR)/dispatch_.c \ $(OBJDIR)/doc_.c \ | < | 676 677 678 679 680 681 682 683 684 685 686 687 688 689 | $(OBJDIR)/delta_.c \ $(OBJDIR)/deltacmd_.c \ $(OBJDIR)/descendants_.c \ $(OBJDIR)/diff_.c \ $(OBJDIR)/diffcmd_.c \ $(OBJDIR)/dispatch_.c \ $(OBJDIR)/doc_.c \ $(OBJDIR)/encode_.c \ $(OBJDIR)/etag_.c \ $(OBJDIR)/event_.c \ $(OBJDIR)/export_.c \ $(OBJDIR)/file_.c \ $(OBJDIR)/finfo_.c \ $(OBJDIR)/foci_.c \ |
︙ | ︙ | |||
781 782 783 784 785 786 787 788 789 790 791 792 793 794 | $(OBJDIR)/wysiwyg_.c \ $(OBJDIR)/xfer_.c \ $(OBJDIR)/xfersetup_.c \ $(OBJDIR)/zip_.c OBJ = \ $(OBJDIR)/add.o \ $(OBJDIR)/allrepo.o \ $(OBJDIR)/attach.o \ $(OBJDIR)/backoffice.o \ $(OBJDIR)/bag.o \ $(OBJDIR)/bisect.o \ $(OBJDIR)/blob.o \ $(OBJDIR)/branch.o \ | > | 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 | $(OBJDIR)/wysiwyg_.c \ $(OBJDIR)/xfer_.c \ $(OBJDIR)/xfersetup_.c \ $(OBJDIR)/zip_.c OBJ = \ $(OBJDIR)/add.o \ $(OBJDIR)/alerts.o \ $(OBJDIR)/allrepo.o \ $(OBJDIR)/attach.o \ $(OBJDIR)/backoffice.o \ $(OBJDIR)/bag.o \ $(OBJDIR)/bisect.o \ $(OBJDIR)/blob.o \ $(OBJDIR)/branch.o \ |
︙ | ︙ | |||
811 812 813 814 815 816 817 | $(OBJDIR)/delta.o \ $(OBJDIR)/deltacmd.o \ $(OBJDIR)/descendants.o \ $(OBJDIR)/diff.o \ $(OBJDIR)/diffcmd.o \ $(OBJDIR)/dispatch.o \ $(OBJDIR)/doc.o \ | < | 813 814 815 816 817 818 819 820 821 822 823 824 825 826 | $(OBJDIR)/delta.o \ $(OBJDIR)/deltacmd.o \ $(OBJDIR)/descendants.o \ $(OBJDIR)/diff.o \ $(OBJDIR)/diffcmd.o \ $(OBJDIR)/dispatch.o \ $(OBJDIR)/doc.o \ $(OBJDIR)/encode.o \ $(OBJDIR)/etag.o \ $(OBJDIR)/event.o \ $(OBJDIR)/export.o \ $(OBJDIR)/file.o \ $(OBJDIR)/finfo.o \ $(OBJDIR)/foci.o \ |
︙ | ︙ | |||
1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 | $(MKINDEX) $(TRANS_SRC) >$@ $(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES) $(MKBUILTIN) --prefix $(SRCDIR)/ $(EXTRA_FILES) >$@ $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(OBJDIR)/default_css.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h $(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \ $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \ $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \ $(OBJDIR)/backoffice_.c:$(OBJDIR)/backoffice.h \ $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \ $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \ $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \ $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \ | > | 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 | $(MKINDEX) $(TRANS_SRC) >$@ $(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES) $(MKBUILTIN) --prefix $(SRCDIR)/ $(EXTRA_FILES) >$@ $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(OBJDIR)/default_css.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h $(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \ $(OBJDIR)/alerts_.c:$(OBJDIR)/alerts.h \ $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \ $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \ $(OBJDIR)/backoffice_.c:$(OBJDIR)/backoffice.h \ $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \ $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \ $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \ $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \ |
︙ | ︙ | |||
1167 1168 1169 1170 1171 1172 1173 | $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h \ $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h \ $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h \ $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h \ $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h \ $(OBJDIR)/dispatch_.c:$(OBJDIR)/dispatch.h \ $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h \ | < | 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 | $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h \ $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h \ $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h \ $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h \ $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h \ $(OBJDIR)/dispatch_.c:$(OBJDIR)/dispatch.h \ $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h \ $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h \ $(OBJDIR)/etag_.c:$(OBJDIR)/etag.h \ $(OBJDIR)/event_.c:$(OBJDIR)/event.h \ $(OBJDIR)/export_.c:$(OBJDIR)/export.h \ $(OBJDIR)/file_.c:$(OBJDIR)/file.h \ $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \ $(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \ |
︙ | ︙ | |||
1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 | $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/add.c >$@ $(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/add.o -c $(OBJDIR)/add_.c $(OBJDIR)/add.h: $(OBJDIR)/headers $(OBJDIR)/allrepo_.c: $(SRCDIR)/allrepo.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/allrepo.c >$@ $(OBJDIR)/allrepo.o: $(OBJDIR)/allrepo_.c $(OBJDIR)/allrepo.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/allrepo.o -c $(OBJDIR)/allrepo_.c | > > > > > > > > | 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 | $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/add.c >$@ $(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/add.o -c $(OBJDIR)/add_.c $(OBJDIR)/add.h: $(OBJDIR)/headers $(OBJDIR)/alerts_.c: $(SRCDIR)/alerts.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/alerts.c >$@ $(OBJDIR)/alerts.o: $(OBJDIR)/alerts_.c $(OBJDIR)/alerts.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/alerts.o -c $(OBJDIR)/alerts_.c $(OBJDIR)/alerts.h: $(OBJDIR)/headers $(OBJDIR)/allrepo_.c: $(SRCDIR)/allrepo.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/allrepo.c >$@ $(OBJDIR)/allrepo.o: $(OBJDIR)/allrepo_.c $(OBJDIR)/allrepo.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/allrepo.o -c $(OBJDIR)/allrepo_.c |
︙ | ︙ | |||
1528 1529 1530 1531 1532 1533 1534 | $(TRANSLATE) $(SRCDIR)/doc.c >$@ $(OBJDIR)/doc.o: $(OBJDIR)/doc_.c $(OBJDIR)/doc.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/doc.o -c $(OBJDIR)/doc_.c $(OBJDIR)/doc.h: $(OBJDIR)/headers | < < < < < < < < | 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 | $(TRANSLATE) $(SRCDIR)/doc.c >$@ $(OBJDIR)/doc.o: $(OBJDIR)/doc_.c $(OBJDIR)/doc.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/doc.o -c $(OBJDIR)/doc_.c $(OBJDIR)/doc.h: $(OBJDIR)/headers $(OBJDIR)/encode_.c: $(SRCDIR)/encode.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/encode.c >$@ $(OBJDIR)/encode.o: $(OBJDIR)/encode_.c $(OBJDIR)/encode.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/encode.o -c $(OBJDIR)/encode_.c $(OBJDIR)/encode.h: $(OBJDIR)/headers |
︙ | ︙ |
Changes to win/Makefile.mingw.mistachkin.
︙ | ︙ | |||
158 159 160 161 162 163 164 | ZLIBCONFIG = ZLIBTARGETS = endif #### Disable creation of the OpenSSL shared libraries. Also, disable support # for SSLv3 (i.e. thereby forcing the use of TLS). # | | | 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | ZLIBCONFIG = ZLIBTARGETS = endif #### Disable creation of the OpenSSL shared libraries. Also, disable support # for SSLv3 (i.e. thereby forcing the use of TLS). # SSLCONFIG += no-ssl3 no-weak-ssl-ciphers no-shared #### When using zlib, make sure that OpenSSL is configured to use the zlib # that Fossil knows about (i.e. the one within the source tree). # ifndef FOSSIL_ENABLE_MINIZ SSLCONFIG += --with-zlib-lib=$(PWD)/$(ZLIBDIR) --with-zlib-include=$(PWD)/$(ZLIBDIR) zlib endif |
︙ | ︙ | |||
435 436 437 438 439 440 441 442 443 444 445 446 447 448 | # You should not need to change anything below this line #-------------------------------------------------------- XBCC = $(BCC) $(CFLAGS) XTCC = $(TCC) $(CFLAGS) -I. -I$(SRCDIR) SRC = \ $(SRCDIR)/add.c \ $(SRCDIR)/allrepo.c \ $(SRCDIR)/attach.c \ $(SRCDIR)/backoffice.c \ $(SRCDIR)/bag.c \ $(SRCDIR)/bisect.c \ $(SRCDIR)/blob.c \ $(SRCDIR)/branch.c \ | > | 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 | # You should not need to change anything below this line #-------------------------------------------------------- XBCC = $(BCC) $(CFLAGS) XTCC = $(TCC) $(CFLAGS) -I. -I$(SRCDIR) SRC = \ $(SRCDIR)/add.c \ $(SRCDIR)/alerts.c \ $(SRCDIR)/allrepo.c \ $(SRCDIR)/attach.c \ $(SRCDIR)/backoffice.c \ $(SRCDIR)/bag.c \ $(SRCDIR)/bisect.c \ $(SRCDIR)/blob.c \ $(SRCDIR)/branch.c \ |
︙ | ︙ | |||
465 466 467 468 469 470 471 | $(SRCDIR)/delta.c \ $(SRCDIR)/deltacmd.c \ $(SRCDIR)/descendants.c \ $(SRCDIR)/diff.c \ $(SRCDIR)/diffcmd.c \ $(SRCDIR)/dispatch.c \ $(SRCDIR)/doc.c \ | < | 466 467 468 469 470 471 472 473 474 475 476 477 478 479 | $(SRCDIR)/delta.c \ $(SRCDIR)/deltacmd.c \ $(SRCDIR)/descendants.c \ $(SRCDIR)/diff.c \ $(SRCDIR)/diffcmd.c \ $(SRCDIR)/dispatch.c \ $(SRCDIR)/doc.c \ $(SRCDIR)/encode.c \ $(SRCDIR)/etag.c \ $(SRCDIR)/event.c \ $(SRCDIR)/export.c \ $(SRCDIR)/file.c \ $(SRCDIR)/finfo.c \ $(SRCDIR)/foci.c \ |
︙ | ︙ | |||
530 531 532 533 534 535 536 537 538 539 540 541 542 543 | $(SRCDIR)/regexp.c \ $(SRCDIR)/report.c \ $(SRCDIR)/rss.c \ $(SRCDIR)/schema.c \ $(SRCDIR)/search.c \ $(SRCDIR)/security_audit.c \ $(SRCDIR)/setup.c \ $(SRCDIR)/sha1.c \ $(SRCDIR)/sha1hard.c \ $(SRCDIR)/sha3.c \ $(SRCDIR)/shun.c \ $(SRCDIR)/sitemap.c \ $(SRCDIR)/skins.c \ $(SRCDIR)/smtp.c \ | > | 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 | $(SRCDIR)/regexp.c \ $(SRCDIR)/report.c \ $(SRCDIR)/rss.c \ $(SRCDIR)/schema.c \ $(SRCDIR)/search.c \ $(SRCDIR)/security_audit.c \ $(SRCDIR)/setup.c \ $(SRCDIR)/setupuser.c \ $(SRCDIR)/sha1.c \ $(SRCDIR)/sha1hard.c \ $(SRCDIR)/sha3.c \ $(SRCDIR)/shun.c \ $(SRCDIR)/sitemap.c \ $(SRCDIR)/skins.c \ $(SRCDIR)/smtp.c \ |
︙ | ︙ | |||
597 598 599 600 601 602 603 604 605 606 607 608 609 610 | $(SRCDIR)/../skins/bootstrap/details.txt \ $(SRCDIR)/../skins/bootstrap/footer.txt \ $(SRCDIR)/../skins/bootstrap/header.txt \ $(SRCDIR)/../skins/default/css.txt \ $(SRCDIR)/../skins/default/details.txt \ $(SRCDIR)/../skins/default/footer.txt \ $(SRCDIR)/../skins/default/header.txt \ $(SRCDIR)/../skins/eagle/css.txt \ $(SRCDIR)/../skins/eagle/details.txt \ $(SRCDIR)/../skins/eagle/footer.txt \ $(SRCDIR)/../skins/eagle/header.txt \ $(SRCDIR)/../skins/enhanced1/css.txt \ $(SRCDIR)/../skins/enhanced1/details.txt \ $(SRCDIR)/../skins/enhanced1/footer.txt \ | > | 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 | $(SRCDIR)/../skins/bootstrap/details.txt \ $(SRCDIR)/../skins/bootstrap/footer.txt \ $(SRCDIR)/../skins/bootstrap/header.txt \ $(SRCDIR)/../skins/default/css.txt \ $(SRCDIR)/../skins/default/details.txt \ $(SRCDIR)/../skins/default/footer.txt \ $(SRCDIR)/../skins/default/header.txt \ $(SRCDIR)/../skins/default/js.txt \ $(SRCDIR)/../skins/eagle/css.txt \ $(SRCDIR)/../skins/eagle/details.txt \ $(SRCDIR)/../skins/eagle/footer.txt \ $(SRCDIR)/../skins/eagle/header.txt \ $(SRCDIR)/../skins/enhanced1/css.txt \ $(SRCDIR)/../skins/enhanced1/details.txt \ $(SRCDIR)/../skins/enhanced1/footer.txt \ |
︙ | ︙ | |||
643 644 645 646 647 648 649 650 651 652 653 654 655 656 | $(SRCDIR)/sorttable.js \ $(SRCDIR)/tree.js \ $(SRCDIR)/useredit.js \ $(SRCDIR)/wiki.wiki TRANS_SRC = \ $(OBJDIR)/add_.c \ $(OBJDIR)/allrepo_.c \ $(OBJDIR)/attach_.c \ $(OBJDIR)/backoffice_.c \ $(OBJDIR)/bag_.c \ $(OBJDIR)/bisect_.c \ $(OBJDIR)/blob_.c \ $(OBJDIR)/branch_.c \ | > | 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 | $(SRCDIR)/sorttable.js \ $(SRCDIR)/tree.js \ $(SRCDIR)/useredit.js \ $(SRCDIR)/wiki.wiki TRANS_SRC = \ $(OBJDIR)/add_.c \ $(OBJDIR)/alerts_.c \ $(OBJDIR)/allrepo_.c \ $(OBJDIR)/attach_.c \ $(OBJDIR)/backoffice_.c \ $(OBJDIR)/bag_.c \ $(OBJDIR)/bisect_.c \ $(OBJDIR)/blob_.c \ $(OBJDIR)/branch_.c \ |
︙ | ︙ | |||
673 674 675 676 677 678 679 | $(OBJDIR)/delta_.c \ $(OBJDIR)/deltacmd_.c \ $(OBJDIR)/descendants_.c \ $(OBJDIR)/diff_.c \ $(OBJDIR)/diffcmd_.c \ $(OBJDIR)/dispatch_.c \ $(OBJDIR)/doc_.c \ | < | 676 677 678 679 680 681 682 683 684 685 686 687 688 689 | $(OBJDIR)/delta_.c \ $(OBJDIR)/deltacmd_.c \ $(OBJDIR)/descendants_.c \ $(OBJDIR)/diff_.c \ $(OBJDIR)/diffcmd_.c \ $(OBJDIR)/dispatch_.c \ $(OBJDIR)/doc_.c \ $(OBJDIR)/encode_.c \ $(OBJDIR)/etag_.c \ $(OBJDIR)/event_.c \ $(OBJDIR)/export_.c \ $(OBJDIR)/file_.c \ $(OBJDIR)/finfo_.c \ $(OBJDIR)/foci_.c \ |
︙ | ︙ | |||
738 739 740 741 742 743 744 745 746 747 748 749 750 751 | $(OBJDIR)/regexp_.c \ $(OBJDIR)/report_.c \ $(OBJDIR)/rss_.c \ $(OBJDIR)/schema_.c \ $(OBJDIR)/search_.c \ $(OBJDIR)/security_audit_.c \ $(OBJDIR)/setup_.c \ $(OBJDIR)/sha1_.c \ $(OBJDIR)/sha1hard_.c \ $(OBJDIR)/sha3_.c \ $(OBJDIR)/shun_.c \ $(OBJDIR)/sitemap_.c \ $(OBJDIR)/skins_.c \ $(OBJDIR)/smtp_.c \ | > | 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 | $(OBJDIR)/regexp_.c \ $(OBJDIR)/report_.c \ $(OBJDIR)/rss_.c \ $(OBJDIR)/schema_.c \ $(OBJDIR)/search_.c \ $(OBJDIR)/security_audit_.c \ $(OBJDIR)/setup_.c \ $(OBJDIR)/setupuser_.c \ $(OBJDIR)/sha1_.c \ $(OBJDIR)/sha1hard_.c \ $(OBJDIR)/sha3_.c \ $(OBJDIR)/shun_.c \ $(OBJDIR)/sitemap_.c \ $(OBJDIR)/skins_.c \ $(OBJDIR)/smtp_.c \ |
︙ | ︙ | |||
779 780 781 782 783 784 785 786 787 788 789 790 791 792 | $(OBJDIR)/wysiwyg_.c \ $(OBJDIR)/xfer_.c \ $(OBJDIR)/xfersetup_.c \ $(OBJDIR)/zip_.c OBJ = \ $(OBJDIR)/add.o \ $(OBJDIR)/allrepo.o \ $(OBJDIR)/attach.o \ $(OBJDIR)/backoffice.o \ $(OBJDIR)/bag.o \ $(OBJDIR)/bisect.o \ $(OBJDIR)/blob.o \ $(OBJDIR)/branch.o \ | > | 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 | $(OBJDIR)/wysiwyg_.c \ $(OBJDIR)/xfer_.c \ $(OBJDIR)/xfersetup_.c \ $(OBJDIR)/zip_.c OBJ = \ $(OBJDIR)/add.o \ $(OBJDIR)/alerts.o \ $(OBJDIR)/allrepo.o \ $(OBJDIR)/attach.o \ $(OBJDIR)/backoffice.o \ $(OBJDIR)/bag.o \ $(OBJDIR)/bisect.o \ $(OBJDIR)/blob.o \ $(OBJDIR)/branch.o \ |
︙ | ︙ | |||
809 810 811 812 813 814 815 | $(OBJDIR)/delta.o \ $(OBJDIR)/deltacmd.o \ $(OBJDIR)/descendants.o \ $(OBJDIR)/diff.o \ $(OBJDIR)/diffcmd.o \ $(OBJDIR)/dispatch.o \ $(OBJDIR)/doc.o \ | < | 813 814 815 816 817 818 819 820 821 822 823 824 825 826 | $(OBJDIR)/delta.o \ $(OBJDIR)/deltacmd.o \ $(OBJDIR)/descendants.o \ $(OBJDIR)/diff.o \ $(OBJDIR)/diffcmd.o \ $(OBJDIR)/dispatch.o \ $(OBJDIR)/doc.o \ $(OBJDIR)/encode.o \ $(OBJDIR)/etag.o \ $(OBJDIR)/event.o \ $(OBJDIR)/export.o \ $(OBJDIR)/file.o \ $(OBJDIR)/finfo.o \ $(OBJDIR)/foci.o \ |
︙ | ︙ | |||
874 875 876 877 878 879 880 881 882 883 884 885 886 887 | $(OBJDIR)/regexp.o \ $(OBJDIR)/report.o \ $(OBJDIR)/rss.o \ $(OBJDIR)/schema.o \ $(OBJDIR)/search.o \ $(OBJDIR)/security_audit.o \ $(OBJDIR)/setup.o \ $(OBJDIR)/sha1.o \ $(OBJDIR)/sha1hard.o \ $(OBJDIR)/sha3.o \ $(OBJDIR)/shun.o \ $(OBJDIR)/sitemap.o \ $(OBJDIR)/skins.o \ $(OBJDIR)/smtp.o \ | > | 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 | $(OBJDIR)/regexp.o \ $(OBJDIR)/report.o \ $(OBJDIR)/rss.o \ $(OBJDIR)/schema.o \ $(OBJDIR)/search.o \ $(OBJDIR)/security_audit.o \ $(OBJDIR)/setup.o \ $(OBJDIR)/setupuser.o \ $(OBJDIR)/sha1.o \ $(OBJDIR)/sha1hard.o \ $(OBJDIR)/sha3.o \ $(OBJDIR)/shun.o \ $(OBJDIR)/sitemap.o \ $(OBJDIR)/skins.o \ $(OBJDIR)/smtp.o \ |
︙ | ︙ | |||
1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 | $(MKINDEX) $(TRANS_SRC) >$@ $(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES) $(MKBUILTIN) --prefix $(SRCDIR)/ $(EXTRA_FILES) >$@ $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(OBJDIR)/default_css.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h $(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \ $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \ $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \ $(OBJDIR)/backoffice_.c:$(OBJDIR)/backoffice.h \ $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \ $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \ $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \ $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \ | > | 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 | $(MKINDEX) $(TRANS_SRC) >$@ $(OBJDIR)/builtin_data.h: $(MKBUILTIN) $(EXTRA_FILES) $(MKBUILTIN) --prefix $(SRCDIR)/ $(EXTRA_FILES) >$@ $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/builtin_data.h $(OBJDIR)/default_css.h $(MAKEHEADERS) $(OBJDIR)/VERSION.h $(MAKEHEADERS) $(OBJDIR)/add_.c:$(OBJDIR)/add.h \ $(OBJDIR)/alerts_.c:$(OBJDIR)/alerts.h \ $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h \ $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \ $(OBJDIR)/backoffice_.c:$(OBJDIR)/backoffice.h \ $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \ $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \ $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \ $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \ |
︙ | ︙ | |||
1164 1165 1166 1167 1168 1169 1170 | $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h \ $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h \ $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h \ $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h \ $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h \ $(OBJDIR)/dispatch_.c:$(OBJDIR)/dispatch.h \ $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h \ | < | 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 | $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h \ $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h \ $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h \ $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h \ $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h \ $(OBJDIR)/dispatch_.c:$(OBJDIR)/dispatch.h \ $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h \ $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h \ $(OBJDIR)/etag_.c:$(OBJDIR)/etag.h \ $(OBJDIR)/event_.c:$(OBJDIR)/event.h \ $(OBJDIR)/export_.c:$(OBJDIR)/export.h \ $(OBJDIR)/file_.c:$(OBJDIR)/file.h \ $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \ $(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \ |
︙ | ︙ | |||
1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 | $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \ $(OBJDIR)/report_.c:$(OBJDIR)/report.h \ $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \ $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \ $(OBJDIR)/search_.c:$(OBJDIR)/search.h \ $(OBJDIR)/security_audit_.c:$(OBJDIR)/security_audit.h \ $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \ $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h \ $(OBJDIR)/sha1hard_.c:$(OBJDIR)/sha1hard.h \ $(OBJDIR)/sha3_.c:$(OBJDIR)/sha3.h \ $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h \ $(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \ $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \ $(OBJDIR)/smtp_.c:$(OBJDIR)/smtp.h \ | > | 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 | $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \ $(OBJDIR)/report_.c:$(OBJDIR)/report.h \ $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \ $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \ $(OBJDIR)/search_.c:$(OBJDIR)/search.h \ $(OBJDIR)/security_audit_.c:$(OBJDIR)/security_audit.h \ $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \ $(OBJDIR)/setupuser_.c:$(OBJDIR)/setupuser.h \ $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h \ $(OBJDIR)/sha1hard_.c:$(OBJDIR)/sha1hard.h \ $(OBJDIR)/sha3_.c:$(OBJDIR)/sha3.h \ $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h \ $(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \ $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \ $(OBJDIR)/smtp_.c:$(OBJDIR)/smtp.h \ |
︙ | ︙ | |||
1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 | $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/add.c >$@ $(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/add.o -c $(OBJDIR)/add_.c $(OBJDIR)/add.h: $(OBJDIR)/headers $(OBJDIR)/allrepo_.c: $(SRCDIR)/allrepo.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/allrepo.c >$@ $(OBJDIR)/allrepo.o: $(OBJDIR)/allrepo_.c $(OBJDIR)/allrepo.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/allrepo.o -c $(OBJDIR)/allrepo_.c | > > > > > > > > | 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 | $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/add.c >$@ $(OBJDIR)/add.o: $(OBJDIR)/add_.c $(OBJDIR)/add.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/add.o -c $(OBJDIR)/add_.c $(OBJDIR)/add.h: $(OBJDIR)/headers $(OBJDIR)/alerts_.c: $(SRCDIR)/alerts.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/alerts.c >$@ $(OBJDIR)/alerts.o: $(OBJDIR)/alerts_.c $(OBJDIR)/alerts.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/alerts.o -c $(OBJDIR)/alerts_.c $(OBJDIR)/alerts.h: $(OBJDIR)/headers $(OBJDIR)/allrepo_.c: $(SRCDIR)/allrepo.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/allrepo.c >$@ $(OBJDIR)/allrepo.o: $(OBJDIR)/allrepo_.c $(OBJDIR)/allrepo.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/allrepo.o -c $(OBJDIR)/allrepo_.c |
︙ | ︙ | |||
1524 1525 1526 1527 1528 1529 1530 | $(TRANSLATE) $(SRCDIR)/doc.c >$@ $(OBJDIR)/doc.o: $(OBJDIR)/doc_.c $(OBJDIR)/doc.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/doc.o -c $(OBJDIR)/doc_.c $(OBJDIR)/doc.h: $(OBJDIR)/headers | < < < < < < < < | 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 | $(TRANSLATE) $(SRCDIR)/doc.c >$@ $(OBJDIR)/doc.o: $(OBJDIR)/doc_.c $(OBJDIR)/doc.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/doc.o -c $(OBJDIR)/doc_.c $(OBJDIR)/doc.h: $(OBJDIR)/headers $(OBJDIR)/encode_.c: $(SRCDIR)/encode.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/encode.c >$@ $(OBJDIR)/encode.o: $(OBJDIR)/encode_.c $(OBJDIR)/encode.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/encode.o -c $(OBJDIR)/encode_.c $(OBJDIR)/encode.h: $(OBJDIR)/headers |
︙ | ︙ | |||
2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 | $(OBJDIR)/setup_.c: $(SRCDIR)/setup.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/setup.c >$@ $(OBJDIR)/setup.o: $(OBJDIR)/setup_.c $(OBJDIR)/setup.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/setup.o -c $(OBJDIR)/setup_.c $(OBJDIR)/setup.h: $(OBJDIR)/headers $(OBJDIR)/sha1_.c: $(SRCDIR)/sha1.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/sha1.c >$@ $(OBJDIR)/sha1.o: $(OBJDIR)/sha1_.c $(OBJDIR)/sha1.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/sha1.o -c $(OBJDIR)/sha1_.c | > > > > > > > > | 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 | $(OBJDIR)/setup_.c: $(SRCDIR)/setup.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/setup.c >$@ $(OBJDIR)/setup.o: $(OBJDIR)/setup_.c $(OBJDIR)/setup.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/setup.o -c $(OBJDIR)/setup_.c $(OBJDIR)/setup.h: $(OBJDIR)/headers $(OBJDIR)/setupuser_.c: $(SRCDIR)/setupuser.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/setupuser.c >$@ $(OBJDIR)/setupuser.o: $(OBJDIR)/setupuser_.c $(OBJDIR)/setupuser.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/setupuser.o -c $(OBJDIR)/setupuser_.c $(OBJDIR)/setupuser.h: $(OBJDIR)/headers $(OBJDIR)/sha1_.c: $(SRCDIR)/sha1.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/sha1.c >$@ $(OBJDIR)/sha1.o: $(OBJDIR)/sha1_.c $(OBJDIR)/sha1.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/sha1.o -c $(OBJDIR)/sha1_.c |
︙ | ︙ |
Changes to win/Makefile.msc.
︙ | ︙ | |||
108 109 110 111 112 113 114 | SSLLIBDIR = $(SSLDIR)\out32 !endif SSLLFLAGS = /nologo /opt:ref /debug SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib crypt32.lib !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64" !message Using 'x64' platform for OpenSSL... # BUGBUG (OpenSSL): Using "no-ssl*" here breaks the build. | | | | | | | | 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | SSLLIBDIR = $(SSLDIR)\out32 !endif SSLLFLAGS = /nologo /opt:ref /debug SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib crypt32.lib !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64" !message Using 'x64' platform for OpenSSL... # BUGBUG (OpenSSL): Using "no-ssl*" here breaks the build. # SSLCONFIG = VC-WIN64A no-asm no-ssl3 no-weak-ssl-ciphers SSLCONFIG = VC-WIN64A no-asm !if $(FOSSIL_DYNAMIC_BUILD)!=0 SSLCONFIG = $(SSLCONFIG) shared !else SSLCONFIG = $(SSLCONFIG) no-shared !endif SSLSETUP = ms\do_win64a.bat !if $(FOSSIL_DYNAMIC_BUILD)!=0 SSLNMAKE = ms\ntdll.mak all !else SSLNMAKE = ms\nt.mak all !endif # BUGBUG (OpenSSL): Using "OPENSSL_NO_SSL*" here breaks dynamic builds. !if $(FOSSIL_DYNAMIC_BUILD)==0 SSLCFLAGS = -DOPENSSL_NO_SSL3 -DOPENSSL_NO_WEAK_SSL_CIPHERS !endif !elseif "$(PLATFORM)"=="ia64" !message Using 'ia64' platform for OpenSSL... # BUGBUG (OpenSSL): Using "no-ssl*" here breaks the build. # SSLCONFIG = VC-WIN64I no-asm no-ssl3 no-weak-ssl-ciphers SSLCONFIG = VC-WIN64I no-asm !if $(FOSSIL_DYNAMIC_BUILD)!=0 SSLCONFIG = $(SSLCONFIG) shared !else SSLCONFIG = $(SSLCONFIG) no-shared !endif SSLSETUP = ms\do_win64i.bat !if $(FOSSIL_DYNAMIC_BUILD)!=0 SSLNMAKE = ms\ntdll.mak all !else SSLNMAKE = ms\nt.mak all !endif # BUGBUG (OpenSSL): Using "OPENSSL_NO_SSL*" here breaks dynamic builds. !if $(FOSSIL_DYNAMIC_BUILD)==0 SSLCFLAGS = -DOPENSSL_NO_SSL3 -DOPENSSL_NO_WEAK_SSL_CIPHERS !endif !else !message Assuming 'x86' platform for OpenSSL... # BUGBUG (OpenSSL): Using "no-ssl*" here breaks the build. # SSLCONFIG = VC-WIN32 no-asm no-ssl3 no-weak-ssl-ciphers SSLCONFIG = VC-WIN32 no-asm !if $(FOSSIL_DYNAMIC_BUILD)!=0 SSLCONFIG = $(SSLCONFIG) shared !else SSLCONFIG = $(SSLCONFIG) no-shared !endif SSLSETUP = ms\do_ms.bat !if $(FOSSIL_DYNAMIC_BUILD)!=0 SSLNMAKE = ms\ntdll.mak all !else SSLNMAKE = ms\nt.mak all !endif # BUGBUG (OpenSSL): Using "OPENSSL_NO_SSL*" here breaks dynamic builds. !if $(FOSSIL_DYNAMIC_BUILD)==0 SSLCFLAGS = -DOPENSSL_NO_SSL3 -DOPENSSL_NO_WEAK_SSL_CIPHERS !endif !endif !endif !if $(FOSSIL_ENABLE_TCL)!=0 TCLDIR = $(B)\compat\tcl-8.6 TCLSRCDIR = $(TCLDIR) |
︙ | ︙ | |||
377 378 379 380 381 382 383 384 385 386 387 388 389 390 | /Dfopen=fossil_fopen MINIZ_OPTIONS = /DMINIZ_NO_STDIO \ /DMINIZ_NO_TIME \ /DMINIZ_NO_ARCHIVE_APIS SRC = add_.c \ allrepo_.c \ attach_.c \ backoffice_.c \ bag_.c \ bisect_.c \ blob_.c \ branch_.c \ | > | 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 | /Dfopen=fossil_fopen MINIZ_OPTIONS = /DMINIZ_NO_STDIO \ /DMINIZ_NO_TIME \ /DMINIZ_NO_ARCHIVE_APIS SRC = add_.c \ alerts_.c \ allrepo_.c \ attach_.c \ backoffice_.c \ bag_.c \ bisect_.c \ blob_.c \ branch_.c \ |
︙ | ︙ | |||
407 408 409 410 411 412 413 | delta_.c \ deltacmd_.c \ descendants_.c \ diff_.c \ diffcmd_.c \ dispatch_.c \ doc_.c \ | < | 408 409 410 411 412 413 414 415 416 417 418 419 420 421 | delta_.c \ deltacmd_.c \ descendants_.c \ diff_.c \ diffcmd_.c \ dispatch_.c \ doc_.c \ encode_.c \ etag_.c \ event_.c \ export_.c \ file_.c \ finfo_.c \ foci_.c \ |
︙ | ︙ | |||
539 540 541 542 543 544 545 546 547 548 549 550 551 552 | $(SRCDIR)\..\skins\bootstrap\details.txt \ $(SRCDIR)\..\skins\bootstrap\footer.txt \ $(SRCDIR)\..\skins\bootstrap\header.txt \ $(SRCDIR)\..\skins\default\css.txt \ $(SRCDIR)\..\skins\default\details.txt \ $(SRCDIR)\..\skins\default\footer.txt \ $(SRCDIR)\..\skins\default\header.txt \ $(SRCDIR)\..\skins\eagle\css.txt \ $(SRCDIR)\..\skins\eagle\details.txt \ $(SRCDIR)\..\skins\eagle\footer.txt \ $(SRCDIR)\..\skins\eagle\header.txt \ $(SRCDIR)\..\skins\enhanced1\css.txt \ $(SRCDIR)\..\skins\enhanced1\details.txt \ $(SRCDIR)\..\skins\enhanced1\footer.txt \ | > | 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 | $(SRCDIR)\..\skins\bootstrap\details.txt \ $(SRCDIR)\..\skins\bootstrap\footer.txt \ $(SRCDIR)\..\skins\bootstrap\header.txt \ $(SRCDIR)\..\skins\default\css.txt \ $(SRCDIR)\..\skins\default\details.txt \ $(SRCDIR)\..\skins\default\footer.txt \ $(SRCDIR)\..\skins\default\header.txt \ $(SRCDIR)\..\skins\default\js.txt \ $(SRCDIR)\..\skins\eagle\css.txt \ $(SRCDIR)\..\skins\eagle\details.txt \ $(SRCDIR)\..\skins\eagle\footer.txt \ $(SRCDIR)\..\skins\eagle\header.txt \ $(SRCDIR)\..\skins\enhanced1\css.txt \ $(SRCDIR)\..\skins\enhanced1\details.txt \ $(SRCDIR)\..\skins\enhanced1\footer.txt \ |
︙ | ︙ | |||
584 585 586 587 588 589 590 591 592 593 594 595 596 597 | $(SRCDIR)\skin.js \ $(SRCDIR)\sorttable.js \ $(SRCDIR)\tree.js \ $(SRCDIR)\useredit.js \ $(SRCDIR)\wiki.wiki OBJ = $(OX)\add$O \ $(OX)\allrepo$O \ $(OX)\attach$O \ $(OX)\backoffice$O \ $(OX)\bag$O \ $(OX)\bisect$O \ $(OX)\blob$O \ $(OX)\branch$O \ | > | 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 | $(SRCDIR)\skin.js \ $(SRCDIR)\sorttable.js \ $(SRCDIR)\tree.js \ $(SRCDIR)\useredit.js \ $(SRCDIR)\wiki.wiki OBJ = $(OX)\add$O \ $(OX)\alerts$O \ $(OX)\allrepo$O \ $(OX)\attach$O \ $(OX)\backoffice$O \ $(OX)\bag$O \ $(OX)\bisect$O \ $(OX)\blob$O \ $(OX)\branch$O \ |
︙ | ︙ | |||
615 616 617 618 619 620 621 | $(OX)\delta$O \ $(OX)\deltacmd$O \ $(OX)\descendants$O \ $(OX)\diff$O \ $(OX)\diffcmd$O \ $(OX)\dispatch$O \ $(OX)\doc$O \ | < | 617 618 619 620 621 622 623 624 625 626 627 628 629 630 | $(OX)\delta$O \ $(OX)\deltacmd$O \ $(OX)\descendants$O \ $(OX)\diff$O \ $(OX)\diffcmd$O \ $(OX)\dispatch$O \ $(OX)\doc$O \ $(OX)\encode$O \ $(OX)\etag$O \ $(OX)\event$O \ $(OX)\export$O \ $(OX)\file$O \ $(OX)\finfo$O \ $(OX)\foci$O \ |
︙ | ︙ | |||
780 781 782 783 784 785 786 787 788 789 790 791 792 793 | codecheck1$E $(SRC) link $(LDFLAGS) /OUT:$@ $(LIBDIR) Wsetargv.obj fossil.res @linkopts if exist $@.manifest \ $(MTC) -nologo -manifest $@.manifest -outputresource:$@;1 $(OX)\linkopts: $B\win\Makefile.msc echo $(OX)\add.obj > $@ echo $(OX)\allrepo.obj >> $@ echo $(OX)\attach.obj >> $@ echo $(OX)\backoffice.obj >> $@ echo $(OX)\bag.obj >> $@ echo $(OX)\bisect.obj >> $@ echo $(OX)\blob.obj >> $@ echo $(OX)\branch.obj >> $@ | > | 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 | codecheck1$E $(SRC) link $(LDFLAGS) /OUT:$@ $(LIBDIR) Wsetargv.obj fossil.res @linkopts if exist $@.manifest \ $(MTC) -nologo -manifest $@.manifest -outputresource:$@;1 $(OX)\linkopts: $B\win\Makefile.msc echo $(OX)\add.obj > $@ echo $(OX)\alerts.obj >> $@ echo $(OX)\allrepo.obj >> $@ echo $(OX)\attach.obj >> $@ echo $(OX)\backoffice.obj >> $@ echo $(OX)\bag.obj >> $@ echo $(OX)\bisect.obj >> $@ echo $(OX)\blob.obj >> $@ echo $(OX)\branch.obj >> $@ |
︙ | ︙ | |||
811 812 813 814 815 816 817 | echo $(OX)\delta.obj >> $@ echo $(OX)\deltacmd.obj >> $@ echo $(OX)\descendants.obj >> $@ echo $(OX)\diff.obj >> $@ echo $(OX)\diffcmd.obj >> $@ echo $(OX)\dispatch.obj >> $@ echo $(OX)\doc.obj >> $@ | < | 813 814 815 816 817 818 819 820 821 822 823 824 825 826 | echo $(OX)\delta.obj >> $@ echo $(OX)\deltacmd.obj >> $@ echo $(OX)\descendants.obj >> $@ echo $(OX)\diff.obj >> $@ echo $(OX)\diffcmd.obj >> $@ echo $(OX)\dispatch.obj >> $@ echo $(OX)\doc.obj >> $@ echo $(OX)\encode.obj >> $@ echo $(OX)\etag.obj >> $@ echo $(OX)\event.obj >> $@ echo $(OX)\export.obj >> $@ echo $(OX)\file.obj >> $@ echo $(OX)\finfo.obj >> $@ echo $(OX)\foci.obj >> $@ |
︙ | ︙ | |||
1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 | $(OBJDIR)\json_wiki$O : $(SRCDIR)\json_detail.h $(OX)\add$O : add_.c add.h $(TCC) /Fo$@ -c add_.c add_.c : $(SRCDIR)\add.c translate$E $** > $@ $(OX)\allrepo$O : allrepo_.c allrepo.h $(TCC) /Fo$@ -c allrepo_.c allrepo_.c : $(SRCDIR)\allrepo.c translate$E $** > $@ | > > > > > > | 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 | $(OBJDIR)\json_wiki$O : $(SRCDIR)\json_detail.h $(OX)\add$O : add_.c add.h $(TCC) /Fo$@ -c add_.c add_.c : $(SRCDIR)\add.c translate$E $** > $@ $(OX)\alerts$O : alerts_.c alerts.h $(TCC) /Fo$@ -c alerts_.c alerts_.c : $(SRCDIR)\alerts.c translate$E $** > $@ $(OX)\allrepo$O : allrepo_.c allrepo.h $(TCC) /Fo$@ -c allrepo_.c allrepo_.c : $(SRCDIR)\allrepo.c translate$E $** > $@ |
︙ | ︙ | |||
1224 1225 1226 1227 1228 1229 1230 | $(OX)\doc$O : doc_.c doc.h $(TCC) /Fo$@ -c doc_.c doc_.c : $(SRCDIR)\doc.c translate$E $** > $@ | < < < < < < | 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 | $(OX)\doc$O : doc_.c doc.h $(TCC) /Fo$@ -c doc_.c doc_.c : $(SRCDIR)\doc.c translate$E $** > $@ $(OX)\encode$O : encode_.c encode.h $(TCC) /Fo$@ -c encode_.c encode_.c : $(SRCDIR)\encode.c translate$E $** > $@ $(OX)\etag$O : etag_.c etag.h |
︙ | ︙ | |||
1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 | translate$E $** > $@ fossil.res : $B\win\fossil.rc $(RCC) /fo $@ $** headers: makeheaders$E page_index.h builtin_data.h default_css.h VERSION.h makeheaders$E add_.c:add.h \ allrepo_.c:allrepo.h \ attach_.c:attach.h \ backoffice_.c:backoffice.h \ bag_.c:bag.h \ bisect_.c:bisect.h \ blob_.c:blob.h \ branch_.c:branch.h \ | > | 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 | translate$E $** > $@ fossil.res : $B\win\fossil.rc $(RCC) /fo $@ $** headers: makeheaders$E page_index.h builtin_data.h default_css.h VERSION.h makeheaders$E add_.c:add.h \ alerts_.c:alerts.h \ allrepo_.c:allrepo.h \ attach_.c:attach.h \ backoffice_.c:backoffice.h \ bag_.c:bag.h \ bisect_.c:bisect.h \ blob_.c:blob.h \ branch_.c:branch.h \ |
︙ | ︙ | |||
1883 1884 1885 1886 1887 1888 1889 | delta_.c:delta.h \ deltacmd_.c:deltacmd.h \ descendants_.c:descendants.h \ diff_.c:diff.h \ diffcmd_.c:diffcmd.h \ dispatch_.c:dispatch.h \ doc_.c:doc.h \ | < | 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 | delta_.c:delta.h \ deltacmd_.c:deltacmd.h \ descendants_.c:descendants.h \ diff_.c:diff.h \ diffcmd_.c:diffcmd.h \ dispatch_.c:dispatch.h \ doc_.c:doc.h \ encode_.c:encode.h \ etag_.c:etag.h \ event_.c:event.h \ export_.c:export.h \ file_.c:file.h \ finfo_.c:finfo.h \ foci_.c:foci.h \ |
︙ | ︙ |
Changes to www/aboutdownload.wiki.
1 2 3 4 5 6 7 8 9 10 | <title>How The Fossil Download Page Works</title> <h1 align="center">How The Download Page Works</h1> <h2>1.0 Overview</h2> The [/uv/download.html|Download] page for the Fossil self-hosting repository is implemented using [./unvers.wiki|unversioned files]. The "download.html" screen itself, and the various build products are all stored as unversioned content. The download.html page uses AJAX to retrieve the [/help?cmd=/juvlist|/juvlist] webpage | | > | | | > > | | > > | > > | < | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 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 | <title>How The Fossil Download Page Works</title> <h1 align="center">How The Download Page Works</h1> <h2>1.0 Overview</h2> The [/uv/download.html|Download] page for the Fossil self-hosting repository is implemented using [./unvers.wiki|unversioned files]. The "download.html" screen itself, and the various build products are all stored as unversioned content. The download.html page uses AJAX to retrieve the [/help?cmd=/juvlist|/juvlist] webpage for a list of all unversioned files. Javascript in the [/uv/download.js?mimetype=text/plain|download.js] file (which is sourced by "download.html") then figures out which unversioned files are build products and paints appropriate icons on the displayed download page. When a new version is generated, the developers use the [/help?cmd=uv|fossil uv edit] command to make minor changes to the "[/uv/download.js?mimetype=text/plain|download.js]" file so that it knows about the new version number. Then the developers run the [/help?cmd=uv|fossil uv add] command for each build product. Finally, the [/help?cmd=uv|fossil uv sync] command is run to push all the content up to servers. All [./selfhost.wiki|three self-hosting repositories] for Fossil are updated automatically. <h2>2.0 Details</h2> The current text of the "download.html" and "download.js" files can be seen at: * [/uv/download.html?mimetype=text/plain] * [/uv/download.js?mimetype=text/plain] Notice how the hyperlinks above use the "mimetype=text/plain" query parameter in order to display the file as plain text instead of the usual HTML or Javascript. The default mimetype for "download.html" is text/html. But because the entire page is enclosed within <b><div class='fossil-doc' data-title='Download Page'>...</div></b> Fossil knows to add its standard header and footer information to the document, making it look just like any other page. See "[./embeddeddoc.wiki|embedded documentation]" for further details on how <div class='fossil-doc'> this works. With each new release, the "releases" variable in the javascript on the [/uv/download.js?mimetype=text/plain|download.js] page is edited (using "[/help?cmd=uv|fossil uv edit download.js]") to add details of the release. When the javascript in the "download.js" file runs, it requests a listing of all unversioned content using the /juvlist URL. ([/juvlist|sample /juvlist output]). The content of the download page is constructed by matching unversioned files against regular expressions in the "releases" variable. Build products need to be constructed on different machines. The precompiled binary for Linux is compiled on Linux, the precompiled binary for Windows is compiled on Windows10, and so forth. After a new release is tagged, the release manager goes around to each of the target platforms, checks out the release and compiles it, then runs [/help?cmd=uv|fossil uv add] for the build product followed by [/help?cmd=uv|fossil uv sync] to push the new build product to the [./selfhost.wiki|various servers]. This process is repeated for each build product. When older builds are retired from the download page, the [/uv/download.js?mimetype=text/plain|download.js] page is again edited to remove the corresponding entry from the "release" variable and the edit is synced using [/help?cmd=uv|fossil uv sync]. This causes the build products to disappear from the download page immediately. But those build products are still taking up space in the unversioned content table of the server repository. To purge the obsolete build products, one or more [/help?cmd=uv|fossil uv rm] commands are run, followed by |
︙ | ︙ |
Changes to www/changes.wiki.
1 2 3 4 5 | <title>Change Log</title> <a name='v2_7'></a> <h2>Changes for Version 2.7 (2018-??-??)</h2> | | > | | > > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <title>Change Log</title> <a name='v2_7'></a> <h2>Changes for Version 2.7 (2018-??-??)</h2> * Add the [./alerts.md|email alerts] feature for commits, ticket changes, wiki changes, forum posts, and announcements. * Add the discussion forum feature. * Add new user capabilities letters needed to support alerts and forum. Formerly, user capabilities were letters from [a-z], but with the enhancements, the supply of lower case letters was exhausted. User capabilities are now letters in [a-zA-Z0-9]. * The default skin is now responsive, providing better layout on small screens, including mobile devices. * Add the [./backoffice.md|backoffice]. * Update internal Unicode character tables, used in regular expression handling, from version 10.0 to 11.0. * Improvements to the "Security Audit" administration page <a name='v2_6'></a> <h2>Changes for Version 2.6 (2018-05-04)</h2> |
︙ | ︙ |
Changes to www/forum.wiki.
︙ | ︙ | |||
171 172 173 174 175 176 177 | For either type of repository, you are likely to want to give at least the WriteTrusted capability (4) to users in the <tt>developer</tt> category. If you did not give the Read Forum capability (2) to <tt>anonymous</tt> above, you should give <tt>developer</tt> that capability here if you choose to give it capability 3 or 4. | > | | | | | | | | | | | > > | > > > > > | > > > > > > > > > | | | | 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | For either type of repository, you are likely to want to give at least the WriteTrusted capability (4) to users in the <tt>developer</tt> category. If you did not give the Read Forum capability (2) to <tt>anonymous</tt> above, you should give <tt>developer</tt> that capability here if you choose to give it capability 3 or 4. If you want to use the email notification feature, by default only those users in the Setup and Admin user categories can make use of it. Grant the Email Alerts capability (7) to give others access to this feature. Alternately, you can handle notification signups outside of Fossil, with a Setup or Admin users manually signing users up via Admin → Notification. You'll want to grant this capability to the <tt>nobody</tt> user category if you want anyone to sign up without any restrictions. Give it to <tt>anonymous</tt> instead if you want the user to solve a simple CAPTCHA before signing up. Or, give it to <tt>reader</tt> or <tt>developer</tt> if you want only users with Fossil logins to have this ability. (That's assuming you give one or both of these capabilities to every user on your Fossil repository.) By following this advice, you should not need to tediously add capabilities to individual accounts except in atypical cases, such as to grant the Moderate Forum capability (5) to an uncommonly highly-trusted user. <h3 id="skin">Skin Setup</h3> If you create a new Fossil repository with version 2.7 or newer, its default skin is already set up correctly for typical forum configurations. If you have an existing repository, you have two choices if you want its skin to be upgraded to support forums: <ol> <li>Go into Admin → Skins and switch from your current skin to one of the stock skins. If you were on a stock skin, just switch away from your current one to the actual stock skin, since they will be different after the upgrade.</li> <li>If you have local customization that you do not want to throw away, you can use the diff feature of Fossil's skin editor to show how the skins differ.</li> </ol> The remainder of this section summarizes the differences you're expected to see when taking option #2. The first thing is that you'll need to add something like the following to the Header part of the skin to create the navbar link: <verbatim> if {[anycap 234567] || [anoncap 2] || [anoncap 3]} { menulink /forum Forum } </verbatim> These rules say that any logged-in user with any forum-related capability (2-7 inclusive, as of this writing) or an anonymous user with read or write capability on the forum (2, 3) will see the "Forum" navbar link, which just takes you to <tt>/forum</tt>. The exact code you need here varies depending on which skin you're using. Follow the style you see for the other navbar links. The new forum feature also brings many new CSS styles to the table. If |
︙ | ︙ | |||
238 239 240 241 242 243 244 245 246 247 248 249 250 251 | <verbatim> div.forumSel { background-color: rgba(255, 255, 255, 0.05); } </verbatim> That overlays the background with 5% white to lighten it slightly. <h3 id="search">Enable Forum Search</h3> One of the underlying assumptions of the forum feature is that you will want to be able to search the forum archives, so the <tt>/forum</tt> page always includes a search box. Since that depends on search being | > > > > > > > > > > > > > > > > > > > > > > > > > | 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 | <verbatim> div.forumSel { background-color: rgba(255, 255, 255, 0.05); } </verbatim> That overlays the background with 5% white to lighten it slightly. Another new forum-related CSS style you might want to reflect into your existing skin is: <verbatim> div.forumPosts a:visited { color: #6A7F94; } </verbatim> This changes the clicked-hyperlink color for the forum post links on the main <tt>/forum</tt> page only, which allows your browser's history mechanism to show which threads a user has read and which not. The link color will change back to the normal link color — indicating "unread" — when a reply is added to an existing thread because that changes where the link from the <tt>/forum</tt> page points, taking you to the newest post in the thread. The color given above is suitable for the stock skin. Beware that when changing this example, there are some [https://hacks.mozilla.org/2010/03/privacy-related-changes-coming-to-css-vistited/ | stringent restrictions] in modern browsers to prevent snoopy web sites from brute-forcing your browsing history. (See the link for the method, which explains the restrictions.) <h3 id="search">Enable Forum Search</h3> One of the underlying assumptions of the forum feature is that you will want to be able to search the forum archives, so the <tt>/forum</tt> page always includes a search box. Since that depends on search being |
︙ | ︙ |
Changes to www/th1.md.
︙ | ︙ | |||
31 32 33 34 35 36 37 | operations are accomplished by converting from string to numeric, performing the computation, then converting the result back into a string. (This might seem inefficient, but it is faster than people imagine, and numeric computations do not come up very often for the kinds of work that TH1 does, so it has never been a factor.) A TH1 script consist of a sequence of commands. | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | operations are accomplished by converting from string to numeric, performing the computation, then converting the result back into a string. (This might seem inefficient, but it is faster than people imagine, and numeric computations do not come up very often for the kinds of work that TH1 does, so it has never been a factor.) A TH1 script consist of a sequence of commands. Each command is terminated by the first *unescaped* newline or ";" character. The text of the command (excluding the newline or semicolon terminator) is broken into space-separated tokens. The first token is the command name and subsequent tokens are the arguments. In this sense, TH1 syntax is similar to the familiar command-line shell syntax. A token is any sequence of characters other than whitespace and semicolons. Or, all text without double-quotes is a single token even if it includes whitespace and semicolons. Or, all text without nested {...} pairs is a single token. The nested {...} form of tokens is important because it allows TH1 commands to have an appearance similar to C/C++. It is important to remember, though, that a TH1 script is really just a list of text commands, not a context-free language with a grammar like C/C++. This can be confusing to long-time C/C++ programmers because TH1 does look a lot like C/C++, but the semantics of TH1 are closer to FORTH or Lisp than they are to C. Consider the `if` command in TH1. if {$current eq "dev"} { puts "hello" } else { puts "world" } The example above is a single command. The first token, and the name of the command, is `if`. The second token is `$current eq "dev"` - an expression. (The outer {...} are removed from each token by the command parser.) The third token is the `puts "hello"`, with its whitespace and newlines. The fourth token is `else"` And the fifth and last token is `puts "world"`. The `if` command evaluates its first argument (the second token) as an expression, and if that expression is true, evaluates its second argument (the third token) as a TH1 script. If the expression is false and the third argument is `else`, then the fourth argument is evaluated as a TH1 expression. So, you see, even though the example above spans five lines, it is really just a single command. All of this also explains the emphasis on *unescaped* characters above: the curly braces `{ }` are string quoting characters in Tcl/TH1, not block delimiters as in C. This is how we can have a command that extends over multiple lines. It is also why the `else` keyword must be cuddled up with the closing brace for the `if` clause's scriptlet. The following is invalid Tcl/TH1: if {$current eq "dev"} { puts "hello" } else { puts "world" } If you try to run this under either Tcl or TH1, the interpreter will tell you that there is no `else` command, because with the newline on the third line, you terminated the `if` command. Occasionally in Tcl/TH1 scripts, you may need to use a backslash at the end of a line to allow a command to extend over multiple lines without being considered two separate commands. Here's an example from one of Fossil's test scripts: return [lindex [regexp -line -inline -nocase -- \ {^uuid:\s+([0-9A-F]{40}) } [eval [getFossilCommand \ $repository "" info trunk]]] end] Those backslashes allow the command to wrap nicely within a standard terminal width while telling the interpreter to consider those three lines as a single command. Summary of Core TH1 Commands ---------------------------- The original Tcl language after when TH1 is modeled has a very rich repertoire of commands. TH1, as it is designed to be minimalist and embedded has a greatly reduced command set. The following bullets |
︙ | ︙ |