Check-in [766bec08ce]
Not logged in
Overview

SHA1 Hash:766bec08cebeb858a874df71c4d6e3961e3a33e8
Date: 2009-01-25 19:18:09
User: drh
Comment:Documentation tweaks. Change the "Setup" menu title to "Admin". Added pages under Admin to view the RCVFROM table of the database.
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified src/info.c from [b888c0d485] to [420d4f7587].

@@ -390,14 +390,30 @@
       @ <tr><th>Original&nbsp;Comment:</th><td>%w(zComment)</td></tr>
     }else{
       @ <tr><th>Comment:</th><td>%w(zComment)</td></tr>
     }
     @ </td></tr>
+    if( g.okAdmin ){
+      db_prepare(&q,
+         "SELECT rcvfrom.ipaddr, user.login, datetime(rcvfrom.mtime)"
+         "  FROM blob JOIN rcvfrom USING(rcvid) LEFT JOIN user USING(uid)"
+         " WHERE blob.rid=%d",
+         rid
+      );
+      if( db_step(&q)==SQLITE_ROW ){
+        const char *zIpAddr = db_column_text(&q, 0);
+        const char *zUser = db_column_text(&q, 1);
+        const char *zDate = db_column_text(&q, 2);
+        if( zUser==0 || zUser[0]==0 ) zUser = "unknown";
+        @ <tr><th>Received&nbsp;From:</th>
+        @ <td>%h(zUser) @ %h(zIpAddr) on %s(zDate)</td></tr>
+      }
+      db_finalize(&q);
+    }
     if( g.okHistory ){
       char *zShortUuid = mprintf("%.10s", zUuid);
       const char *zProjName = db_get("project-name", "unnamed");
-      Stmt q;
       @ <tr><th>Timelines:</th><td>
       @    <a href="%s(g.zBaseURL)/timeline?p=%d(rid)">ancestors</a>
       @    | <a href="%s(g.zBaseURL)/timeline?d=%d(rid)">descendants</a>
       @    | <a href="%s(g.zBaseURL)/timeline?d=%d(rid)&p=%d(rid)">both</a>
       db_prepare(&q, "SELECT substr(tag.tagname,5) FROM tagxref, tag "
@@ -1127,13 +1143,10 @@
     style_footer();
     return;
   }
   if( db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid) ){
     vinfo_page();
-  }else
-  if( db_exists("SELECT 1 FROM mlink WHERE fid=%d", rid) ){
-    finfo_page();
   }else
   if( db_exists("SELECT 1 FROM tagxref JOIN tag USING(tagid)"
                 " WHERE rid=%d AND tagname LIKE 'wiki-%%'", rid) ){
     winfo_page();
   }else

Modified src/setup.c from [fca5464418] to [9d845dbac4].

@@ -56,11 +56,11 @@
   login_check_credentials();
   if( !g.okSetup ){
     login_needed();
   }
 
-  style_header("Setup");
+  style_header("Server Administration");
   @ <table border="0" cellspacing="20">
   setup_menu_entry("Users", "setup_ulist",
     "Grant privileges to individual users.");
   setup_menu_entry("Access", "setup_access",
     "Control access settings.");
@@ -76,10 +76,12 @@
     "Edit HTML text inserted at the top of every page");
   setup_menu_entry("Footer", "setup_footer",
     "Edit HTML text inserted at the bottom of every page");
   setup_menu_entry("Shunned", "shun",
     "Show artifacts that are shunned by this repository");
+  setup_menu_entry("Log", "rcvfromlist",
+    "A record of received artifacts and their sources");
   setup_menu_entry("Stats", "stat",
     "Display repository statistics");
   @ </table>
 
   style_footer();

Modified src/shun.c from [ffc8251555] to [a2062a7125].

@@ -26,11 +26,11 @@
 #include "config.h"
 #include "shun.h"
 #include <assert.h>
 
 /*
-** Return true if the given UUID should be shunned.
+** Return true if the given artifact ID should be shunned.
 */
 int uuid_is_shunned(const char *zUuid){
   static Stmt q;
   int rc;
   if( zUuid==0 || zUuid[0]==0 ) return 0;
@@ -119,14 +119,18 @@
   }
   db_finalize(&q);
   @ </blockquote>
   @ <hr>
   @ <a name="addshun"></a>
-  @ <p>To shun an artifact, enter its UUID in the
+  @ <p>To shun an artifact, enter its artifact ID (the 40-character SHA1
+  @ hash of the artifact) in the
   @ following box and press the "Shun" button.  This will cause the artifact
   @ to be removed from the repository and will prevent the artifact from being
   @ readded to the repository by subsequent sync operation.</p>
+  @
+  @ <p>Note that you must enter the full 40-character artifact ID, not
+  @ an abbreviation or a symbolic tag.</p>
   @
   @ <p>Warning:  Shunning should only be used to remove inappropriate content
   @ from the repository.  Inappropriate content includes such things as
   @ spam added to Wiki, files that violate copyright or patent agreements,
   @ or artifacts that by design or accident interfere with the processing
@@ -153,10 +157,11 @@
   @ <input type="text" name="uuid" size="50">
   @ <input type="submit" name="sub" value="Accept">
   @ </form>
   @ </blockquote>
   @
+  @ <hr>
   @ <p>Press the button below to rebuild the respository.  The rebuild
   @ may take several seconds, so be patient after pressing the button.</p>
   @
   @ <blockquote>
   @ <form method="POST" action="%s(g.zBaseURL)/%s(g.zPath)">
@@ -188,6 +193,110 @@
   db_multi_exec(
      "DELETE FROM delta WHERE rid IN toshun;"
      "DELETE FROM blob WHERE rid IN toshun;"
      "DROP TABLE toshun;"
   );
+}
+
+/*
+** WEBPAGE: rcvfromlist
+**
+** Show a listing of RCVFROM table entries.
+*/
+void rcvfromlist_page(void){
+  int ofst = atoi(PD("ofst","0"));
+  int cnt;
+  Stmt q;
+
+  login_check_credentials();
+  if( !g.okAdmin ){
+    login_needed();
+  }
+  style_header("Content Sources");
+  if( ofst>0 ){
+    style_submenu_element("Later", "Later", "rcvfromlist?ofst=%d",
+                           ofst>30 ? ofst-30 : 0);
+  }
+  db_prepare(&q,
+    "SELECT rcvid, login, datetime(rcvfrom.mtime), rcvfrom.ipaddr"
+    "  FROM rcvfrom LEFT JOIN user USING(uid)"
+    " ORDER BY rcvid DESC LIMIT 31 OFFSET %d",
+    ofst
+  );
+  @ <table cellpadding=0 cellspacing=0 border=0>
+  @ <tr><th>rcvid</th><th width=15>
+  @     <th>Date</th><th width=15><th>User</th>
+  @     <th width=15><th>IP&nbsp;Address</th></tr>
+  cnt = 0;
+  while( db_step(&q)==SQLITE_ROW ){
+    int rcvid = db_column_int(&q, 0);
+    const char *zUser = db_column_text(&q, 1);
+    const char *zDate = db_column_text(&q, 2);
+    const char *zIpAddr = db_column_text(&q, 3);
+    if( cnt==30 ){
+      style_submenu_element("Earlier", "Earlier",
+         "rcvfromlist?ofst=%d", ofst+30);
+    }else{
+      cnt++;
+      @ <tr>
+      @ <td><a href="rcvfrom?rcvid=%d(rcvid)">%d(rcvid)</a></td><td>
+      @ <td>%s(zDate)</td><td>
+      @ <td>%h(zUser)</td><td>
+      @ <td>&nbsp;%s(zIpAddr)&nbsp</td>
+      @ </tr>
+    }
+  }
+  db_finalize(&q);
+  @ </table>
+  style_footer();
+}
+
+/*
+** WEBPAGE: rcvfrom
+**
+** Show a single RCVFROM table entry.
+*/
+void rcvfrom_page(void){
+  int rcvid = atoi(PD("rcvid","0"));
+  Stmt q;
+
+  login_check_credentials();
+  if( !g.okAdmin ){
+    login_needed();
+  }
+  style_header("Content Source %d", rcvid);
+  db_prepare(&q,
+    "SELECT login, datetime(rcvfrom.mtime), rcvfrom.ipaddr"
+    "  FROM rcvfrom LEFT JOIN user USING(uid)"
+    " WHERE rcvid=%d",
+    rcvid
+  );
+  @ <table cellspacing=15 cellpadding=0 border=0>
+  @ <tr><td valign="top" align="right">rcvid:</td>
+  @ <td valign="top">%d(rcvid)</td></tr>
+  if( db_step(&q)==SQLITE_ROW ){
+    const char *zUser = db_column_text(&q, 0);
+    const char *zDate = db_column_text(&q, 1);
+    const char *zIpAddr = db_column_text(&q, 2);
+    @ <tr><td valign="top" align="right">User:</td>
+    @ <td valign="top">%s(zUser)</td></tr>
+    @ <tr><td valign="top" align="right">Date:</td>
+    @ <td valign="top">%s(zDate)</td></tr>
+    @ <tr><td valign="top" align="right">IP&nbspAddress:</td>
+    @ <td valign="top">%s(zIpAddr)</td></tr>
+  }
+  db_finalize(&q);
+  db_prepare(&q,
+    "SELECT rid, uuid, size FROM blob WHERE rcvid=%d", rcvid
+  );
+  @ <tr><td valign="top" align="right">Artifacts:</td>
+  @ <td valign="top">
+  while( db_step(&q)==SQLITE_ROW ){
+    int rid = db_column_int(&q, 0);
+    const char *zUuid = db_column_text(&q, 1);
+    int size = db_column_int(&q, 2);
+    @ <a href="%s(g.zBaseURL)/info/%s(zUuid)">%s(zUuid)</a>
+    @ (rid: %d(rid), size: %d(size))<br>
+  }
+  @ </td></tr>
+  @ </table>
 }

Modified src/style.c from [3c8c1ba929] to [49507955d9].

@@ -221,11 +221,11 @@
 @ }
 @ if {[hascap j]} {
 @   html "<a href='$baseurl/wiki'>Wiki</a>"
 @ }
 @ if {[hascap s]} {
-@   html "<a href='$baseurl/setup'>Setup</a>"
+@   html "<a href='$baseurl/setup'>Admin</a>"
 @ } elseif {[hascap a]} {
 @   html "<a href='$baseurl/setup_ulist'>Users</a>"
 @ }
 @ if {[info exists login]} {
 @   html "<a href='$baseurl/login'>Logout</a>"

Modified www/branching.wiki from [867e5fd1b3] to [eeebbc4b17].

@@ -80,13 +80,13 @@
 <tr><td align="center">
 <img src="branch03.gif" width=282 height=152><br>
 Figure 3
 </td></tr></table></center>
 
-Check-in 5 is a direct child of check-in 3 because it was created by editing
+Check-in 5 is a child of check-in 3 because it was created by editing
 check-in 3.  But check-in 5 also inherits the changes from check-in 4 by
-virtual of the merge.  So we say that check-in 5 is a <i>merge child</i>
+virtue of the merge.  So we say that check-in 5 is a <i>merge child</i>
 of check-in 4 and that it is a <i>direct child</i> of check-in 3.
 The graph is now back to a single leaf (check-in 5).
 
 We have already seen that if fossil is in autosync mode then Bob would
 have been warned about the potential fork the first time he tried to
@@ -109,13 +109,13 @@
 instead of as a separate manual step.  We will not take sides in that
 debate.  We will simply point out that fossil enables you to do it either way.
 
 <h2>Forking Versus Branching</h2>
 
-Forking and having more than one leaf in the check-in tree is usually
-considered undesirable, and so forks are usually quickly resolved as
-shown in figure 3 above.
+Having more than one leaf in the check-in tree is usually
+considered undesirable, and so forks are usually either avoided entirely,
+as in figure 1, or else quickly resolved as shown in figure 3.
 But sometimes, one does want to have multiple leaves.  For example, a project
 might have one leaf that is the latest version of the project under
 development and another leaf that is the latest version that has been
 tested.
 When multiple leaves are desirable, we call the phenomenon <i>branching</i>
@@ -146,11 +146,11 @@
 shown by the dashed merge arrows between check-ins 6 and 7 and between
 check-ins 9 and 10.
 
 In both figures 2 and 4, check-in 2 has two children.  In figure 2,
 we called this a "fork".  In diagram 4, we call it a "branch".  What is
-the difference?  As far as the internal fossil data structure are
+the difference?  As far as the internal fossil data structures are
 concerned, there is no difference.  The distinction is in the intent.
 In figure 2, the fact that check-in 2 has multiple children is an
 accident that stems from concurrent development.  In figure 4, giving
 check-in 2 multiple children is a deliberate act.  So, to a good
 approximation, we define forking to be by accident and branching to
@@ -172,19 +172,20 @@
 <i>property</i> is a name/value pair.  Internally, fossil implements
 tags as properties with a NULL value.  So, tags and properties really
 are much the same thing, and henceforth we will use the word "tag"
 to mean either a tag or a property.
 
-A tag can be either a one-time tag or an propagating tag or a cancellation.
+A tag can be either a one-time tag or an propagating tag or a cancellation tag.
 A one-time tag only applies to the check-in to which it is attached.  A
 propagating tag applies to the check-in to which it is attached and also
 to all direct descendants of that check-in.  A <i>direct descendant</i>
 is a descendant through direct children.  Tags propagation does not
 cross merges.  Tag propagation also stops as soon
 as it encounters another check-in with the same tag.  A cancellation tag
 is attached to a single check-in in order to either override a one-time
-tag that was placed on that same check-in, or to block tag propagation.
+tag that was previously placed on that same check-in, or to block
+tag propagation from an ancestor.
 
 Every repository is created with a single empty check-in that has two
 propagating tags.  In figure 5, that initial empty check-in is check-in 1.
 The <b>branch</b> tag tells (by its value)
 what branch the check-in is a member of.
@@ -214,11 +215,11 @@
 <b>sym-trunk</b> on check-in 4.  The net effect of all of this is that
 check-ins on the trunk go by the symbolic name of "trunk" and check-ins
 that are on the test branch go by the symbolic name "test".
 
 The <b>bgcolor=blue</b> tag on check-in 4 causes the background color
-of timelines to be blue for check-in 4 and its descendants.
+of timelines to be blue for check-in 4 and its direct descendants.
 
 Figure 5 also shows two one-time tags on check-in 9.  (The diagram does
 not make a graphical distinction between one-time and propagating tags.)
 The <b>sym-release-1.0</b> tag means that check-in 9 can be referred to
 using the more meaningful name "release-1.0".  The <b>closed</b> tag means
@@ -231,10 +232,11 @@
 
 
 <blockquote><dl>
 <dt><b>Branch</b></dt>
 <dd><p>A branch is a set of check-ins that have the same value for their
+branch property.</p></dd>
 <dt><b>Leaf</b></dt>
 <dd><p>A leaf is a check-in that has no children in the same branch.</p></dd>
 <dt><b>Closed Leaf</b></dt>
 <dd><p>A closed leaf is leaf that has the <b>closed</b> tag.  Such leaves
 are intented to never be extended with descendents and hence are omitted

Modified www/newrepo.wiki from [6e108d436b] to [0f60ddea66].

@@ -30,11 +30,11 @@
 </verbatim>
 
 The <tt>ui</tt> command starts up a server (with an optional <tt>-port
 NUMBER</tt> argument) and launches a web browser pointing at the
 fossil server. From there it takes just a few moments to configure the
-repo. Most importantly, go to the Setup menu, then the Users link, and
+repo. Most importantly, go to the Admin menu, then the Users link, and
 set your account name and password, and grant your account all access
 priviledges. (I also like to grant Clone access to the anonymous user,
 but that's personal preference.)
 
 Once you are done, kill the fossil server (with Ctrl-C or equivalent)
@@ -154,11 +154,11 @@
 remote repository. If you have <tt>autosync</tt> on then this sync
 happens automatically, otherwise you will need to use the
 <em>pull</em> command to get remote changes and the <em>push</em>
 command to push your local commits to the remote repository. You must
 of course have authorization to commit changes (access is configured
-via the Setup/Users page mentioned above).
+via the Admin/Users page mentioned above).
 
 You may always use the <em>server</em> or <em>ui</em> commands to
 browse a cloned repository. You can even edit create or wiki entries,
 etc., and they will be pushed to the remote side the next time you
 push data to the the remote.

Modified www/quickstart.wiki from [c0029b88f0] to [6b03b1426c].

@@ -73,11 +73,11 @@
     After the server is running, fossil will then attempt to launch your
     web browser and make it point to this web server.  If your system
     has an unusual configuration, fossil might not be able to figure out
     how to start your web browser.  In that case, start the web browser
     yourself and point it at http://localhost:8080/.  Click on the
-    "Setup" link on the menu bar to start configuring your repository.</p>
+    "Admin" link on the menu bar to start configuring your repository.</p>
 
     <p>By default, fossil does not require a login for HTTP connections
     coming in from the IP loopback address 127.0.0.1.  You can, and perhaps
     should, change this after you create a few users.</p>