Fossil

Diff
Login

Diff

Differences From Artifact [c8f8250a5d]:

To Artifact [dfdaaff44e]:


520
521
522
523
524
525
526

527
528

529
530
531
532
533
534
535
520
521
522
523
524
525
526
527
528

529
530
531
532
533
534
535
536







+

-
+







      base = i+5;
    }
  }
  blob_append(cgi_output_blob(), &z[base], i-base);
}

/*
** WEBPAGE: uv
** WEBPAGE: doc
** URL: /doc?name=CHECKIN/FILE
** URL: /uv/FILE
** URL: /doc/CHECKIN/FILE
**
** CHECKIN can be either tag or SHA1 hash or timestamp identifying a
** particular check, or the name of a branch (meaning the most recent
** check-in on that branch) or one of various magic words:
**
**     "tip"      means the most recent check-in
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


612
613
614
615
616
617
618
619
620
621
622
623










624

625
626
627
628
629
630
631
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
612
613
614

615
616
617
618
619
620
621

622
623
624
625
626
627
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







+
+










+



+
+
+
-
-
-
-
-
+
+
+
+
+
+






-
+



+
+
+
-
+
+












+
+
+
+
+
+
+
+
+
+
-
+







  char *zCheckin = "tip";           /* The check-in holding the document */
  int vid = 0;                      /* Artifact of check-in */
  int rid = 0;                      /* Artifact of file */
  int i;                            /* Loop counter */
  Blob filebody;                    /* Content of the documentation file */
  Blob title;                       /* Document title */
  int nMiss = (-1);                 /* Failed attempts to find the document */
  int isUV = g.zPath[0]=='u';       /* True for /uv.  False for /doc */
  const char *zDfltTitle;
  static const char *const azSuffix[] = {
     "index.html", "index.wiki", "index.md"
#ifdef FOSSIL_ENABLE_TH1_DOCS
      , "index.th1"
#endif
  };

  login_check_credentials();
  if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
  blob_init(&title, 0, 0);
  zDfltTitle = isUV ? "" : "Documentation";
  db_begin_transaction();
  while( rid==0 && (++nMiss)<=ArraySize(azSuffix) ){
    zName = P("name");
    if( isUV ){
      i = 0;
    }else{
    if( zName==0 || zName[0]==0 ) zName = "tip/index.wiki";
    for(i=0; zName[i] && zName[i]!='/'; i++){}
    zCheckin = mprintf("%.*s", i, zName);
    if( fossil_strcmp(zCheckin,"ckout")==0 && g.localOpen==0 ){
      zCheckin = "tip";
      if( zName==0 || zName[0]==0 ) zName = "tip/index.wiki";
      for(i=0; zName[i] && zName[i]!='/'; i++){}
      zCheckin = mprintf("%.*s", i, zName);
      if( fossil_strcmp(zCheckin,"ckout")==0 && g.localOpen==0 ){
        zCheckin = "tip";
      }
    }
    if( nMiss==ArraySize(azSuffix) ){
      zName = "404.md";
    }else if( zName[i]==0 ){
      assert( nMiss>=0 && nMiss<ArraySize(azSuffix) );
      zName = azSuffix[nMiss];
    }else{
    }else if( !isUV ){
      zName += i;
    }
    while( zName[0]=='/' ){ zName++; }
    if( isUV ){
      g.zPath = mprintf("%s/%s", g.zPath, zName);
    }else{
    g.zPath = mprintf("%s/%s/%s", g.zPath, zCheckin, zName);
      g.zPath = mprintf("%s/%s/%s", g.zPath, zCheckin, zName);
    }
    if( nMiss==0 ) zOrigName = zName;
    if( !file_is_simple_pathname(zName, 1) ){
      if( sqlite3_strglob("*/", zName)==0 ){
        assert( nMiss>=0 && nMiss<ArraySize(azSuffix) );
        zName = mprintf("%s%s", zName, azSuffix[nMiss]);
        if( !file_is_simple_pathname(zName, 1) ){
          goto doc_not_found;
        }
      }else{
        goto doc_not_found;
      }
    }
    if( isUV ){
      if( db_exists("SELECT 1 FROM unversioned"
                    " WHERE name=%Q AND content IS NOT NULL", zName) ){
        blob_init(&filebody, 0, 0);
        db_blob(&filebody, "SELECT content FROM unversioned WHERE name=%Q",
                zName);
        blob_uncompress(&filebody, &filebody);
        rid = 1;
        zDfltTitle = zName;
      }
    if( fossil_strcmp(zCheckin,"ckout")==0 ){
    }else if( fossil_strcmp(zCheckin,"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)
       && blob_read_from_file(&filebody, zFullpath)>0 ){
        rid = 1;  /* Fake RID just to get the loop to end */
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
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







+
-
-
-
-
+
+
+
+
+







-
+










-
+




-
+







  ** file to the user
  */
  zMime = nMiss==0 ? P("mimetype") : 0;
  if( zMime==0 ){
    zMime = mimetype_from_name(zName);
  }
  Th_Store("doc_name", zName);
  if( vid ){
  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));
    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, "text/x-fossil-wiki")==0 ){
    Blob tail;
    style_adunit_config(ADUNIT_RIGHT_OK);
    if( wiki_find_title(&filebody, &title, &tail) ){
      style_header("%s", blob_str(&title));
      wiki_convert(&tail, 0, WIKI_BUTTONS);
    }else{
      style_header("Documentation");
      style_header("%s", zDfltTitle);
      wiki_convert(&filebody, 0, WIKI_BUTTONS);
    }
    style_footer();
  }else if( fossil_strcmp(zMime, "text/x-markdown")==0 ){
    Blob tail = BLOB_INITIALIZER;
    markdown_to_html(&filebody, &title, &tail);
    if( blob_size(&title)>0 ){
      style_header("%s", blob_str(&title));
    }else{
      style_header("%s", nMiss>=ArraySize(azSuffix)?
                        "Not Found" : "Documentation");
                        "Not Found" : zDfltTitle);
    }
    convert_href_and_output(&tail);
    style_footer();
  }else if( fossil_strcmp(zMime, "text/plain")==0 ){
    style_header("Documentation");
    style_header("%s", zDfltTitle);
    @ <blockquote><pre>
    @ %h(blob_str(&filebody))
    @ </pre></blockquote>
    style_footer();
  }else if( fossil_strcmp(zMime, "text/html")==0
            && doc_is_embedded_html(&filebody, &title) ){
    if( blob_size(&title)==0 ) blob_append(&title,zName,-1);