Fossil

Check-in [4cc0ebef9a]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Avoid the use of tabs. Make sure lines do not exceed 80 characters.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | wolfgangFormat2CSS
Files: files | file ages | folders
SHA1: 4cc0ebef9a74d415d83ee58cb257af4cc09b3b26
User & Date: drh 2010-09-13 22:14:01.000
Context
2010-09-13
22:15
Fix a compiler warning of an unused variable. check-in: d35608836e user: drh tags: wolfgangFormat2CSS
22:14
Avoid the use of tabs. Make sure lines do not exceed 80 characters. check-in: 4cc0ebef9a user: drh tags: wolfgangFormat2CSS
20:41
Detect when an "update" is a no-op and exit early, without doing any work. This edit was suppose to go on trunk - it landed on wolfgangFormat2CSS by mistake. But we'll leave it here and let it go to trunk when we merge the wolfgangFormat2CSS changes... check-in: db313c32ce user: drh tags: wolfgangFormat2CSS
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/branch.c.
229
230
231
232
233
234
235
236

237
238
239
240

241

242
243
244
245
246
247
248
  }else{
    style_submenu_element("Closed","Closed","brlist?closed");
  }
  login_anonymous_available();
  compute_leaves(0, 1);
  style_sidebox_begin("Nomenclature:", "33%");
  @ <ol>
  @ <li> An <div class="sideboxDescribed"><a href="brlist">open branch</a></div> is a branch that has one or

  @ more <a href="leaves">open leaves.</a>
  @ The presence of open leaves presumably means
  @ that the branch is still being extended with new check-ins.</li>
  @ <li> A <div class="sideboxDescribed"><a href="brlist?closed">closed branch</a></div> is a branch with only

  @ <div class="sideboxDescribed"><a href="leaves?closed">closed leaves</a></div>.

  @ Closed branches are fixed and do not change (unless they are first
  @ reopened)</li>
  @ </ol>
  style_sidebox_end();

  cnt = 0;
  if( !showClosed ){







|
>



|
>
|
>







229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
  }else{
    style_submenu_element("Closed","Closed","brlist?closed");
  }
  login_anonymous_available();
  compute_leaves(0, 1);
  style_sidebox_begin("Nomenclature:", "33%");
  @ <ol>
  @ <li> An <div class="sideboxDescribed"><a href="brlist">
  @ open branch</a></div> is a branch that has one or
  @ more <a href="leaves">open leaves.</a>
  @ The presence of open leaves presumably means
  @ that the branch is still being extended with new check-ins.</li>
  @ <li> A <div class="sideboxDescribed"><a href="brlist?closed">
  @ closed branch</a></div> is a branch with only
  @ <div class="sideboxDescribed"><a href="leaves?closed">
  @ closed leaves</a></div>.
  @ Closed branches are fixed and do not change (unless they are first
  @ reopened)</li>
  @ </ol>
  style_sidebox_end();

  cnt = 0;
  if( !showClosed ){
Changes to src/browse.c.
231
232
233
234
235
236
237
238

239
240
241
242
243
244
    if( zFN[0]=='/' ){
      zFN++;
      @ <li><a href="%s(zSubdirLink)%T(zFN)">%h(zFN)/</a></li>
    }else if( zCI ){
      const char *zUuid = db_column_text(&q, 1);
      @ <li><a href="%s(g.zBaseURL)/artifact?name=%s(zUuid)">%h(zFN)</a></li>
    }else{
      @ <li><a href="%s(g.zBaseURL)/finfo?name=%T(zPrefix)%T(zFN)">%h(zFN)</a></li>

    }
  }
  db_finalize(&q);
  @ </ul></td></tr></table>
  style_footer();
}







|
>






231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
    if( zFN[0]=='/' ){
      zFN++;
      @ <li><a href="%s(zSubdirLink)%T(zFN)">%h(zFN)/</a></li>
    }else if( zCI ){
      const char *zUuid = db_column_text(&q, 1);
      @ <li><a href="%s(g.zBaseURL)/artifact?name=%s(zUuid)">%h(zFN)</a></li>
    }else{
      @ <li><a href="%s(g.zBaseURL)/finfo?name=%T(zPrefix)%T(zFN)">%h(zFN)
      @     </a></li>
    }
  }
  db_finalize(&q);
  @ </ul></td></tr></table>
  style_footer();
}
Changes to src/db.c.
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
    fossil_fatal("cannot locate home directory - "
                 "please set the HOME environment variable");
  }
#endif
  if( file_isdir(zHome)!=1 ){
    fossil_fatal("invalid home directory: %s", zHome);
  }
#ifndef __MINGW32__
#ifndef _WIN32
  if( access(zHome, W_OK) ){
    fossil_fatal("home directory %s must be writeable", zHome);
  }
#endif
#endif
  g.zHome = mprintf("%/", zHome);
#if defined(_WIN32)
  /* . filenames give some window systems problems and many apps problems */
  zDbName = mprintf("%//_fossil", zHome);
#else
  zDbName = mprintf("%s/.fossil", zHome);







<




<







662
663
664
665
666
667
668

669
670
671
672

673
674
675
676
677
678
679
    fossil_fatal("cannot locate home directory - "
                 "please set the HOME environment variable");
  }
#endif
  if( file_isdir(zHome)!=1 ){
    fossil_fatal("invalid home directory: %s", zHome);
  }

#ifndef _WIN32
  if( access(zHome, W_OK) ){
    fossil_fatal("home directory %s must be writeable", zHome);
  }

#endif
  g.zHome = mprintf("%/", zHome);
#if defined(_WIN32)
  /* . filenames give some window systems problems and many apps problems */
  zDbName = mprintf("%//_fossil", zHome);
#else
  zDbName = mprintf("%s/.fossil", zHome);
Changes to src/descendants.c.
316
317
318
319
320
321
322
323

324

325
326

327
328
329
330
331
332
333
    style_submenu_element("Open", "Open", "leaves");
  }
  style_header("Leaves");
  login_anonymous_available();
  compute_leaves(0, showAll ? 0 : showClosed ? 2 : 1);
  style_sidebox_begin("Nomenclature:", "33%");
  @ <ol>
  @ <li> A <div class="sideboxDescribed">leaf</div> is a check-in with no descendants.</li>

  @ <li> An <div class="sideboxDescribed">open leaf</div> is a leaf that does not have a "closed" tag

  @ and is thus assumed to still be in use.</li>
  @ <li> A <div class="sideboxDescribed">closed leaf</div> has a "closed" tag and is thus assumed to

  @ be historical and no longer in active use.</li>
  @ </ol>
  style_sidebox_end();

  if( showAll ){
    @ <h1>All leaves, both open and closed:</h1>
  }else if( showClosed ){







|
>
|
>

|
>







316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
    style_submenu_element("Open", "Open", "leaves");
  }
  style_header("Leaves");
  login_anonymous_available();
  compute_leaves(0, showAll ? 0 : showClosed ? 2 : 1);
  style_sidebox_begin("Nomenclature:", "33%");
  @ <ol>
  @ <li> A <div class="sideboxDescribed">leaf</div>
  @ is a check-in with no descendants.</li>
  @ <li> An <div class="sideboxDescribed">open leaf</div>
  @ is a leaf that does not have a "closed" tag
  @ and is thus assumed to still be in use.</li>
  @ <li> A <div class="sideboxDescribed">closed leaf</div>
  @ has a "closed" tag and is thus assumed to
  @ be historical and no longer in active use.</li>
  @ </ol>
  style_sidebox_end();

  if( showAll ){
    @ <h1>All leaves, both open and closed:</h1>
  }else if( showClosed ){
Changes to src/finfo.c.
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
      @ <b>Deleted</b> by check-in
    }
    hyperlink_to_uuid(zShortCkin);
    @ %h(zCom) (user: 
    hyperlink_to_user(zUser, zDate, "");
    @ branch: %h(zBr))
    if( g.okHistory && zUuid ){

      if( fpid ){
        @ <a href="%s(g.zTop)/fdiff?v1=%s(zPUuid)&amp;v2=%s(zUuid)">[diff]</a>
      }
      @ <a href="%s(g.zTop)/annotate?checkin=%S(zCkin)&amp;filename=%h(zFilename)">
      @ [annotate]</a>
    }
    @ </td></tr>
  }
  db_finalize(&q);
  if( pGraph ){
    graph_finish(pGraph, 1);
    if( pGraph->nErr ){
      graph_free(pGraph);
      pGraph = 0;
    }else{
      @ <tr><td></td><td><div style="width:%d(pGraph->mxRail*20+30)px;"></div></td></tr>

    }
  }
  @ </table>
  timeline_output_graph_javascript(pGraph);
  style_footer();
}







>



|











|
>






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
      @ <b>Deleted</b> by check-in
    }
    hyperlink_to_uuid(zShortCkin);
    @ %h(zCom) (user: 
    hyperlink_to_user(zUser, zDate, "");
    @ branch: %h(zBr))
    if( g.okHistory && zUuid ){
      const char *z = zFilename;
      if( fpid ){
        @ <a href="%s(g.zTop)/fdiff?v1=%s(zPUuid)&amp;v2=%s(zUuid)">[diff]</a>
      }
      @ <a href="%s(g.zTop)/annotate?checkin=%S(zCkin)&amp;filename=%h(z)">
      @ [annotate]</a>
    }
    @ </td></tr>
  }
  db_finalize(&q);
  if( pGraph ){
    graph_finish(pGraph, 1);
    if( pGraph->nErr ){
      graph_free(pGraph);
      pGraph = 0;
    }else{
      @ <tr><td></td><td><div style="width:%d(pGraph->mxRail*20+30)px;"></div>
      @     </td></tr>
    }
  }
  @ </table>
  timeline_output_graph_javascript(pGraph);
  style_footer();
}
Changes to src/info.c.
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
        @ <td>%h(zUser) @ %h(zIpAddr) on %s(zDate)</td></tr>
      }
      db_finalize(&q);
    }
    if( g.okHistory ){
      const char *zProjName = db_get("project-name", "unnamed");
      @ <tr><th>Timelines:</th><td>
      @    <a href="%s(g.zBaseURL)/timeline?p=%S(zUuid)">ancestors</a>
      @    | <a href="%s(g.zBaseURL)/timeline?d=%S(zUuid)">descendants</a>
      @    | <a href="%s(g.zBaseURL)/timeline?d=%S(zUuid)&amp;p=%S(zUuid)">both</a>
      db_prepare(&q, "SELECT substr(tag.tagname,5) FROM tagxref, tag "
                     " WHERE rid=%d AND tagtype>0 "
                     "   AND tag.tagid=tagxref.tagid "
                     "   AND +tag.tagname GLOB 'sym-*'", rid);
      while( db_step(&q)==SQLITE_ROW ){
        const char *zTagName = db_column_text(&q, 0);
        @  | <a href="%s(g.zTop)/timeline?r=%T(zTagName)">%h(zTagName)</a>







|
|
|







397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
        @ <td>%h(zUser) @ %h(zIpAddr) on %s(zDate)</td></tr>
      }
      db_finalize(&q);
    }
    if( g.okHistory ){
      const char *zProjName = db_get("project-name", "unnamed");
      @ <tr><th>Timelines:</th><td>
      @   <a href="%s(g.zBaseURL)/timeline?p=%S(zUuid)">ancestors</a>
      @ | <a href="%s(g.zBaseURL)/timeline?d=%S(zUuid)">descendants</a>
      @ | <a href="%s(g.zBaseURL)/timeline?d=%S(zUuid)&amp;p=%S(zUuid)">both</a>
      db_prepare(&q, "SELECT substr(tag.tagname,5) FROM tagxref, tag "
                     " WHERE rid=%d AND tagtype>0 "
                     "   AND tag.tagid=tagxref.tagid "
                     "   AND +tag.tagname GLOB 'sym-*'", rid);
      while( db_step(&q)==SQLITE_ROW ){
        const char *zTagName = db_column_text(&q, 0);
        @  | <a href="%s(g.zTop)/timeline?r=%T(zTagName)">%h(zTagName)</a>
Changes to src/login.c.
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
  if( P("g") ){
    @ <input type="hidden" name="g" value="%h(P("g"))" />
  }
  @ <table class="login_out">
  @ <tr>
  @   <td class="login_out_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="login_out_label">Password:</td>
  @   <td><input type="password" id="p" name="p" value="" size="30" /></td>
  @ </tr>
  if( g.zLogin==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>
  @ </table>
  @ <script  type="text/JavaScript">document.getElementById('u').focus()</script>
  if( g.zLogin==0 ){
    @ <p>Enter
  }else{
    @ <p>You are currently logged in as <b>%h(g.zLogin)</b></p>
    @ <p>To change your login to a different user, enter
  }
  @ your user-id and password at the left and press the







|

|
















|







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
  if( P("g") ){
    @ <input type="hidden" name="g" value="%h(P("g"))" />
  }
  @ <table class="login_out">
  @ <tr>
  @   <td class="login_out_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="login_out_label">Password:</td>
  @   <td><input type="password" id="p" name="p" value="" size="30" /></td>
  @ </tr>
  if( g.zLogin==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>
  @ </table>
  @ <script type="text/JavaScript">document.getElementById('u').focus()</script>
  if( g.zLogin==0 ){
    @ <p>Enter
  }else{
    @ <p>You are currently logged in as <b>%h(g.zLogin)</b></p>
    @ <p>To change your login to a different user, enter
  }
  @ your user-id and password at the left and press the
Changes to src/setup.c.
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
     @ <tr><td valign="top"><b>v</b></td>
     @   <td><i>Developer:</i> Inherit privileges of
     @   user <tt>developer</tt></td></tr>
     @ <tr><td valign="top"><b>w</b></td>
     @   <td><i>Write-Tkt:</i> Edit tickets</td></tr>
     @ <tr><td valign="top"><b>z</b></td>
     @   <td><i>Zip download:</i> Download a baseline via the
     @   <tt>/zip</tt> URL even without check<span class="capability">o</span>ut

     @    and <span class="capability">h</span>istory permissions</td></tr>
  @ </table>
  @ </li>
  @
  @ <li><p>
  @ Every user, logged in or not, inherits the privileges of <span class="usertype">nobody</span>.

  @ </p></li>
  @
  @ <li><p>
  @ Any human can login as <span class="usertype">anonymous</span> since the
  @ password is clearly displayed on the login page for them to type.  The purpose
  @ of requiring anonymous to log in is to prevent access by spiders.
  @ Every logged-in user inherits the combined privileges of
  @ <span class="usertype">anonymous</span> and
  @ <span class="usertype">nobody</span>.
  @ </p></li>
  @
  @ <li><p>
  @ Users with privilege <span class="capability">v</span> inherit the combined







|
>





|
>




|
|







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
     @ <tr><td valign="top"><b>v</b></td>
     @   <td><i>Developer:</i> Inherit privileges of
     @   user <tt>developer</tt></td></tr>
     @ <tr><td valign="top"><b>w</b></td>
     @   <td><i>Write-Tkt:</i> Edit tickets</td></tr>
     @ <tr><td valign="top"><b>z</b></td>
     @   <td><i>Zip download:</i> Download a baseline via the
     @   <tt>/zip</tt> URL even without 
     @    check<span class="capability">o</span>ut
     @    and <span class="capability">h</span>istory permissions</td></tr>
  @ </table>
  @ </li>
  @
  @ <li><p>
  @ Every user, logged in or not, inherits the privileges of
  @ <span class="usertype">nobody</span>.
  @ </p></li>
  @
  @ <li><p>
  @ Any human can login as <span class="usertype">anonymous</span> since the
  @ password is clearly displayed on the login page for them to type. The
  @ purpose of requiring anonymous to log in is to prevent access by spiders.
  @ Every logged-in user inherits the combined privileges of
  @ <span class="usertype">anonymous</span> and
  @ <span class="usertype">nobody</span>.
  @ </p></li>
  @
  @ <li><p>
  @ Users with privilege <span class="capability">v</span> inherit the combined
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
    }else{
      zPw = db_text(0, "SELECT pw FROM user WHERE uid=%d", uid);
    }
    if( uid>0 &&
        db_exists("SELECT 1 FROM user WHERE login=%Q AND uid!=%d", zLogin, uid)
    ){
      style_header("User Creation Error");
      @ <span class="loginError">Login "%h(zLogin)" is already used by a different
      @ user.</span>
      @
      @ <p><a href="setup_uedit?id=%d(uid)">[Bummer]</a></p>
      style_footer();
      return;
    }
    login_verify_csrf_secret();
    db_multi_exec(







|
|







323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
    }else{
      zPw = db_text(0, "SELECT pw FROM user WHERE uid=%d", uid);
    }
    if( uid>0 &&
        db_exists("SELECT 1 FROM user WHERE login=%Q AND uid!=%d", zLogin, uid)
    ){
      style_header("User Creation Error");
      @ <span class="loginError">Login "%h(zLogin)" is already used by
      @ a different user.</span>
      @
      @ <p><a href="setup_uedit?id=%d(uid)">[Bummer]</a></p>
      style_footer();
      return;
    }
    login_verify_csrf_secret();
    db_multi_exec(
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

  /* figure out inherited permissions */
  memset(inherit, 0, sizeof(inherit));
  if( strcmp(zLogin, "developer") ){
    char *z1, *z2;
    z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='developer'");
    while( z1 && *z1 ){

      inherit[0x7f & *(z1++)] = "<span class=\"ueditInheritDeveloper\">&bull;</span>";
    }
    free(z2);
  }
  if( strcmp(zLogin, "reader") ){
    char *z1, *z2;
    z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='reader'");
    while( z1 && *z1 ){

      inherit[0x7f & *(z1++)] = "<span class=\"ueditInheritReader\">&bull;</span>";
    }
    free(z2);
  }
  if( strcmp(zLogin, "anonymous") ){
    char *z1, *z2;
    z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='anonymous'");
    while( z1 && *z1 ){

      inherit[0x7f & *(z1++)] = "<span class=\"ueditInheritAnonymous\">&bull;</span>";
    }
    free(z2);
  }
  if( strcmp(zLogin, "nobody") ){
    char *z1, *z2;
    z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='nobody'");
    while( z1 && *z1 ){

      inherit[0x7f & *(z1++)] = "<span class=\"ueditInheritNobody\">&bull;</span>";
    }
    free(z2);
  }

  /* Begin generating the page
  */
  style_submenu_element("Cancel", "Cancel", "setup_ulist");







>
|







>
|







>
|







>
|







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

  /* figure out inherited permissions */
  memset(inherit, 0, sizeof(inherit));
  if( strcmp(zLogin, "developer") ){
    char *z1, *z2;
    z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='developer'");
    while( z1 && *z1 ){
      inherit[0x7f & *(z1++)] =
         "<span class=\"ueditInheritDeveloper\">&bull;</span>";
    }
    free(z2);
  }
  if( strcmp(zLogin, "reader") ){
    char *z1, *z2;
    z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='reader'");
    while( z1 && *z1 ){
      inherit[0x7f & *(z1++)] =
          "<span class=\"ueditInheritReader\">&bull;</span>";
    }
    free(z2);
  }
  if( strcmp(zLogin, "anonymous") ){
    char *z1, *z2;
    z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='anonymous'");
    while( z1 && *z1 ){
      inherit[0x7f & *(z1++)] =
           "<span class=\"ueditInheritAnonymous\">&bull;</span>";
    }
    free(z2);
  }
  if( strcmp(zLogin, "nobody") ){
    char *z1, *z2;
    z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='nobody'");
    while( z1 && *z1 ){
      inherit[0x7f & *(z1++)] =
           "<span class=\"ueditInheritNobody\">&bull;</span>";
    }
    free(z2);
  }

  /* Begin generating the page
  */
  style_submenu_element("Cancel", "Cancel", "setup_ulist");
497
498
499
500
501
502
503
504

505
506
507
508
509
510
511
512
513
514
515
516
517
518

519
520
521
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
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
    @ <li><p><font color="blue"><b>
    @ User %h(zLogin) has Setup privileges and you only have Admin privileges
    @ so you are not permitted to make changes to %h(zLogin).
    @ </b></font></p></li>
    @
  }
  @ <li><p>
  @ The <span class="capability">Setup</span> user can make arbitrary configuration changes.

  @ An <span class="usertype">Admin</span> user can add other users and change user privileges
  @ and reset user passwords.  Both automatically get all other privileges
  @ listed below.  Use these two settings with discretion.
  @ </p></li>
  @
  @ <li><p>
  @ The "<span class="ueditInheritNobody"><big>&bull;</big></span>" mark indicates
  @ the privileges of <span class="usertype">nobody</span> that are available to all users
  @ regardless of whether or not they are logged in.
  @ </p></li>
  @
  @ <li><p>
  @ The "<span class="ueditInheritAnonymous"><big>&bull;</big></span>" mark indicates
  @ the privileges of <span class="usertype">anonymous</span> that are inherited by all logged-in users.

  @ </p></li>
  @
  @ <li><p>
  @ The "<span class="ueditInheritDeveloper"><big>&bull;</big></span>" mark indicates
  @ the privileges of <span class="usertype">developer</span> that are inherited by all users with

  @ the <span class="capability">Developer</span> privilege.
  @ </p></li>
  @
  @ <li><p>
  @ The "<span class="ueditInheritReader"><big>&bull;</big></span>" mark indicates
  @ the privileges of <span class="usertype">reader</span> that are inherited by all users with

  @ the <span class="capability">Reader</span> privilege.
  @ </p></li>
  @
  @ <li><p>
  @ The <span class="capability">Delete</span> privilege give the user the ability to erase
  @ wiki, tickets, and attachments that have been added by anonymous
  @ users.  This capability is intended for deletion of spam.  The
  @ delete capability is only in effect for 24 hours after the item
  @ is first posted.  The <span class="usertype">Setup</span> user can delete anything at any time.

  @ </p></li>
  @
  @ <li><p>
  @ The <span class="capability">History</span> privilege allows a user to see most hyperlinks.
  @ This is recommended ON for most logged-in users but OFF for
  @ user "nobody" to avoid problems with spiders trying to walk every
  @ historical version of every baseline and file.
  @ </p></li>
  @
  @ <li><p>
  @ The <span class="capability">Zip</span> privilege allows a user to see the "download as ZIP"

  @ hyperlink and permits access to the <tt>/zip</tt> page.  This allows
  @ users to download ZIP archives without granting other rights like

  @ <span class="capability">Read</span> or <span class="capability">History</span>.  This privilege is recommended for
  @ user <span class="usertype">nobody</span> so that automatic package downloaders can obtain
  @ the sources without going through the login procedure.

  @ </p></li>
  @
  @ <li><p>
  @ The <span class="capability">Check-in</span> privilege allows remote users to "push".
  @ The <span class="capability">Check-out</span> privilege allows remote users to "pull".

  @ The <span class="capability">Clone</span> privilege allows remote users to "clone".
  @ </p></li>
  @
  @ <li><p>
  @ The <span class="capability">Read Wiki</span>, <span class="capability">New Wiki</span>, <span class="capability">Append Wiki</span>, and


  @ <b>Write Wiki</b> privileges control access to wiki pages.  The
  @ <span class="capability">Read Ticket</span>, <span class="capability">New Ticket</span>, <span class="capability">Append Ticket</span>, and


  @ <span class="capability">Write Ticket</span> privileges control access to trouble tickets.

  @ The <span class="capability">Ticket Report</span> privilege allows the user to create or edit
  @ ticket report formats.
  @ </p></li>
  @
  @ <li><p>
  @ Users with the <span class="capability">Password</span> privilege are allowed
  @ to change their own password.  Recommended ON for most users but OFF for special

  @ users <span class="usertype">developer</span>, <span class="usertype">anonymous</span>,
  @ and <span class="usertype">nobody</span>.
  @ </p></li>
  @
  @ <li><p>
  @ The <span class="capability">EMail</span> privilege allows the display of
  @ sensitive information such as the email address of users and contact information

  @ on tickets. Recommended OFF for <span class="usertype">anonymousy</span> and for
  @ <span class="usertype">nobody</span> but ON for <span class="usertype">developer</span>.

  @ </p></li>
  @
  @ <li><p>
  @ The <span class="capability">Attachment</span> privilege is needed in order to
  @ add attachments to tickets or wiki.  Write privilege on the ticket or wiki is
  @ also required.
  @ </p></li>
  @
  @ <li><p>
  @ Login is prohibited if the password is an empty string.
  @ </p></li>
  @ </ul>
  @
  @ <h2>Special Logins</h2>
  @
  @ <ul>
  @ <li><p>
  @ No login is required for user <span class="usertype">nobody</span>. The
  @ capabilities of the <span class="usertype">nobody</span> user are inherited by
  @ all users, regardless of whether or not they are logged in. To disable universal
  @ access to the repository, make sure no user named <span class="usertype">nobody</span>

  @ exists or that the <span class="usertype">nobody</span> user has no capabilities
  @ enabled. The password for <span class="usertype">nobody</span> is ignore. To
  @ avoid problems with spiders overloading the server, it is recommended
  @ that the <span class="capability">h</span> (History) capability be turned off
  @ for the <span class="usertype">nobody</span> user.
  @ </p></li>
  @
  @ <li><p>
  @ Login is required for user <span class="usertype">anonymous</span> but the
  @ password is displayed on the login screen beside the password entry box
  @ so anybody who can read should be able to login as anonymous.
  @ On the other hand, spiders and web-crawlers will typically not
  @ be able to login.  Set the capabilities of the <span class="usertype">anonymous</span>

  @ user to things that you want any human to be able to do, but not any
  @ spider.  Every other logged-in user inherits the privileges of
  @ <span class="usertype">anonymous</span>.
  @ </p></li>
  @
  @ <li><p>
  @ The <span class="usertype">developer</span> user is intended as a template
  @ for trusted users with check-in privileges. When adding new trusted users,
  @ simply select the <span class="capability">developer</span> privilege to cause
  @ the new user to inherit all privileges of the <span class="usertype">developer</span>

  @ user.  Similarly, the <span class="usertype">reader</span> user is a template

  @ for users who are allowed more access than <span class="usertype">anonymous</span>,
  @ but less than a <span class="usertype">developer</span>.
  @ </p></li>
  @ </ul>
  style_footer();
}









|
>
|





|
|
|



|
|
>



|
|
>
|



|
|
>
|



|
|
|
|
|
>



|
|
|
|



|
>


>
|
|
|
>



|
|
>
|



|
>
>

|
>
>
|
>
|
|



|
|
>
|





|
>
|
|
>



|
|
|












|
|
|
>
|
|
|
|
|







|
>








|
|
>
|
>
|







503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
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
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
654
655
656
657
658
659
660
661
662
663
    @ <li><p><font color="blue"><b>
    @ User %h(zLogin) has Setup privileges and you only have Admin privileges
    @ so you are not permitted to make changes to %h(zLogin).
    @ </b></font></p></li>
    @
  }
  @ <li><p>
  @ The <span class="capability">Setup</span> user can make arbitrary
  @ configuration changes. An <span class="usertype">Admin</span> user
  @ can add other users and change user privileges
  @ and reset user passwords.  Both automatically get all other privileges
  @ listed below.  Use these two settings with discretion.
  @ </p></li>
  @
  @ <li><p>
  @ The "<span class="ueditInheritNobody"><big>&bull;</big></span>" mark
  @ indicates the privileges of <span class="usertype">nobody</span> that
  @ are available to all users regardless of whether or not they are logged in.
  @ </p></li>
  @
  @ <li><p>
  @ The "<span class="ueditInheritAnonymous"><big>&bull;</big></span>" mark
  @ indicates the privileges of <span class="usertype">anonymous</span> that
  @ are inherited by all logged-in users.
  @ </p></li>
  @
  @ <li><p>
  @ The "<span class="ueditInheritDeveloper"><big>&bull;</big></span>" mark
  @ indicates the privileges of <span class="usertype">developer</span> that
  @ are inherited by all users with the
  @ <span class="capability">Developer</span> privilege.
  @ </p></li>
  @
  @ <li><p>
  @ The "<span class="ueditInheritReader"><big>&bull;</big></span>" mark
  @ indicates the privileges of <span class="usertype">reader</span> that
  @ are inherited by all users with the <span class="capability">Reader</span>
  @ privilege.
  @ </p></li>
  @
  @ <li><p>
  @ The <span class="capability">Delete</span> privilege give the user the
  @ ability to erase wiki, tickets, and attachments that have been added
  @ by anonymous users.  This capability is intended for deletion of spam. 
  @ The delete capability is only in effect for 24 hours after the item
  @ is first posted.  The <span class="usertype">Setup</span> user can
  @ delete anything at any time.
  @ </p></li>
  @
  @ <li><p>
  @ The <span class="capability">History</span> privilege allows a user
  @ to see most hyperlinks. This is recommended ON for most logged-in users
  @ but OFF for user "nobody" to avoid problems with spiders trying to walk
  @ every historical version of every baseline and file.
  @ </p></li>
  @
  @ <li><p>
  @ The <span class="capability">Zip</span> privilege allows a user to
  @ see the "download as ZIP"
  @ hyperlink and permits access to the <tt>/zip</tt> page.  This allows
  @ users to download ZIP archives without granting other rights like
  @ <span class="capability">Read</span> or
  @ <span class="capability">History</span>.  This privilege is recommended for
  @ user <span class="usertype">nobody</span> so that automatic package
  @ downloaders can obtain the sources without going through the login
  @ procedure.
  @ </p></li>
  @
  @ <li><p>
  @ The <span class="capability">Check-in</span> privilege allows remote
  @ users to "push". The <span class="capability">Check-out</span> privilege
  @ allows remote users to "pull". The <span class="capability">Clone</span>
  @ privilege allows remote users to "clone".
  @ </p></li>
  @
  @ <li><p>
  @ The <span class="capability">Read Wiki</span>,
  @ <span class="capability">New Wiki</span>,
  @ <span class="capability">Append Wiki</span>, and
  @ <b>Write Wiki</b> privileges control access to wiki pages.  The
  @ <span class="capability">Read Ticket</span>,
  @ <span class="capability">New Ticket</span>,
  @ <span class="capability">Append Ticket</span>, and
  @ <span class="capability">Write Ticket</span> privileges control access
  @ to trouble tickets.
  @ The <span class="capability">Ticket Report</span> privilege allows
  @ the user to create or edit ticket report formats.
  @ </p></li>
  @
  @ <li><p>
  @ Users with the <span class="capability">Password</span> privilege
  @ are allowed to change their own password.  Recommended ON for most
  @ users but OFF for special users <span class="usertype">developer</span>,
  @ <span class="usertype">anonymous</span>,
  @ and <span class="usertype">nobody</span>.
  @ </p></li>
  @
  @ <li><p>
  @ The <span class="capability">EMail</span> privilege allows the display of
  @ sensitive information such as the email address of users and contact
  @ information on tickets. Recommended OFF for 
  @ <span class="usertype">anonymousy</span> and for
  @ <span class="usertype">nobody</span> but ON for
  @ <span class="usertype">developer</span>.
  @ </p></li>
  @
  @ <li><p>
  @ The <span class="capability">Attachment</span> privilege is needed in
  @ order to add attachments to tickets or wiki.  Write privilege on the
  @ ticket or wiki is also required.
  @ </p></li>
  @
  @ <li><p>
  @ Login is prohibited if the password is an empty string.
  @ </p></li>
  @ </ul>
  @
  @ <h2>Special Logins</h2>
  @
  @ <ul>
  @ <li><p>
  @ No login is required for user <span class="usertype">nobody</span>. The
  @ capabilities of the <span class="usertype">nobody</span> user are
  @ inherited by all users, regardless of whether or not they are logged in.
  @ To disable universal access to the repository, make sure no user named 
  @ <span class="usertype">nobody</span> exists or that the
  @ <span class="usertype">nobody</span> user has no capabilities
  @ enabled. The password for <span class="usertype">nobody</span> is ignore.
  @ To avoid problems with spiders overloading the server, it is recommended
  @ that the <span class="capability">h</span> (History) capability be turned 
  @ off for the <span class="usertype">nobody</span> user.
  @ </p></li>
  @
  @ <li><p>
  @ Login is required for user <span class="usertype">anonymous</span> but the
  @ password is displayed on the login screen beside the password entry box
  @ so anybody who can read should be able to login as anonymous.
  @ On the other hand, spiders and web-crawlers will typically not
  @ be able to login.  Set the capabilities of the
  @ <span class="usertype">anonymous</span>
  @ user to things that you want any human to be able to do, but not any
  @ spider.  Every other logged-in user inherits the privileges of
  @ <span class="usertype">anonymous</span>.
  @ </p></li>
  @
  @ <li><p>
  @ The <span class="usertype">developer</span> user is intended as a template
  @ for trusted users with check-in privileges. When adding new trusted users,
  @ simply select the <span class="capability">developer</span> privilege to
  @ cause the new user to inherit all privileges of the 
  @ <span class="usertype">developer</span>
  @ user.  Similarly, the <span class="usertype">reader</span> user is a 
  @ template for users who are allowed more access than
  @ <span class="usertype">anonymous</span>,
  @ but less than a <span class="usertype">developer</span>.
  @ </p></li>
  @ </ul>
  style_footer();
}


653
654
655
656
657
658
659
660

661
662
663
664
665
666
667
    if( iQ!=iVal ){
      login_verify_csrf_secret();
      db_set(zVar, iQ ? "1" : "0", 0);
      iVal = iQ;
    }
  }
  if( iVal ){
    @ <input type="checkbox" name="%s(zQParm)" checked="checked" /><b>%s(zLabel)</b>

  }else{
    @ <input type="checkbox" name="%s(zQParm)" /><b>%s(zLabel)</b>
  }
}

/*
** Generate an entry box for an attribute.







|
>







680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
    if( iQ!=iVal ){
      login_verify_csrf_secret();
      db_set(zVar, iQ ? "1" : "0", 0);
      iVal = iQ;
    }
  }
  if( iVal ){
    @ <input type="checkbox" name="%s(zQParm)" checked="checked" />
    @ <b>%s(zLabel)</b>
  }else{
    @ <input type="checkbox" name="%s(zQParm)" /><b>%s(zLabel)</b>
  }
}

/*
** Generate an entry box for an attribute.
856
857
858
859
860
861
862
863
864
865

866
867
868
869
870
871
872
  @
  @ <p>The default "/home" page displays a Wiki page with the same name
  @ as the Project Name specified above.  Some sites prefer to redirect
  @ to a documentation page (ex: "/doc/tip/index.wiki") or to "/timeline".</p>
  @ <hr />
  onoff_attribute("Use HTML as wiki markup language",
    "wiki-use-html", "wiki-use-html", 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>

  @ <p><strong>CAUTION:</strong> when
  @ enabling, <i>all</i> HTML tags and attributes are accepted in the wiki.
  @ No sanitization is done. This means that it is very possible for malicious
  @ users to inject dangerous HTML, CSS and JavaScript code into your wiki.</p>
  @ <p>This should <strong>only</strong> be enabled when wiki editing is limited
  @ to trusted users. It should <strong>not</strong> be used on a publically
  @ editable wiki.</p>







|
|
|
>







884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
  @
  @ <p>The default "/home" page displays a Wiki page with the same name
  @ as the Project Name specified above.  Some sites prefer to redirect
  @ to a documentation page (ex: "/doc/tip/index.wiki") or to "/timeline".</p>
  @ <hr />
  onoff_attribute("Use HTML as wiki markup language",
    "wiki-use-html", "wiki-use-html", 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>
  @ <p><strong>CAUTION:</strong> when
  @ enabling, <i>all</i> HTML tags and attributes are accepted in the wiki.
  @ No sanitization is done. This means that it is very possible for malicious
  @ users to inject dangerous HTML, CSS and JavaScript code into your wiki.</p>
  @ <p>This should <strong>only</strong> be enabled when wiki editing is limited
  @ to trusted users. It should <strong>not</strong> be used on a publically
  @ editable wiki.</p>
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
  login_insert_csrf_secret();
  @ Edit the CSS below:<br />
  textarea_attribute("", 40, 80, "css", "css", zDefaultCSS);
  @ <br />
  @ <input type="submit" name="submit" value="Apply Changes" />
  @ <input type="submit" name="clear" value="Revert To Default" />
  @ </div></form>
  @ <p><span class="note">Note:</span> Press your browser Reload button after modifying the
  @ CSS in order to pull in the modified CSS file.</p>
  @ <hr />
  @ The default CSS is shown below for reference.  Other examples
  @ of CSS files can be seen on the <a href="setup_skin">skins page</a>.
  @ See also the <a href="setup_header">header</a> and
  @ <a href="setup_footer">footer</a> editing screens.
  @ <blockquote><pre>
  cgi_append_default_css();







|
|







932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
  login_insert_csrf_secret();
  @ Edit the CSS below:<br />
  textarea_attribute("", 40, 80, "css", "css", zDefaultCSS);
  @ <br />
  @ <input type="submit" name="submit" value="Apply Changes" />
  @ <input type="submit" name="clear" value="Revert To Default" />
  @ </div></form>
  @ <p><span class="note">Note:</span> Press your browser Reload button after
  @ modifying the CSS in order to pull in the modified CSS file.</p>
  @ <hr />
  @ The default CSS is shown below for reference.  Other examples
  @ of CSS files can be seen on the <a href="setup_skin">skins page</a>.
  @ See also the <a href="setup_header">header</a> and
  @ <a href="setup_footer">footer</a> editing screens.
  @ <blockquote><pre>
  cgi_append_default_css();
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
  login_insert_csrf_secret();
  @ Logo Image file:
  @ <input type="file" name="im" size="60" accept="image/*" /><br />
  @ <input type="submit" name="set" value="Change Logo" />
  @ <input type="submit" name="clr" value="Revert To Default" />
  @ </div></form>
  @
  @ <p><span class="note">Note:</span>  Your browser has probably cached the logo image, so
  @ you will probably need to press the Reload button on your browser after
  @ changing the logo to provoke your browser to reload the new logo image.
  @ </p>
  style_footer();
  db_end_transaction(0);
}







|
|
|
|



1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
  login_insert_csrf_secret();
  @ Logo Image file:
  @ <input type="file" name="im" size="60" accept="image/*" /><br />
  @ <input type="submit" name="set" value="Change Logo" />
  @ <input type="submit" name="clr" value="Revert To Default" />
  @ </div></form>
  @
  @ <p><span class="note">Note:</span>  Your browser has probably cached the
  @ logo image, so you will probably need to press the Reload button on your
  @ browser after changing the logo to provoke your browser to reload the new
  @ logo image. </p>
  style_footer();
  db_end_transaction(0);
}
Changes to src/style.c.
385
386
387
388
389
390
391






392
393
394
395
396
397
398
399
400
401
402
@ table.label-value th {
@   vertical-align: top;
@   text-align: right;
@   padding: 0.2ex 2ex;
@ }
@
;






const struct strctCssDefaults {
  char const * const elementClass;
  char const * const comment;
  char const * const value;
} cssDefaultList[] = {
  { "",
    "",
    zDefaultCSS
  },
  { "div.sidebox",
    "The nomenclature sidebox for branches,..",







>
>
>
>
>
>

|
|
|







385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
@ table.label-value th {
@   vertical-align: top;
@   text-align: right;
@   padding: 0.2ex 2ex;
@ }
@
;


/* The following table contains bits of default CSS that must
** be included if they are not found in the application-defined
** CSS.
*/
const struct strctCssDefaults {
  char const * const elementClass;  /* Name of element needed */
  char const * const comment;       /* Comment text */
  char const * const value;         /* CSS text */
} cssDefaultList[] = {
  { "",
    "",
    zDefaultCSS
  },
  { "div.sidebox",
    "The nomenclature sidebox for branches,..",
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
  },
  { 0,
    0,
    0
  }
};




void cgi_append_default_css(void) {
  int i;

  for (i=0;cssDefaultList[i].elementClass;i++)
    if (cssDefaultList[i].elementClass[0])
      cgi_printf("/* %s */\n%s {\n%s\n}\n\n",
		 cssDefaultList[i].comment,
		 cssDefaultList[i].elementClass,
		 cssDefaultList[i].value
		);
    else
      cgi_printf("%s",
		 cssDefaultList[i].value
		);


}

/*
** WEBPAGE: style.css
*/
void page_style_css(void){
  const char *zCSS    = 0;
  const char *zCSSdef = 0;
  int i;

  cgi_set_content_type("text/css");
  zCSS = db_get("css",(char*)zDefaultCSS);
  /* append user defined css */
  cgi_append_content(zCSS, -1);
  /* add special missing definitions */







>
>
>



|
|





|



>
>







<







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
  },
  { 0,
    0,
    0
  }
};

/*
** Append all of the default CSS to the CGI output.
*/
void cgi_append_default_css(void) {
  int i;

  for (i=0;cssDefaultList[i].elementClass;i++){
    if (cssDefaultList[i].elementClass[0]){
      cgi_printf("/* %s */\n%s {\n%s\n}\n\n",
		 cssDefaultList[i].comment,
		 cssDefaultList[i].elementClass,
		 cssDefaultList[i].value
		);
    }else{
      cgi_printf("%s",
		 cssDefaultList[i].value
		);
    }
  }
}

/*
** WEBPAGE: style.css
*/
void page_style_css(void){
  const char *zCSS    = 0;

  int i;

  cgi_set_content_type("text/css");
  zCSS = db_get("css",(char*)zDefaultCSS);
  /* append user defined css */
  cgi_append_content(zCSS, -1);
  /* add special missing definitions */
Changes to src/tag.c.
512
513
514
515
516
517
518
519

520
521
522
523
524
525
526
    " AND tagname GLOB 'sym-*'"
    " ORDER BY tagname"
  );
  @ <ul>
  while( db_step(&q)==SQLITE_ROW ){
    const char *zName = db_column_text(&q, 0);
    if( g.okHistory ){
      @ <li><a class="tagLink" href="%s(g.zBaseURL)/timeline?t=%T(zName)">%h(zName)</a></li>

    }else{
      @ <li><span class="tagDsp">%h(zName)</span></li>
    }
  }
  @ </ul>
  db_finalize(&q);
  style_footer();







|
>







512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
    " AND tagname GLOB 'sym-*'"
    " ORDER BY tagname"
  );
  @ <ul>
  while( db_step(&q)==SQLITE_ROW ){
    const char *zName = db_column_text(&q, 0);
    if( g.okHistory ){
      @ <li><a class="tagLink" href="%s(g.zBaseURL)/timeline?t=%T(zName)">
      @ %h(zName)</a></li>
    }else{
      @ <li><span class="tagDsp">%h(zName)</span></li>
    }
  }
  @ </ul>
  db_finalize(&q);
  style_footer();
540
541
542
543
544
545
546
547

548
549
550
551
552
553
554
    "   AND tagxref.tagtype>0 AND tagxref.srcid>0"
    "   AND tag.tagname GLOB 'sym-*'",
    rid
  );
  while( db_step(&q)==SQLITE_ROW ){
    const char *zTagName = db_column_text(&q, 0);
    if( g.okHistory ){
      @ <a class="tagLink" href="%s(g.zBaseURL)/timeline?t=%T(zTagName)">[%h(zTagName)]</a>

    }else{
      @ <span class="tagDsp">[%h(zTagName)]</span>
    }
  }
  db_finalize(&q);
}








|
>







541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
    "   AND tagxref.tagtype>0 AND tagxref.srcid>0"
    "   AND tag.tagname GLOB 'sym-*'",
    rid
  );
  while( db_step(&q)==SQLITE_ROW ){
    const char *zTagName = db_column_text(&q, 0);
    if( g.okHistory ){
      @ <a class="tagLink" href="%s(g.zBaseURL)/timeline?t=%T(zTagName)">
      @ [%h(zTagName)]</a>
    }else{
      @ <span class="tagDsp">[%h(zTagName)]</span>
    }
  }
  db_finalize(&q);
}

Changes to src/th_main.c.
276
277
278
279
280
281
282
283

284
285
286
287
288
289
290
    sendText(z, -1, 0);
    free(z);
    blob_reset(&name);
    for(i=0; i<nElem; i++){
      zH = htmlize((char*)azElem[i], aszElem[i]);
      if( zValue && aszElem[i]==nValue 
             && memcmp(zValue, azElem[i], nValue)==0 ){
        z = mprintf("<option value=\"%s\" selected=\"selected\">%s</option>", zH, zH);

      }else{
        z = mprintf("<option value=\"%s\">%s</option>", zH, zH);
      }
      free(zH);
      sendText(z, -1, 0);
      free(z);
    }







|
>







276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
    sendText(z, -1, 0);
    free(z);
    blob_reset(&name);
    for(i=0; i<nElem; i++){
      zH = htmlize((char*)azElem[i], aszElem[i]);
      if( zValue && aszElem[i]==nValue 
             && memcmp(zValue, azElem[i], nValue)==0 ){
        z = mprintf("<option value=\"%s\" selected=\"selected\">%s</option>",
                     zH, zH);
      }else{
        z = mprintf("<option value=\"%s\">%s</option>", zH, zH);
      }
      free(zH);
      sendText(z, -1, 0);
      free(z);
    }
Changes to src/timeline.c.
46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
/*
** Generate a hyperlink to a version.
*/
void hyperlink_to_uuid(const char *zUuid){
  char zShortUuid[UUID_SIZE+1];
  shorten_uuid(zShortUuid, zUuid);
  if( g.okHistory ){
    @ <a class="timelineHistLink" href="%s(g.zBaseURL)/info/%s(zShortUuid)">[%s(zShortUuid)]</a>

  }else{
    @ <span class="timelineHistDsp">[%s(zShortUuid)]</span>
  }
}

/*
** Generate a hyperlink that invokes javascript to highlight







|
>







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/*
** Generate a hyperlink to a version.
*/
void hyperlink_to_uuid(const char *zUuid){
  char zShortUuid[UUID_SIZE+1];
  shorten_uuid(zShortUuid, zUuid);
  if( g.okHistory ){
    @ <a class="timelineHistLink" href="%s(g.zBaseURL)/info/%s(zShortUuid)">
    @ [%s(zShortUuid)]</a>
  }else{
    @ <span class="timelineHistDsp">[%s(zShortUuid)]</span>
  }
}

/*
** Generate a hyperlink that invokes javascript to highlight
Changes to src/tkt.c.
565
566
567
568
569
570
571
572

573
574
575
576
577
578
579
                zName);
  if( nRec==0 ){
    @ <span class="tktError">No such ticket: \"%h(zName)\"</span>
    style_footer();
    return;
  }
  if( nRec>1 ){
    @ <span class="tktError"><b>%d(nRec) tickets begin with: \"%h(zName)\"</span>

    style_footer();
    return;
  }
  if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT<br />\n", -1);
  ticket_init();
  getAllTicketFields();
  initializeVariablesFromCGI();







|
>







565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
                zName);
  if( nRec==0 ){
    @ <span class="tktError">No such ticket: \"%h(zName)\"</span>
    style_footer();
    return;
  }
  if( nRec>1 ){
    @ <span class="tktError"><b>%d(nRec) tickets begin with:
    @ \"%h(zName)\"</span>
    style_footer();
    return;
  }
  if( g.thTrace ) Th_Trace("BEGIN_TKTEDIT<br />\n", -1);
  ticket_init();
  getAllTicketFields();
  initializeVariablesFromCGI();
Changes to src/tktsetup.c.
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
@ affect the operation of the product?</td>
@ </tr>
@ 
@ <tr>
@ <td style="text-align: center;">EMail:
@ <input type="text" name="private_contact" value="$<private_contact>" size="30" />
@ </td>
@ <td><span style="text-decoration: underline;">Not publicly visible</span>. Used by developers to contact you with
@ questions.</td>
@ </tr>
@ 
@ <tr>
@ <td colspan="2">
@ Enter a detailed description of the problem.
@ For code defects, be sure to provide details on exactly how
@ the problem can be reproduced.  Provide as much detail as







|
|







283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
@ affect the operation of the product?</td>
@ </tr>
@ 
@ <tr>
@ <td style="text-align: center;">EMail:
@ <input type="text" name="private_contact" value="$<private_contact>" size="30" />
@ </td>
@ <td><span style="text-decoration: underline;">Not publicly visible</span>.
@ Used by developers to contact you with questions.</td>
@ </tr>
@ 
@ <tr>
@ <td colspan="2">
@ Enter a detailed description of the problem.
@ For code defects, be sure to provide details on exactly how
@ the problem can be reproduced.  Provide as much detail as
336
337
338
339
340
341
342
343

344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
}

/*
** WEBPAGE: tktsetup_newpage
*/
void tktsetup_newpage_page(void){
  static const char zDesc[] =
  @ Enter HTML with embedded TH1 script that will render the "new ticket" page

  ;
  tktsetup_generic(
    "HTML For New Tickets",
    "ticket-newpage",
    zDefaultNew,
    zDesc,
    0,
    0,
    40
  );
}

static const char zDefaultView[] =
@ <table cellpadding="5">
@ <tr><td class="tktDspLabel">Ticket&nbsp;UUID:</td><td class="tktDspValue" colspan="3">
@ $<tkt_uuid>
@ </td></tr>
@ <tr><td class="tktDspLabel">Title:</td>
@ <td class="tktDspValue" colspan="3">
@ <th1>wiki $title</th1>
@ </td></tr>
@ <tr><td class="tktDspLabel">Status:</td><td class="tktDspValue">
@ $<status>
@ </td>







|
>














|
|
<







336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360

361
362
363
364
365
366
367
}

/*
** WEBPAGE: tktsetup_newpage
*/
void tktsetup_newpage_page(void){
  static const char zDesc[] =
  @ Enter HTML with embedded TH1 script that will render the "new ticket"
  @ page
  ;
  tktsetup_generic(
    "HTML For New Tickets",
    "ticket-newpage",
    zDefaultNew,
    zDesc,
    0,
    0,
    40
  );
}

static const char zDefaultView[] =
@ <table cellpadding="5">
@ <tr><td class="tktDspLabel">Ticket&nbsp;UUID:</td>
@ <td class="tktDspValue" colspan="3">$<tkt_uuid></td></tr>

@ <tr><td class="tktDspLabel">Title:</td>
@ <td class="tktDspValue" colspan="3">
@ <th1>wiki $title</th1>
@ </td></tr>
@ <tr><td class="tktDspLabel">Status:</td><td class="tktDspValue">
@ $<status>
@ </td>
Changes to src/wiki.c.
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
    @ <li> Use the <a href="%s(g.zBaseURL)/wiki?name=Sandbox">Sandbox</a>
    @      to experiment.</li>
    if( g.okNewWiki ){
      @ <li>  Create a <a href="%s(g.zBaseURL)/wikinew">new wiki page</a>.</li>
    }
    @ <li> <a href="%s(g.zBaseURL)/wcontent">List of All Wiki Pages</a>
    @      available on this server.</li>
	@ <li> <form method="get" action="%s(g.zBaseURL)/wfind"><div>
	@     Search wiki titles: <input type="text" name="title"/>
        @  &nbsp; <input type="submit" /></div></form>
	@ </li>
    @ </ul>
    style_footer();
    return;
  }
  if( check_name(zPageName) ) return;
  isSandbox = is_sandbox(zPageName);
  if( isSandbox ){







|
|
|
|







153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
    @ <li> Use the <a href="%s(g.zBaseURL)/wiki?name=Sandbox">Sandbox</a>
    @      to experiment.</li>
    if( g.okNewWiki ){
      @ <li>  Create a <a href="%s(g.zBaseURL)/wikinew">new wiki page</a>.</li>
    }
    @ <li> <a href="%s(g.zBaseURL)/wcontent">List of All Wiki Pages</a>
    @      available on this server.</li>
    @ <li> <form method="get" action="%s(g.zBaseURL)/wfind"><div>
    @     Search wiki titles: <input type="text" name="title"/>
    @  &nbsp; <input type="submit" /></div></form>
    @ </li>
    @ </ul>
    style_footer();
    return;
  }
  if( check_name(zPageName) ) return;
  isSandbox = is_sandbox(zPageName);
  if( isSandbox ){
225
226
227
228
229
230
231

232
233
234
235
236
237
238
239
    const char *zUser = db_column_text(&q, 2);
    if( cnt==0 ){
      @ <hr><h2>Attachments:</h2>
      @ <ul>
    }
    cnt++;
    if( g.okHistory && g.okRead ){

      @ <li><a href="%s(g.zTop)/attachview?page=%s(zPageName)&amp;file=%t(zFile)">
      @ %h(zFile)</a>
    }else{
      @ <li>%h(zFile)
    }
    @ added by %h(zUser) on
    hyperlink_to_date(zDate, ".");
    if( g.okWrWiki && g.okAttach ){







>
|







225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
    const char *zUser = db_column_text(&q, 2);
    if( cnt==0 ){
      @ <hr><h2>Attachments:</h2>
      @ <ul>
    }
    cnt++;
    if( g.okHistory && g.okRead ){
      @ <li>
      @ <a href="%s(g.zTop)/attachview?page=%s(zPageName)&amp;file=%t(zFile)">
      @ %h(zFile)</a>
    }else{
      @ <li>%h(zFile)
    }
    @ added by %h(zUser) on
    hyperlink_to_date(zDate, ".");
    if( g.okWrWiki && g.okAttach ){
Changes to src/wikiformat.c.
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
** Render markup on the given blob.
*/
static void renderMarkup(Blob *pOut, ParsedMarkup *p){
  int i;
  if( p->endTag ){
    blob_appendf(pOut, "</%s>", aMarkup[p->iCode].zName);
  }else{
    /* close active paragraph for several elemnts, which are not allowed
    ** in paragraphs(xhtml!)
    */
    blob_appendf(pOut, "<%s", aMarkup[p->iCode].zName);
    for(i=0; i<p->nAttr; i++){
      blob_appendf(pOut, " %s", aAttribute[p->aAttr[i].iACode].zName);
      if( p->aAttr[i].zValue ){
        const char *zVal = p->aAttr[i].zValue;
        if( p->aAttr[i].iACode==ATTR_SRC && zVal[0]=='/' ){
          blob_appendf(pOut, "=\"%s%s\"", g.zBaseURL, zVal);
        }else{
          blob_appendf(pOut, "=\"%s\"", zVal);
        }
      }
    }
    if (p->iType & MUTYPE_SINGLE)
      blob_append(pOut, " /", 2);

    blob_append(pOut, ">", 1);
  }
}

/*
** When the markup was parsed, some "\000" may have been inserted.
** This routine restores to those "\000" values back to their







|
|













|

>







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
** Render markup on the given blob.
*/
static void renderMarkup(Blob *pOut, ParsedMarkup *p){
  int i;
  if( p->endTag ){
    blob_appendf(pOut, "</%s>", aMarkup[p->iCode].zName);
  }else{
    /* Close active paragraph for several elements, which are not allowed
    ** in paragraphs in XHTML.
    */
    blob_appendf(pOut, "<%s", aMarkup[p->iCode].zName);
    for(i=0; i<p->nAttr; i++){
      blob_appendf(pOut, " %s", aAttribute[p->aAttr[i].iACode].zName);
      if( p->aAttr[i].zValue ){
        const char *zVal = p->aAttr[i].zValue;
        if( p->aAttr[i].iACode==ATTR_SRC && zVal[0]=='/' ){
          blob_appendf(pOut, "=\"%s%s\"", g.zBaseURL, zVal);
        }else{
          blob_appendf(pOut, "=\"%s\"", zVal);
        }
      }
    }
    if (p->iType & MUTYPE_SINGLE){
      blob_append(pOut, " /", 2);
    }
    blob_append(pOut, ">", 1);
  }
}

/*
** When the markup was parsed, some "\000" may have been inserted.
** This routine restores to those "\000" values back to their
1022
1023
1024
1025
1026
1027
1028

1029
1030
1031
1032
1033
1034
1035
1036
1037
    int isClosed = 0;
    if( is_ticket(zTarget, &isClosed) ){
      /* Special display processing for tickets.  Display the hyperlink
      ** as crossed out if the ticket is closed.
      */
      if( isClosed ){
        if( g.okHistory ){

          blob_appendf(p->pOut,"<a href=\"%s/info/%s\"><span class=\"wikiTagCancelled\">",
              g.zBaseURL, zTarget
          );
          zTerm = "</span></a>";
        }else{
          blob_appendf(p->pOut,"<span class=\"wikiTagCancelled\">");
          zTerm = "</span>";
        }
      }else{







>
|
|







1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
    int isClosed = 0;
    if( is_ticket(zTarget, &isClosed) ){
      /* Special display processing for tickets.  Display the hyperlink
      ** as crossed out if the ticket is closed.
      */
      if( isClosed ){
        if( g.okHistory ){
          blob_appendf(p->pOut,
             "<a href=\"%s/info/%s\"><span class=\"wikiTagCancelled\">",
             g.zBaseURL, zTarget
          );
          zTerm = "</span></a>";
        }else{
          blob_appendf(p->pOut,"<span class=\"wikiTagCancelled\">");
          zTerm = "</span>";
        }
      }else{
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411

1412
1413
1414
1415
1416
1417
1418
        }else
        {
          if( markup.iType==MUTYPE_FONT ){
            startAutoParagraph(p);
          }else if( markup.iType==MUTYPE_BLOCK ){
            p->wantAutoParagraph = 0;
          }
          if (   markup.iCode==MARKUP_HR
              || markup.iCode==MARKUP_H1
              || markup.iCode==MARKUP_H2
              || markup.iCode==MARKUP_H3
              || markup.iCode==MARKUP_H4
              || markup.iCode==MARKUP_H5
              || markup.iCode==MARKUP_P
	  )
            endAutoParagraph(p);

          if( (markup.iType & MUTYPE_STACK )!=0 ){
            pushStack(p, markup.iCode);
          }
          renderMarkup(p->pOut, &markup);
        }
        break;
      }







|
|
|
|
|
|
|
|

>







1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
        }else
        {
          if( markup.iType==MUTYPE_FONT ){
            startAutoParagraph(p);
          }else if( markup.iType==MUTYPE_BLOCK ){
            p->wantAutoParagraph = 0;
          }
          if(   markup.iCode==MARKUP_HR
             || markup.iCode==MARKUP_H1
             || markup.iCode==MARKUP_H2
             || markup.iCode==MARKUP_H3
             || markup.iCode==MARKUP_H4
             || markup.iCode==MARKUP_H5
             || markup.iCode==MARKUP_P
          ){
            endAutoParagraph(p);
          }
          if( (markup.iType & MUTYPE_STACK )!=0 ){
            pushStack(p, markup.iCode);
          }
          renderMarkup(p->pOut, &markup);
        }
        break;
      }