コード例 #1
0
ファイル: tkt_.c プロジェクト: LitleWaffle/sampleDirectory
/*
** WEBPAGE: tktedit
** WEBPAGE: debug_tktedit
**
** Edit a ticket.  The ticket is identified by the name CGI parameter.
** /tktedit is the official page.  The /debug_tktedit page does the same
** thing except that it does not save the ticket change record when you
** press submit - it instead prints the ticket change record at the top
** of the page.  The /debug_tktedit page is intended to be used when
** debugging ticket configurations.
*/
void tktedit_page(void){
  const char *zScript;
  int nName;
  const char *zName;
  int nRec;

  login_check_credentials();
  if( !g.perm.ApndTkt && !g.perm.WrTkt ){ login_needed(); return; }
  zName = P("name");
  if( P("cancel") ){
    cgi_redirectf("tktview?name=%T", zName);
  }
  style_header("Edit Ticket");
  if( zName==0 || (nName = strlen(zName))<4 || nName>UUID_SIZE
          || !validate16(zName,nName) ){
    cgi_printf("<span class=\"tktError\">Not a valid ticket id: \\\"%h\\\"</span>\n",(zName));
    style_footer();
    return;
  }
  nRec = db_int(0, "SELECT count(*) FROM ticket WHERE tkt_uuid GLOB '%q*'",
                zName);
  if( nRec==0 ){
    cgi_printf("<span class=\"tktError\">No such ticket: \\\"%h\\\"</span>\n",(zName));
    style_footer();
    return;
  }
  if( nRec>1 ){
    cgi_printf("<span class=\"tktError\">%d tickets begin with:\n"
           "\\\"%h\\\"</span>\n",(nRec),(zName));
    style_footer();
    return;
  }
  if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT<br />\n", -1);
  ticket_init();
  getAllTicketFields();
  initializeVariablesFromCGI();
  initializeVariablesFromDb();
  if( g.zPath[0]=='d' ) showAllFields();
  form_begin(0, "%R/%s", g.zPath);
  cgi_printf("<input type=\"hidden\" name=\"name\" value=\"%s\" />\n",(zName));
  login_insert_csrf_secret();
  zScript = ticket_editpage_code();
  Th_Store("login", g.zLogin ? g.zLogin : "******");
  Th_Store("date", db_text(0, "SELECT datetime('now')"));
  Th_CreateCommand(g.interp, "append_field", appendRemarkCmd, 0, 0);
  Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd, (void*)&zName,0);
  if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT_SCRIPT<br />\n", -1);
  if( Th_Render(zScript)==TH_RETURN && !g.thTrace && zName ){
    cgi_redirect(mprintf("%s/tktview/%s", g.zTop, zName));
    return;
  }
  captcha_generate(0);
  cgi_printf("</form>\n");
  if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT<br />\n", -1);
  style_footer();
}
コード例 #2
0
ファイル: tktsetup_.c プロジェクト: sambassett/Fossil-Repo
/*
** Main sub-menu for configuring the ticketing system.
** WEBPAGE: tktsetup
*/
void tktsetup_page(void){
  login_check_credentials();
  if( !g.perm.Setup ){
    login_needed(0);
    return;
  }

  style_header("Ticket Setup");
  cgi_printf("<table border=\"0\" cellspacing=\"20\">\n");
  setup_menu_entry("Table", "tktsetup_tab",
    "Specify the schema of the  \"ticket\" table in the database.");
  setup_menu_entry("Timeline", "tktsetup_timeline",
    "How to display ticket status in the timeline");
  setup_menu_entry("Common", "tktsetup_com",
    "Common TH1 code run before all ticket processing.");
  setup_menu_entry("Change", "tktsetup_change",
    "The TH1 code run after a ticket is edited or created.");
  setup_menu_entry("New Ticket Page", "tktsetup_newpage",
    "HTML with embedded TH1 code for the \"new ticket\" webpage.");
  setup_menu_entry("View Ticket Page", "tktsetup_viewpage",
    "HTML with embedded TH1 code for the \"view ticket\" webpage.");
  setup_menu_entry("Edit Ticket Page", "tktsetup_editpage",
    "HTML with embedded TH1 code for the \"edit ticket\" webpage.");
  setup_menu_entry("Report List Page", "tktsetup_reportlist",
    "HTML with embedded TH1 code for the \"report list\" webpage.");
  setup_menu_entry("Report Template", "tktsetup_rpttplt",
    "The default ticket report format.");
  setup_menu_entry("Key Template", "tktsetup_keytplt",
    "The default color key for reports.");
  cgi_printf("</table>\n");
  style_footer();
}
コード例 #3
0
ファイル: finfo.c プロジェクト: digsrc/fossil
/*
** WEBPAGE: finfo
** URL: /finfo?name=FILENAME
**
** Show the change history for a single file.
**
** Additional query parameters:
**
**    a=DATE     Only show changes after DATE
**    b=DATE     Only show changes before DATE
**    n=NUM      Show the first NUM changes only
**    brbg       Background color by branch name
**    ubg        Background color by user name
**    ci=UUID    Ancestors of a particular check-in
**    showid     Show RID values for debugging
*/
void finfo_page(void){
  Stmt q;
  const char *zFilename;
  char zPrevDate[20];
  const char *zA;
  const char *zB;
  int n;
  int baseCheckin;
  int fnid;
  Bag ancestor;
  Blob title;
  Blob sql;
  HQuery url;
  GraphContext *pGraph;
  int brBg = P("brbg")!=0;
  int uBg = P("ubg")!=0;
  int fDebug = atoi(PD("debug","0"));
  int fShowId = P("showid")!=0;

  login_check_credentials();
  if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
  style_header("File History");
  login_anonymous_available();
  url_initialize(&url, "finfo");
  if( brBg ) url_add_parameter(&url, "brbg", 0);
  if( uBg ) url_add_parameter(&url, "ubg", 0);
  baseCheckin = name_to_rid_www("ci");
  zPrevDate[0] = 0;
  zFilename = PD("name","");
  fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
  if( fnid==0 ){
    @ No such file: %h(zFilename)
    style_footer();
    return;
  }
コード例 #4
0
ファイル: name_.c プロジェクト: LitleWaffle/sampleDirectory
/*
** WEBPAGE: ambiguous
** URL: /ambiguous?name=UUID&src=WEBPAGE
** 
** The UUID given by the name parameter is ambiguous.  Display a page
** that shows all possible choices and let the user select between them.
*/
void ambiguous_page(void){
  Stmt q;
  const char *zName = P("name");  
  const char *zSrc = P("src");
  char *z;
  
  if( zName==0 || zName[0]==0 || zSrc==0 || zSrc[0]==0 ){
    fossil_redirect_home();
  }
  style_header("Ambiguous Artifact ID");
  cgi_printf("<p>The artifact id <b>%h</b> is ambiguous and might\n"
         "mean any of the following:\n"
         "<ol>\n",(zName));
  z = mprintf("%s", zName);
  canonical16(z, strlen(z));
  db_prepare(&q, "SELECT uuid, rid FROM blob WHERE uuid GLOB '%q*'", z);
  while( db_step(&q)==SQLITE_ROW ){
    const char *zUuid = db_column_text(&q, 0);
    int rid = db_column_int(&q, 1);
    cgi_printf("<li><p><a href=\"%s/%T/%S\">\n"
           "%S</a> -\n",(g.zTop),(zSrc),(zUuid),(zUuid));
    object_description(rid, 0, 0);
    cgi_printf("</p></li>\n");
  }
  cgi_printf("</ol>\n");
  style_footer();
}
コード例 #5
0
ファイル: tag_.c プロジェクト: LitleWaffle/sampleDirectory
/*
** WEBPAGE: /taglist
*/
void taglist_page(void){
  Stmt q;

  login_check_credentials();
  if( !g.perm.Read ){
    login_needed();
  }
  login_anonymous_available();
  style_header("Tags");
  style_submenu_element("Timeline", "Timeline", "tagtimeline");
  cgi_printf("<h2>Non-propagating tags:</h2>\n");
  db_prepare(&q,
    "SELECT substr(tagname,5)"
    "  FROM tag"
    " WHERE EXISTS(SELECT 1 FROM tagxref"
    "               WHERE tagid=tag.tagid"
    "                 AND tagtype=1)"
    " AND tagname GLOB 'sym-*'"
    " ORDER BY tagname"
  );
  cgi_printf("<ul>\n");
  while( db_step(&q)==SQLITE_ROW ){
    const char *zName = db_column_text(&q, 0);
    if( g.perm.Hyperlink ){
      cgi_printf("<li>%z\n"
             "%h</a></li>\n",(xhref("class='taglink'","%R/timeline?t=%T",zName)),(zName));
    }else{
      cgi_printf("<li><span class=\"tagDsp\">%h</span></li>\n",(zName));
    }
  }
  cgi_printf("</ul>\n");
  db_finalize(&q);
  style_footer();
}
コード例 #6
0
ファイル: tag_.c プロジェクト: LitleWaffle/sampleDirectory
/*
** WEBPAGE: /tagtimeline
*/
void tagtimeline_page(void){
  Stmt q;

  login_check_credentials();
  if( !g.perm.Read ){ login_needed(); return; }

  style_header("Tagged Check-ins");
  style_submenu_element("List", "List", "taglist");
  login_anonymous_available();
  cgi_printf("<h2>Check-ins with non-propagating tags:</h2>\n");
  db_prepare(&q,
    "%s AND blob.rid IN (SELECT rid FROM tagxref"
    "                     WHERE tagtype=1 AND srcid>0"
    "                       AND tagid IN (SELECT tagid FROM tag "
    "                                      WHERE tagname GLOB 'sym-*'))"
    " ORDER BY event.mtime DESC",
    timeline_query_for_www()
  );
  www_print_timeline(&q, 0, 0, 0, 0);
  db_finalize(&q);
  cgi_printf("<br />\n"
         "<script  type=\"text/JavaScript\">\n"
         "function xin(id){\n"
         "}\n"
         "function xout(id){\n"
         "}\n"
         "</script>\n");
  style_footer();
}
コード例 #7
0
ファイル: tktsetup_.c プロジェクト: sambassett/Fossil-Repo
/*
** Common implementation for the ticket setup editor pages.
*/
static void tktsetup_generic(
  const char *zTitle,           /* Page title */
  const char *zDbField,         /* Configuration field being edited */
  const char *zDfltValue,       /* Default text value */
  const char *zDesc,            /* Description of this field */
  char *(*xText)(const char*),  /* Validity test or NULL */
  void (*xRebuild)(void),       /* Run after successful update */
  int height                    /* Height of the edit box */
){
  const char *z;
  int isSubmit;

  login_check_credentials();
  if( !g.perm.Setup ){
    login_needed(0);
    return;
  }
  if( PB("setup") ){
    cgi_redirect("tktsetup");
  }
  isSubmit = P("submit")!=0;
  z = P("x");
  if( z==0 ){
    z = db_get(zDbField, (char*)zDfltValue);
  }
  style_header("Edit %s", zTitle);
  if( P("clear")!=0 ){
    login_verify_csrf_secret();
    db_unset(zDbField, 0);
    if( xRebuild ) xRebuild();
    cgi_redirect("tktsetup");
  }else if( isSubmit ){
    char *zErr = 0;
    login_verify_csrf_secret();
    if( xText && (zErr = xText(z))!=0 ){
      cgi_printf("<p class=\"tktsetupError\">ERROR: %h</p>\n",(zErr));
    }else{
      db_set(zDbField, z, 0);
      if( xRebuild ) xRebuild();
      cgi_redirect("tktsetup");
    }
  }
  cgi_printf("<form action=\"%s/%s\" method=\"post\"><div>\n",(g.zTop),(g.zPath));
  login_insert_csrf_secret();
  cgi_printf("<p>%s</p>\n"
         "<textarea name=\"x\" rows=\"%d\" cols=\"80\">%h</textarea>\n"
         "<blockquote><p>\n"
         "<input type=\"submit\" name=\"submit\" value=\"Apply Changes\" />\n"
         "<input type=\"submit\" name=\"clear\" value=\"Revert To Default\" />\n"
         "<input type=\"submit\" name=\"setup\" value=\"Cancel\" />\n"
         "</p></blockquote>\n"
         "</div></form>\n"
         "<hr />\n"
         "<h2>Default %s</h2>\n"
         "<blockquote><pre>\n"
         "%h\n"
         "</pre></blockquote>\n",(zDesc),(height),(z),(zTitle),(zDfltValue));
  style_footer();
}
コード例 #8
0
ファイル: wiki.c プロジェクト: kassanmoor/fossildocker
/*
** Check a wiki name.  If it is not well-formed, then issue an error
** and return true.  If it is well-formed, return false.
*/
static int check_name(const char *z){
  if( !wiki_name_is_wellformed((const unsigned char *)z) ){
    style_header("Wiki Page Name Error");
    @ The wiki name "<span class="wikiError">%h(z)</span>" is not well-formed.
    @ Rules for wiki page names:
    well_formed_wiki_name_rules();
    style_footer();
    return 1;
  }
コード例 #9
0
ファイル: tkt_.c プロジェクト: LitleWaffle/sampleDirectory
/*
** WEBPAGE: tktview
** URL:  tktview?name=UUID
**
** View a ticket.
*/
void tktview_page(void){
  const char *zScript;
  char *zFullName;
  const char *zUuid = PD("name","");

  login_check_credentials();
  if( !g.perm.RdTkt ){ login_needed(); return; }
  if( g.perm.WrTkt || g.perm.ApndTkt ){
    style_submenu_element("Edit", "Edit The Ticket", "%s/tktedit?name=%T",
        g.zTop, PD("name",""));
  }
  if( g.perm.Hyperlink ){
    style_submenu_element("History", "History Of This Ticket", 
        "%s/tkthistory/%T", g.zTop, zUuid);
    style_submenu_element("Timeline", "Timeline Of This Ticket", 
        "%s/tkttimeline/%T", g.zTop, zUuid);
    style_submenu_element("Check-ins", "Check-ins Of This Ticket", 
        "%s/tkttimeline/%T?y=ci", g.zTop, zUuid);
  }
  if( g.perm.NewTkt ){
    style_submenu_element("New Ticket", "Create a new ticket",
        "%s/tktnew", g.zTop);
  }
  if( g.perm.ApndTkt && g.perm.Attach ){
    style_submenu_element("Attach", "Add An Attachment",
        "%s/attachadd?tkt=%T&from=%s/tktview/%t",
        g.zTop, zUuid, g.zTop, zUuid);
  }
  if( P("plaintext") ){
    style_submenu_element("Formatted", "Formatted", "%R/tktview/%S", zUuid);
  }else{
    style_submenu_element("Plaintext", "Plaintext",
                          "%R/tktview/%S?plaintext", zUuid);
  }
  style_header("View Ticket");
  if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW<br />\n", -1);
  ticket_init();
  initializeVariablesFromCGI();
  getAllTicketFields();
  initializeVariablesFromDb();
  zScript = ticket_viewpage_code();
  if( P("showfields")!=0 ) showAllFields();
  if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW_SCRIPT<br />\n", -1);
  Th_Render(zScript);
  if( g.thTrace ) Th_Trace("END_TKTVIEW<br />\n", -1);

  zFullName = db_text(0, 
       "SELECT tkt_uuid FROM ticket"
       " WHERE tkt_uuid GLOB '%q*'", zUuid);
  if( zFullName ){
    attachment_list(zFullName, "<hr /><h2>Attachments:</h2><ul>");
  }
 
  style_footer();
}
コード例 #10
0
ファイル: tktsetup_.c プロジェクト: sambassett/Fossil-Repo
/*
** WEBPAGE: tktsetup_timeline
*/
void tktsetup_timeline_page(void){
  login_check_credentials();
  if( !g.perm.Setup ){
    login_needed(0);
    return;
  }

  if( P("setup") ){
    cgi_redirect("tktsetup");
  }
  style_header("Ticket Display On Timelines");
  db_begin_transaction();
  cgi_printf("<form action=\"%s/tktsetup_timeline\" method=\"post\"><div>\n",(g.zTop));
  login_insert_csrf_secret();

  cgi_printf("<hr />\n");
  entry_attribute("Ticket Title", 40, "ticket-title-expr", "t",
                  "title", 0);
  cgi_printf("<p>An SQL expression in a query against the TICKET table that will\n"
         "return the title of the ticket for display purposes.</p>\n");

  cgi_printf("<hr />\n");
  entry_attribute("Ticket Status", 40, "ticket-status-column", "s",
                  "status", 0);
  cgi_printf("<p>The name of the column in the TICKET table that contains the ticket\n"
         "status in human-readable form.  Case sensitive.</p>\n");

  cgi_printf("<hr />\n");
  entry_attribute("Ticket Closed", 40, "ticket-closed-expr", "c",
                  "status='Closed'", 0);
  cgi_printf("<p>An SQL expression that evaluates to true in a TICKET table query if\n"
         "the ticket is closed.</p>\n");

  cgi_printf("<hr />\n"
         "<p>\n"
         "<input type=\"submit\"  name=\"submit\" value=\"Apply Changes\" />\n"
         "<input type=\"submit\" name=\"setup\" value=\"Cancel\" />\n"
         "</p>\n"
         "</div></form>\n");
  db_end_transaction(0);
  style_footer();

}
コード例 #11
0
ファイル: tkt_.c プロジェクト: LitleWaffle/sampleDirectory
/*
** WEBPAGE: tktnew
** WEBPAGE: debug_tktnew
**
** Enter a new ticket.  The tktnew_template script in the ticket
** configuration is used.  The /tktnew page is the official ticket
** entry page.  The /debug_tktnew page is used for debugging the
** tktnew_template in the ticket configuration.  /debug_tktnew works
** just like /tktnew except that it does not really save the new ticket
** when you press submit - it just prints the ticket artifact at the
** top of the screen.
*/
void tktnew_page(void){
  const char *zScript;
  char *zNewUuid = 0;

  login_check_credentials();
  if( !g.perm.NewTkt ){ login_needed(); return; }
  if( P("cancel") ){
    cgi_redirect("home");
  }
  style_header("New Ticket");
  if( g.thTrace ) Th_Trace("BEGIN_TKTNEW<br />\n", -1);
  ticket_init();
  initializeVariablesFromCGI();
  getAllTicketFields();
  initializeVariablesFromDb();
  if( g.zPath[0]=='d' ) showAllFields();
  form_begin(0, "%R/%s", g.zPath);
  login_insert_csrf_secret();
  if( P("date_override") && g.perm.Setup ){
    cgi_printf("<input type=\"hidden\" name=\"date_override\" value=\"%h\">\n",(P("date_override")));
  }
  zScript = ticket_newpage_code();
  Th_Store("login", g.zLogin ? g.zLogin : "******");
  Th_Store("date", db_text(0, "SELECT datetime('now')"));
  Th_CreateCommand(g.interp, "submit_ticket", submitTicketCmd,
                   (void*)&zNewUuid, 0);
  if( g.thTrace ) Th_Trace("BEGIN_TKTNEW_SCRIPT<br />\n", -1);
  if( Th_Render(zScript)==TH_RETURN && !g.thTrace && zNewUuid ){
    cgi_redirect(mprintf("%s/tktview/%s", g.zTop, zNewUuid));
    return;
  }
  captcha_generate(0);
  cgi_printf("</form>\n");
  if( g.thTrace ) Th_Trace("END_TKTVIEW<br />\n", -1);
  style_footer();
}
コード例 #12
0
ファイル: xfersetup_.c プロジェクト: sambassett/Fossil-Repo
/*
** Main sub-menu for configuring the transfer system.
** WEBPAGE: xfersetup
*/
void xfersetup_page(void){
  login_check_credentials();
  if( !g.perm.Setup ){
    login_needed(0);
    return;
  }

  style_header("Transfer Setup");

  cgi_printf("<table border=\"0\" cellspacing=\"20\">\n");
  setup_menu_entry("Common", "xfersetup_com",
    "Common TH1 code run before all transfer request processing.");
  setup_menu_entry("Push", "xfersetup_push",
    "Specific TH1 code to run after \"push\" transfer requests.");
  setup_menu_entry("Commit", "xfersetup_commit",
    "Specific TH1 code to run after processing a commit.");
  setup_menu_entry("Ticket", "xfersetup_ticket",
    "Specific TH1 code to run after processing a ticket change.");
  cgi_printf("</table>\n");

  url_parse(0, 0);
  if( g.url.protocol ){
    unsigned syncFlags;
    const char *zButton;
    char *zWarning;

    if( db_get_boolean("dont-push", 0) ){
      syncFlags = SYNC_PULL;
      zButton = "Pull";
      zWarning = 0;
    }else{
      syncFlags = SYNC_PUSH | SYNC_PULL;
      zButton = "Synchronize";
      zWarning = mprintf("WARNING: Pushing to \"%s\" is enabled.",
                         g.url.canonical);
    }
    if( P("sync") ){
      user_select();
      url_enable_proxy(0);
      client_sync(syncFlags, 0, 0);
    }
    cgi_printf("<p>Press the %h button below to synchronize with the\n"
           "\"%h\" repository now.  This may be useful when\n"
           "testing the various transfer scripts.</p>\n"
           "<p>You can use the \"http -async\" command in your scripts, but\n"
           "make sure the \"th1-uri-regexp\" setting is set first.</p>\n",(zButton),(g.url.canonical));
    if( zWarning ){
      cgi_printf("\n"
             "<big><b>%h</b></big>\n",(zWarning));
      free(zWarning);
    }
    cgi_printf("\n"
           "<blockquote>\n"
           "<form method=\"post\" action=\"%s/%s\"><div>\n",(g.zTop),(g.zPath));
    login_insert_csrf_secret();
    cgi_printf("<input type=\"submit\" name=\"sync\" value=\"%h\" />\n"
           "</div></form>\n"
           "</blockquote>\n"
           "\n",(zButton));
  }

  style_footer();
}
コード例 #13
0
/*
** WEBPAGE:  leaves
**
** Find leaves of all branches.
*/
void leaves_page(void){
  Blob sql;
  Stmt q;
  int showAll = P("all")!=0;
  int showClosed = P("closed")!=0;

  login_check_credentials();
  if( !g.perm.Read ){ login_needed(); return; }

  if( !showAll ){
    style_submenu_element("All", "All", "leaves?all");
  }
  if( !showClosed ){
    style_submenu_element("Closed", "Closed", "leaves?closed");
  }
  if( showClosed || showAll ){
    style_submenu_element("Open", "Open", "leaves");
  }
  style_header("Leaves");
  login_anonymous_available();
  style_sidebox_begin("Nomenclature:", "33%");
  cgi_printf("<ol>\n"
         "<li> A <div class=\"sideboxDescribed\">leaf</div>\n"
         "is a check-in with no descendants in the same branch.</li>\n"
         "<li> An <div class=\"sideboxDescribed\">open leaf</div>\n"
         "is a leaf that does not have a \"closed\" tag\n"
         "and is thus assumed to still be in use.</li>\n"
         "<li> A <div class=\"sideboxDescribed\">closed leaf</div>\n"
         "has a \"closed\" tag and is thus assumed to\n"
         "be historical and no longer in active use.</li>\n"
         "</ol>\n");
  style_sidebox_end();

  if( showAll ){
    cgi_printf("<h1>All leaves, both open and closed:</h1>\n");
  }else if( showClosed ){
    cgi_printf("<h1>Closed leaves:</h1>\n");
  }else{
    cgi_printf("<h1>Open leaves:</h1>\n");
  }
  blob_zero(&sql);
  blob_append(&sql, timeline_query_for_www(), -1);
  blob_appendf(&sql, " AND blob.rid IN leaf");
  if( showClosed ){
    blob_appendf(&sql," AND %z", leaf_is_closed_sql("blob.rid"));
  }else if( !showAll ){
    blob_appendf(&sql," AND NOT %z", leaf_is_closed_sql("blob.rid"));
  }
  db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_str(&sql));
  blob_reset(&sql);
  www_print_timeline(&q, TIMELINE_LEAFONLY, 0, 0, 0);
  db_finalize(&q);
  cgi_printf("<br />\n"
         "<script  type=\"text/JavaScript\">\n"
         "function xin(id){\n"
         "}\n"
         "function xout(id){\n"
         "}\n"
         "</script>\n");
  style_footer();
}
コード例 #14
0
/*
** WEBPAGE: doc
** URL: /doc?name=BASELINE/PATH
** URL: /doc/BASELINE/PATH
**
** BASELINE can be either a baseline uuid prefix or magic words "tip"
** to mean the most recently checked in baseline or "ckout" to mean the
** content of the local checkout, if any.  PATH is the relative pathname
** of some file.  This method returns the file content.
**
** If PATH matches the patterns *.wiki or *.txt then formatting content
** is added before returning the file.  For all other names, the content
** is returned straight without any interpretation or processing.
*/
void doc_page(void){
  const char *zName;                /* Argument to the /doc page */
  const char *zMime;                /* Document MIME type */
  int vid = 0;                      /* Artifact of baseline */
  int rid = 0;                      /* Artifact of file */
  int i;                            /* Loop counter */
  Blob filebody;                    /* Content of the documentation file */
  char zBaseline[UUID_SIZE+1];      /* Baseline UUID */

  login_check_credentials();
  if( !g.perm.Read ){ login_needed(); return; }
  zName = PD("name", "tip/index.wiki");
  for(i=0; zName[i] && zName[i]!='/'; i++){}
  if( zName[i]==0 || i>UUID_SIZE ){
    zName = "index.html";
    goto doc_not_found;
  }
  memcpy(zBaseline, zName, i);
  zBaseline[i] = 0;
  zName += i;
  while( zName[0]=='/' ){ zName++; }
  if( !file_is_simple_pathname(zName) ){
    int n = strlen(zName);
    if( n>0 && zName[n-1]=='/' ){
      zName = mprintf("%sindex.html", zName);
      if( !file_is_simple_pathname(zName) ){
        goto doc_not_found;
      }
    }else{
      goto doc_not_found;
    }
  }
  if( fossil_strcmp(zBaseline,"ckout")==0 && db_open_local()==0 ){
    sqlite3_snprintf(sizeof(zBaseline), zBaseline, "tip");
  }
  if( fossil_strcmp(zBaseline,"ckout")==0 ){
    /* Read from the local checkout */
    char *zFullpath;
    db_must_be_within_tree();
    zFullpath = mprintf("%s/%s", g.zLocalRoot, zName);
    if( !file_isfile(zFullpath) ){
      goto doc_not_found;
    }
    if( blob_read_from_file(&filebody, zFullpath)<0 ){
      goto doc_not_found;
    }
  }else{
    db_begin_transaction();
    if( fossil_strcmp(zBaseline,"tip")==0 ){
      vid = db_int(0, "SELECT objid FROM event WHERE type='ci'"
                      " ORDER BY mtime DESC LIMIT 1");
    }else{
      vid = name_to_typed_rid(zBaseline, "ci");
    }

    /* Create the baseline cache if it does not already exist */
    db_multi_exec(
      "CREATE TABLE IF NOT EXISTS vcache(\n"
      "  vid INTEGER,         -- baseline ID\n"
      "  fname TEXT,          -- filename\n"
      "  rid INTEGER,         -- artifact ID\n"
      "  UNIQUE(vid,fname,rid)\n"
      ")"
    );



    /* Check to see if the documentation file artifact ID is contained
    ** in the baseline cache */
    rid = db_int(0, "SELECT rid FROM vcache"
                    " WHERE vid=%d AND fname=%Q", vid, zName);
    if( rid==0 && db_exists("SELECT 1 FROM vcache WHERE vid=%d", vid) ){
      goto doc_not_found;
    }

    if( rid==0 ){
      Stmt s;
      Manifest *pM;
      ManifestFile *pFile;

      /* Add the vid baseline to the cache */
      if( db_int(0, "SELECT count(*) FROM vcache")>10000 ){
        db_multi_exec("DELETE FROM vcache");
      }
      pM = manifest_get(vid, CFTYPE_MANIFEST);
      if( pM==0 ){
        goto doc_not_found;
      }
      db_prepare(&s,
        "INSERT INTO vcache(vid,fname,rid)"
        " SELECT %d, :fname, rid FROM blob"
        "  WHERE uuid=:uuid",
        vid
      );
      manifest_file_rewind(pM);
      while( (pFile = manifest_file_next(pM,0))!=0 ){
        db_bind_text(&s, ":fname", pFile->zName);
        db_bind_text(&s, ":uuid", pFile->zUuid);
        db_step(&s);
        db_reset(&s);
      }
      db_finalize(&s);
      manifest_destroy(pM);

      /* Try again to find the file */
      rid = db_int(0, "SELECT rid FROM vcache"
                      " WHERE vid=%d AND fname=%Q", vid, zName);
    }
    if( rid==0 ){
      goto doc_not_found;
    }

    /* Get the file content */
    if( content_get(rid, &filebody)==0 ){
      goto doc_not_found;
    }
    db_end_transaction(0);
  }

  /* The file is now contained in the filebody blob.  Deliver the
  ** file to the user 
  */
  zMime = P("mimetype");
  if( zMime==0 ){
    zMime = mimetype_from_name(zName);
  }
  Th_Store("doc_name", zName);
  Th_Store("doc_version", db_text(0, "SELECT '[' || substr(uuid,1,10) || ']'"
                                     "  FROM blob WHERE rid=%d", vid));
  Th_Store("doc_date", db_text(0, "SELECT datetime(mtime) FROM event"
                                  " WHERE objid=%d AND type='ci'", vid));
  if( fossil_strcmp(zMime, "application/x-fossil-wiki")==0 ){
    Blob title, tail;
    if( wiki_find_title(&filebody, &title, &tail) ){
      style_header(blob_str(&title));
      wiki_convert(&tail, 0, 0);
    }else{
      style_header("Documentation");
      wiki_convert(&filebody, 0, 0);
    }
    style_footer();
  }else if( fossil_strcmp(zMime, "text/plain")==0 ){
    style_header("Documentation");
    @ <blockquote><pre>
コード例 #15
0
ファイル: tkt_.c プロジェクト: LitleWaffle/sampleDirectory
/*
** WEBPAGE: tkttimeline
** URL: /tkttimeline?name=TICKETUUID&y=TYPE
**
** Show the change history for a single ticket in timeline format.
*/
void tkttimeline_page(void){
  Stmt q;
  char *zTitle;
  char *zSQL;
  const char *zUuid;
  char *zFullUuid;
  int tagid;
  char zGlobPattern[50];
  const char *zType;

  login_check_credentials();
  if( !g.perm.Hyperlink || !g.perm.RdTkt ){ login_needed(); return; }
  zUuid = PD("name","");
  zType = PD("y","a");
  if( zType[0]!='c' ){
    style_submenu_element("Check-ins", "Check-ins",
       "%s/tkttimeline?name=%T&y=ci", g.zTop, zUuid);
  }else{
    style_submenu_element("Timeline", "Timeline",
       "%s/tkttimeline?name=%T", g.zTop, zUuid);
  }
  style_submenu_element("History", "History",
    "%s/tkthistory/%s", g.zTop, zUuid);
  style_submenu_element("Status", "Status",
    "%s/info/%s", g.zTop, zUuid);
  if( zType[0]=='c' ){
    zTitle = mprintf("Check-Ins Associated With Ticket %h", zUuid);
  }else{
    zTitle = mprintf("Timeline Of Ticket %h", zUuid);
  }
  style_header(zTitle);
  free(zTitle);

  sqlite3_snprintf(6, zGlobPattern, "%s", zUuid);
  canonical16(zGlobPattern, strlen(zGlobPattern));
  tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid);
  if( tagid==0 ){
    cgi_printf("No such ticket: %h\n",(zUuid));
    style_footer();
    return;
  }
  zFullUuid = db_text(0, "SELECT substr(tagname, 5) FROM tag WHERE tagid=%d",
                         tagid);
  if( zType[0]=='c' ){
    zSQL = mprintf(
         "%s AND event.objid IN "
         "   (SELECT srcid FROM backlink WHERE target GLOB '%.4s*' "
                                         "AND '%s' GLOB (target||'*')) "
         "ORDER BY mtime DESC",
         timeline_query_for_www(), zFullUuid, zFullUuid
    );
  }else{
    zSQL = mprintf(
         "%s AND event.objid IN "
         "  (SELECT rid FROM tagxref WHERE tagid=%d"
         "   UNION SELECT srcid FROM backlink"
                  " WHERE target GLOB '%.4s*'"
                  "   AND '%s' GLOB (target||'*')"
         "   UNION SELECT attachid FROM attachment"
                  " WHERE target=%Q) "
         "ORDER BY mtime DESC",
         timeline_query_for_www(), tagid, zFullUuid, zFullUuid, zFullUuid
    );
  }
  db_prepare(&q, zSQL);
  free(zSQL);
  www_print_timeline(&q, TIMELINE_ARTID|TIMELINE_DISJOINT|TIMELINE_GRAPH,
                     0, 0, 0);
  db_finalize(&q);
  style_footer();
}
コード例 #16
0
ファイル: tkt_.c プロジェクト: LitleWaffle/sampleDirectory
/*
** WEBPAGE: tkthistory
** URL: /tkthistory?name=TICKETUUID
**
** Show the complete change history for a single ticket
*/
void tkthistory_page(void){
  Stmt q;
  char *zTitle;
  const char *zUuid;
  int tagid;
  int nChng = 0;

  login_check_credentials();
  if( !g.perm.Hyperlink || !g.perm.RdTkt ){ login_needed(); return; }
  zUuid = PD("name","");
  zTitle = mprintf("History Of Ticket %h", zUuid);
  style_submenu_element("Status", "Status",
    "%s/info/%s", g.zTop, zUuid);
  style_submenu_element("Check-ins", "Check-ins",
    "%s/tkttimeline?name=%s&y=ci", g.zTop, zUuid);
  style_submenu_element("Timeline", "Timeline",
    "%s/tkttimeline?name=%s", g.zTop, zUuid);
  if( P("plaintext")!=0 ){
    style_submenu_element("Formatted", "Formatted",
                          "%R/tkthistory/%S", zUuid);
  }else{
    style_submenu_element("Plaintext", "Plaintext",
                          "%R/tkthistory/%S?plaintext", zUuid);
  }
  style_header(zTitle);
  free(zTitle);

  tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname GLOB 'tkt-%q*'",zUuid);
  if( tagid==0 ){
    cgi_printf("No such ticket: %h\n",(zUuid));
    style_footer();
    return;
  }
  db_prepare(&q,
    "SELECT datetime(mtime%s), objid, uuid, NULL, NULL, NULL"
    "  FROM event, blob"
    " WHERE objid IN (SELECT rid FROM tagxref WHERE tagid=%d)"
    "   AND blob.rid=event.objid"
    " UNION "
    "SELECT datetime(mtime%s), attachid, uuid, src, filename, user"
    "  FROM attachment, blob"
    " WHERE target=(SELECT substr(tagname,5) FROM tag WHERE tagid=%d)"
    "   AND blob.rid=attachid"
    " ORDER BY 1",
    timeline_utc(), tagid, timeline_utc(), tagid
  );
  while( db_step(&q)==SQLITE_ROW ){
    Manifest *pTicket;
    char zShort[12];
    const char *zDate = db_column_text(&q, 0);
    int rid = db_column_int(&q, 1);
    const char *zChngUuid = db_column_text(&q, 2);
    const char *zFile = db_column_text(&q, 4);
    memcpy(zShort, zChngUuid, 10);
    zShort[10] = 0;
    if( nChng==0 ){
      cgi_printf("<ol>\n");
    }
    nChng++;
    if( zFile!=0 ){
      const char *zSrc = db_column_text(&q, 3);
      const char *zUser = db_column_text(&q, 5);
      if( zSrc==0 || zSrc[0]==0 ){
        cgi_printf("\n"
               "<li><p>Delete attachment \"%h\"\n",(zFile));
      }else{
        cgi_printf("\n"
               "<li><p>Add attachment\n"
               "\"%z%s</a>\"\n",(href("%R/artifact/%S",zSrc)),(zFile));
      }
      cgi_printf("[%z%s</a>]\n"
             "(rid %d) by\n",(href("%R/artifact/%T",zChngUuid)),(zShort),(rid));
      hyperlink_to_user(zUser,zDate," on");
      hyperlink_to_date(zDate, ".</p>");
    }else{
      pTicket = manifest_get(rid, CFTYPE_TICKET, 0);
      if( pTicket ){
        cgi_printf("\n"
               "<li><p>Ticket change\n"
               "[%z%s</a>]\n"
               "(rid %d) by\n",(href("%R/artifact/%T",zChngUuid)),(zShort),(rid));
        hyperlink_to_user(pTicket->zUser,zDate," on");
        hyperlink_to_date(zDate, ":");
        cgi_printf("</p>\n");
        ticket_output_change_artifact(pTicket, "a");
      }
      manifest_destroy(pTicket);
    }
  }
  db_finalize(&q);
  if( nChng ){
    cgi_printf("</ol>\n");
  }
  style_footer();
}
コード例 #17
0
ファイル: sitemap_.c プロジェクト: sambassett/Fossil-Repo
/*
** WEBPAGE:  sitemap
**
** Show an incomplete list of web pages offered by the Fossil web engine.
*/
void sitemap_page(void){
  login_check_credentials();
  style_header("Site Map");
  style_adunit_config(ADUNIT_RIGHT_OK);
  cgi_printf("<p>\n"
         "The following links are just a few of the many web-pages available for\n"
         "this Fossil repository:\n"
         "</p>\n"
         "\n"
         "<ul>\n"
         "<li>%zHome Page</a>\n"
         "  <ul>\n"
         "  <li>%zSearch Project Documentation</a></li>\n"
         "  </ul></li>\n"
         "<li>%zFile Browser</a></li>\n"
         "  <ul>\n"
         "  <li>%zTree-view,\n"
         "       Trunk Check-in</a></li>\n"
         "  <li>%zFlat-view</a></li>\n"
         "  <li>%zFile ages for Trunk</a></li>\n"
         "</ul>\n"
         "<li>%zProject Timeline</a></li>\n"
         "<ul>\n"
         "  <li>%zFirst 10 \n"
         "       check-ins</a></li>\n"
         "  <li>%zAll check-ins with file name\n"
         "       changes</a></li>\n"
         "  <li>%zActivity Reports</a></li>\n"
         "</ul>\n"
         "<li>%zBranches</a></li>\n"
         "<ul>\n"
         "  <li>%zLeaf Check-ins</a></li>\n"
         "  <li>%zList of Tags</a></li>\n"
         "</ul>\n"
         "</li>\n"
         "<li>%zWiki</a>\n"
         "  <ul>\n"
         "    <li>%zWiki Search</a></li>\n"
         "    <li>%zList of Wiki Pages</a></li>\n"
         "    <li>%zRecent activity</a></li>\n"
         "    <li>%zWiki Formatting Rules</a></li>\n"
         "    <li>%zMarkdown Formatting Rules</a></li>\n"
         "    <li>%zSandbox</a></li>\n"
         "    <li>%zList of Attachments</a></li>\n"
         "  </ul>\n"
         "</li>\n"
         "<li>%zTickets</a>\n"
         "  <ul>\n"
         "  <li>%zTicket Search</a></li>\n"
         "  <li>%zRecent activity</a></li>\n"
         "  <li>%zList of Attachments</a></li>\n"
         "  </ul>\n"
         "</li>\n"
         "<li>%zFull-Text Search</a></li>\n"
         "<li>%zLogin/Logout/Change Password</a></li>\n"
         "<li>%zRepository Status</a>\n"
         "  <ul>\n"
         "  <li>%zCollisions on SHA1 hash\n"
         "      prefixes</a></li>\n"
         "  <li>%zList of URLs used to access\n"
         "      this repository</a></li>\n"
         "  <li>%zList of Artifacts</a></li>\n"
         "  </ul></li>\n"
         "<li>On-line Documentation\n"
         "  <ul>\n"
         "  <li>%zList of All Commands and Web Pages</a></li>\n"
         "  <li>%zAll \"help\" text on a single page</a></li>\n"
         "  <li>%zFilename suffix to mimetype map</a></li>\n"
         "  </ul></li>\n"
         "<li>%zAdministration Pages</a>\n"
         "  <ul>\n"
         "  <li>%zPending Moderation Requests</a></li>\n"
         "  <li>%zAdmin log</a></li>\n"
         "  <li>%zStatus of the web-page cache</a></li>\n"
         "  </ul></li>\n"
         "<li>Test Pages\n"
         "  <ul>\n"
         "  <li>%zCGI Environment Test</a></li>\n"
         "  <li>%zList of \"Timewarp\" Check-ins</a></li>\n"
         "  <li>%zList of file renames</a></li>\n"
         "  <li>%zPage to experiment with the automatic\n"
         "      colors assigned to branch names</a>\n"
         "  </ul></li>\n"
         "</ul></li>\n",(href("%R/home")),(href("%R/docsrc")),(href("%R/tree")),(href("%R/tree?type=tree&ci=trunk")),(href("%R/tree?type=flat")),(href("%R/fileage?name=trunk")),(href("%R/timeline?n=200")),(href("%R/timeline?a=1970-01-01&y=ci&n=10")),(href("%R/timeline?n=all&namechng")),(href("%R/reports")),(href("%R/brlist")),(href("%R/leaves")),(href("%R/taglist")),(href("%R/wikihelp")),(href("%R/wikisrch")),(href("%R/wcontent")),(href("%R/timeline?y=w")),(href("%R/wiki_rules")),(href("%R/md_rules")),(href("%R/wiki?name=Sandbox")),(href("%R/attachlist")),(href("%R/reportlist")),(href("%R/tktsrch")),(href("%R/timeline?y=t")),(href("%R/attachlist")),(href("%R/search")),(href("%R/login")),(href("%R/stat")),(href("%R/hash-collisions")),(href("%R/urllist")),(href("%R/bloblist")),(href("%R/help")),(href("%R/test-all-help")),(href("%R/mimetype_list")),(href("%R/setup")),(href("%R/modreq")),(href("%R/admin_log")),(href("%R/cachestat")),(href("%R/test_env")),(href("%R/test_timewarps")),(href("%R/test-rename-list")),(href("%R/hash-color-test")));
  style_footer();
}