Fossil SCM

merge latest change from trunk.

mgagnon 2023-01-11 03:06 no_ssh_sync_ip_resolve merge
Commit 5d5911e6fd0407d91861a8a02ab98db37734518650c53d35c72cf3e43368bb73
-1
--- src/add.c
+++ src/add.c
@@ -362,11 +362,10 @@
362362
** The --case-sensitive option determines whether or not filenames should
363363
** be treated case sensitive or not. If the option is not given, the default
364364
** depends on the global setting, or the operating system default, if not set.
365365
**
366366
** Options:
367
-**
368367
** --case-sensitive BOOL Override the case-sensitive setting
369368
** --dotfiles Include files beginning with a dot (".")
370369
** -f|--force Add files without prompting
371370
** --ignore CSG Ignore unmanaged files matching patterns from
372371
** the Comma Separated Glob (CSG) pattern list
373372
--- src/add.c
+++ src/add.c
@@ -362,11 +362,10 @@
362 ** The --case-sensitive option determines whether or not filenames should
363 ** be treated case sensitive or not. If the option is not given, the default
364 ** depends on the global setting, or the operating system default, if not set.
365 **
366 ** Options:
367 **
368 ** --case-sensitive BOOL Override the case-sensitive setting
369 ** --dotfiles Include files beginning with a dot (".")
370 ** -f|--force Add files without prompting
371 ** --ignore CSG Ignore unmanaged files matching patterns from
372 ** the Comma Separated Glob (CSG) pattern list
373
--- src/add.c
+++ src/add.c
@@ -362,11 +362,10 @@
362 ** The --case-sensitive option determines whether or not filenames should
363 ** be treated case sensitive or not. If the option is not given, the default
364 ** depends on the global setting, or the operating system default, if not set.
365 **
366 ** Options:
 
367 ** --case-sensitive BOOL Override the case-sensitive setting
368 ** --dotfiles Include files beginning with a dot (".")
369 ** -f|--force Add files without prompting
370 ** --ignore CSG Ignore unmanaged files matching patterns from
371 ** the Comma Separated Glob (CSG) pattern list
372
+3 -6
--- src/alerts.c
+++ src/alerts.c
@@ -1127,12 +1127,12 @@
11271127
**
11281128
** send Compose and send pending email alerts.
11291129
** Some installations may want to do this via
11301130
** a cron-job to make sure alerts are sent
11311131
** in a timely manner.
1132
-** Options:
11331132
**
1133
+** Options:
11341134
** --digest Send digests
11351135
** --renewal Send subscription renewal
11361136
** notices
11371137
** --test Write to standard output
11381138
**
@@ -1146,12 +1146,13 @@
11461146
** LIKE or GLOB wildcards can be used in PATTERN.
11471147
**
11481148
** test-message TO [OPTS] Send a single email message using whatever
11491149
** email sending mechanism is currently configured.
11501150
** Use this for testing the email notification
1151
-** configuration. Options:
1151
+** configuration.
11521152
**
1153
+** Options:
11531154
** --body FILENAME Content from FILENAME
11541155
** --smtp-trace Trace SMTP processing
11551156
** --stdout Send msg to stdout
11561157
** -S|--subject SUBJECT Message "subject:"
11571158
**
@@ -2708,11 +2709,10 @@
27082709
** for check-in, forum, ticket, or wiki. The remaining text is a
27092710
** integer that references the EVENT.OBJID value for the event.
27102711
** Run /timeline?showid to see these OBJID values.
27112712
**
27122713
** Options:
2713
-**
27142714
** --digest Generate digest alert text
27152715
** --needmod Assume all events are pending moderator approval
27162716
*/
27172717
void test_alert_cmd(void){
27182718
Blob out;
@@ -2769,19 +2769,16 @@
27692769
** for check-in, forum, ticket, or wiki. The remaining text is a
27702770
** integer that references the EVENT.OBJID value for the event.
27712771
** Run /timeline?showid to see these OBJID values.
27722772
**
27732773
** Options:
2774
-**
27752774
** --backoffice Run alert_backoffice() after all alerts have
27762775
** been added. This will cause the alerts to be
27772776
** sent out with the SENDALERT_TRACE option.
2778
-**
27792777
** --debug Like --backoffice, but add the SENDALERT_STDOUT
27802778
** so that emails are printed to standard output
27812779
** rather than being sent.
2782
-**
27832780
** --digest Process emails using SENDALERT_DIGEST
27842781
*/
27852782
void test_add_alert_cmd(void){
27862783
int i;
27872784
int doAuto = find_option("backoffice",0,0)!=0;
27882785
--- src/alerts.c
+++ src/alerts.c
@@ -1127,12 +1127,12 @@
1127 **
1128 ** send Compose and send pending email alerts.
1129 ** Some installations may want to do this via
1130 ** a cron-job to make sure alerts are sent
1131 ** in a timely manner.
1132 ** Options:
1133 **
 
1134 ** --digest Send digests
1135 ** --renewal Send subscription renewal
1136 ** notices
1137 ** --test Write to standard output
1138 **
@@ -1146,12 +1146,13 @@
1146 ** LIKE or GLOB wildcards can be used in PATTERN.
1147 **
1148 ** test-message TO [OPTS] Send a single email message using whatever
1149 ** email sending mechanism is currently configured.
1150 ** Use this for testing the email notification
1151 ** configuration. Options:
1152 **
 
1153 ** --body FILENAME Content from FILENAME
1154 ** --smtp-trace Trace SMTP processing
1155 ** --stdout Send msg to stdout
1156 ** -S|--subject SUBJECT Message "subject:"
1157 **
@@ -2708,11 +2709,10 @@
2708 ** for check-in, forum, ticket, or wiki. The remaining text is a
2709 ** integer that references the EVENT.OBJID value for the event.
2710 ** Run /timeline?showid to see these OBJID values.
2711 **
2712 ** Options:
2713 **
2714 ** --digest Generate digest alert text
2715 ** --needmod Assume all events are pending moderator approval
2716 */
2717 void test_alert_cmd(void){
2718 Blob out;
@@ -2769,19 +2769,16 @@
2769 ** for check-in, forum, ticket, or wiki. The remaining text is a
2770 ** integer that references the EVENT.OBJID value for the event.
2771 ** Run /timeline?showid to see these OBJID values.
2772 **
2773 ** Options:
2774 **
2775 ** --backoffice Run alert_backoffice() after all alerts have
2776 ** been added. This will cause the alerts to be
2777 ** sent out with the SENDALERT_TRACE option.
2778 **
2779 ** --debug Like --backoffice, but add the SENDALERT_STDOUT
2780 ** so that emails are printed to standard output
2781 ** rather than being sent.
2782 **
2783 ** --digest Process emails using SENDALERT_DIGEST
2784 */
2785 void test_add_alert_cmd(void){
2786 int i;
2787 int doAuto = find_option("backoffice",0,0)!=0;
2788
--- src/alerts.c
+++ src/alerts.c
@@ -1127,12 +1127,12 @@
1127 **
1128 ** send Compose and send pending email alerts.
1129 ** Some installations may want to do this via
1130 ** a cron-job to make sure alerts are sent
1131 ** in a timely manner.
 
1132 **
1133 ** Options:
1134 ** --digest Send digests
1135 ** --renewal Send subscription renewal
1136 ** notices
1137 ** --test Write to standard output
1138 **
@@ -1146,12 +1146,13 @@
1146 ** LIKE or GLOB wildcards can be used in PATTERN.
1147 **
1148 ** test-message TO [OPTS] Send a single email message using whatever
1149 ** email sending mechanism is currently configured.
1150 ** Use this for testing the email notification
1151 ** configuration.
1152 **
1153 ** Options:
1154 ** --body FILENAME Content from FILENAME
1155 ** --smtp-trace Trace SMTP processing
1156 ** --stdout Send msg to stdout
1157 ** -S|--subject SUBJECT Message "subject:"
1158 **
@@ -2708,11 +2709,10 @@
2709 ** for check-in, forum, ticket, or wiki. The remaining text is a
2710 ** integer that references the EVENT.OBJID value for the event.
2711 ** Run /timeline?showid to see these OBJID values.
2712 **
2713 ** Options:
 
2714 ** --digest Generate digest alert text
2715 ** --needmod Assume all events are pending moderator approval
2716 */
2717 void test_alert_cmd(void){
2718 Blob out;
@@ -2769,19 +2769,16 @@
2769 ** for check-in, forum, ticket, or wiki. The remaining text is a
2770 ** integer that references the EVENT.OBJID value for the event.
2771 ** Run /timeline?showid to see these OBJID values.
2772 **
2773 ** Options:
 
2774 ** --backoffice Run alert_backoffice() after all alerts have
2775 ** been added. This will cause the alerts to be
2776 ** sent out with the SENDALERT_TRACE option.
 
2777 ** --debug Like --backoffice, but add the SENDALERT_STDOUT
2778 ** so that emails are printed to standard output
2779 ** rather than being sent.
 
2780 ** --digest Process emails using SENDALERT_DIGEST
2781 */
2782 void test_add_alert_cmd(void){
2783 int i;
2784 int doAuto = find_option("backoffice",0,0)!=0;
2785
+3 -5
--- src/attach.c
+++ src/attach.c
@@ -678,20 +678,19 @@
678678
** COMMAND: attachment*
679679
**
680680
** Usage: %fossil attachment add ?PAGENAME? FILENAME ?OPTIONS?
681681
**
682682
** Add an attachment to an existing wiki page or tech note.
683
-** Options:
684683
**
684
+** Options:
685685
** -t|--technote DATETIME Specifies the timestamp of
686686
** the technote to which the attachment
687687
** is to be made. The attachment will be
688688
** to the most recently modified tech note
689689
** with the specified timestamp.
690
-**
691690
** -t|--technote TECHNOTE-ID Specifies the technote to be
692
-** updated by its technote id.
691
+** updated by its technote id
693692
**
694693
** One of PAGENAME, DATETIME or TECHNOTE-ID must be specified.
695694
**
696695
** DATETIME may be "now" or "YYYY-MM-DDTHH:MM:SS.SSS". If in
697696
** year-month-day form, it may be truncated, the "T" may be replaced by
@@ -792,12 +791,11 @@
792791
** name arguments are glob prefixes for the attachment.target
793792
** field. If no names are provided then a prefix of [a-zA-Z] is used,
794793
** which will match most wiki page names and some ticket hashes.
795794
**
796795
** Options:
797
-**
798
-** -latest List only the latest version of a given attachment.
796
+** -latest List only the latest version of a given attachment
799797
**
800798
*/
801799
void test_list_attachments(void){
802800
Stmt q;
803801
int i;
804802
--- src/attach.c
+++ src/attach.c
@@ -678,20 +678,19 @@
678 ** COMMAND: attachment*
679 **
680 ** Usage: %fossil attachment add ?PAGENAME? FILENAME ?OPTIONS?
681 **
682 ** Add an attachment to an existing wiki page or tech note.
683 ** Options:
684 **
 
685 ** -t|--technote DATETIME Specifies the timestamp of
686 ** the technote to which the attachment
687 ** is to be made. The attachment will be
688 ** to the most recently modified tech note
689 ** with the specified timestamp.
690 **
691 ** -t|--technote TECHNOTE-ID Specifies the technote to be
692 ** updated by its technote id.
693 **
694 ** One of PAGENAME, DATETIME or TECHNOTE-ID must be specified.
695 **
696 ** DATETIME may be "now" or "YYYY-MM-DDTHH:MM:SS.SSS". If in
697 ** year-month-day form, it may be truncated, the "T" may be replaced by
@@ -792,12 +791,11 @@
792 ** name arguments are glob prefixes for the attachment.target
793 ** field. If no names are provided then a prefix of [a-zA-Z] is used,
794 ** which will match most wiki page names and some ticket hashes.
795 **
796 ** Options:
797 **
798 ** -latest List only the latest version of a given attachment.
799 **
800 */
801 void test_list_attachments(void){
802 Stmt q;
803 int i;
804
--- src/attach.c
+++ src/attach.c
@@ -678,20 +678,19 @@
678 ** COMMAND: attachment*
679 **
680 ** Usage: %fossil attachment add ?PAGENAME? FILENAME ?OPTIONS?
681 **
682 ** Add an attachment to an existing wiki page or tech note.
 
683 **
684 ** Options:
685 ** -t|--technote DATETIME Specifies the timestamp of
686 ** the technote to which the attachment
687 ** is to be made. The attachment will be
688 ** to the most recently modified tech note
689 ** with the specified timestamp.
 
690 ** -t|--technote TECHNOTE-ID Specifies the technote to be
691 ** updated by its technote id
692 **
693 ** One of PAGENAME, DATETIME or TECHNOTE-ID must be specified.
694 **
695 ** DATETIME may be "now" or "YYYY-MM-DDTHH:MM:SS.SSS". If in
696 ** year-month-day form, it may be truncated, the "T" may be replaced by
@@ -792,12 +791,11 @@
791 ** name arguments are glob prefixes for the attachment.target
792 ** field. If no names are provided then a prefix of [a-zA-Z] is used,
793 ** which will match most wiki page names and some ticket hashes.
794 **
795 ** Options:
796 ** -latest List only the latest version of a given attachment
 
797 **
798 */
799 void test_list_attachments(void){
800 Stmt q;
801 int i;
802
+1 -1
--- src/backlink.c
+++ src/backlink.c
@@ -358,11 +358,11 @@
358358
** just print them on stdout. SRCID and SRCTYPE are integers.
359359
**
360360
** Options:
361361
** --mtime DATETIME Use an alternative date/time. Defaults to the
362362
** current date/time.
363
-** --mimetype TYPE Use an alternative mimetype.
363
+** --mimetype TYPE Use an alternative mimetype
364364
*/
365365
void test_backlinks_cmd(void){
366366
const char *zMTime = find_option("mtime",0,1);
367367
const char *zMimetype = find_option("mimetype",0,1);
368368
const int mimetype = parse_mimetype(zMimetype);
369369
--- src/backlink.c
+++ src/backlink.c
@@ -358,11 +358,11 @@
358 ** just print them on stdout. SRCID and SRCTYPE are integers.
359 **
360 ** Options:
361 ** --mtime DATETIME Use an alternative date/time. Defaults to the
362 ** current date/time.
363 ** --mimetype TYPE Use an alternative mimetype.
364 */
365 void test_backlinks_cmd(void){
366 const char *zMTime = find_option("mtime",0,1);
367 const char *zMimetype = find_option("mimetype",0,1);
368 const int mimetype = parse_mimetype(zMimetype);
369
--- src/backlink.c
+++ src/backlink.c
@@ -358,11 +358,11 @@
358 ** just print them on stdout. SRCID and SRCTYPE are integers.
359 **
360 ** Options:
361 ** --mtime DATETIME Use an alternative date/time. Defaults to the
362 ** current date/time.
363 ** --mimetype TYPE Use an alternative mimetype
364 */
365 void test_backlinks_cmd(void){
366 const char *zMTime = find_option("mtime",0,1);
367 const char *zMimetype = find_option("mimetype",0,1);
368 const int mimetype = parse_mimetype(zMimetype);
369
+3 -2
--- src/bisect.c
+++ src/bisect.c
@@ -386,12 +386,12 @@
386386
387387
/*
388388
** fossil bisect run [OPTIONS] COMMAND
389389
**
390390
** Invoke COMMAND (with arguments) repeatedly to perform the bisect.
391
-** Options:
392391
**
392
+** Options:
393393
** -i|--interactive Prompt user for decisions rather than
394394
** using the return code from COMMAND
395395
*/
396396
static void bisect_run(void){
397397
const char *zCmd;
@@ -507,12 +507,13 @@
507507
**
508508
** > fossil bisect run [OPTIONS] COMMAND
509509
**
510510
** Invoke COMMAND repeatedly to run the bisect. The exit code for
511511
** COMMAND should be 0 for "good", 125 for "skip", and any other value
512
-** for "bad". Options:
512
+** for "bad".
513513
**
514
+** Options:
514515
** -i|--interactive Prompt the user for the good/bad/skip decision
515516
** after each step, rather than using the exit
516517
** code from COMMAND
517518
**
518519
** > fossil bisect skip ?VERSION?
519520
--- src/bisect.c
+++ src/bisect.c
@@ -386,12 +386,12 @@
386
387 /*
388 ** fossil bisect run [OPTIONS] COMMAND
389 **
390 ** Invoke COMMAND (with arguments) repeatedly to perform the bisect.
391 ** Options:
392 **
 
393 ** -i|--interactive Prompt user for decisions rather than
394 ** using the return code from COMMAND
395 */
396 static void bisect_run(void){
397 const char *zCmd;
@@ -507,12 +507,13 @@
507 **
508 ** > fossil bisect run [OPTIONS] COMMAND
509 **
510 ** Invoke COMMAND repeatedly to run the bisect. The exit code for
511 ** COMMAND should be 0 for "good", 125 for "skip", and any other value
512 ** for "bad". Options:
513 **
 
514 ** -i|--interactive Prompt the user for the good/bad/skip decision
515 ** after each step, rather than using the exit
516 ** code from COMMAND
517 **
518 ** > fossil bisect skip ?VERSION?
519
--- src/bisect.c
+++ src/bisect.c
@@ -386,12 +386,12 @@
386
387 /*
388 ** fossil bisect run [OPTIONS] COMMAND
389 **
390 ** Invoke COMMAND (with arguments) repeatedly to perform the bisect.
 
391 **
392 ** Options:
393 ** -i|--interactive Prompt user for decisions rather than
394 ** using the return code from COMMAND
395 */
396 static void bisect_run(void){
397 const char *zCmd;
@@ -507,12 +507,13 @@
507 **
508 ** > fossil bisect run [OPTIONS] COMMAND
509 **
510 ** Invoke COMMAND repeatedly to run the bisect. The exit code for
511 ** COMMAND should be 0 for "good", 125 for "skip", and any other value
512 ** for "bad".
513 **
514 ** Options:
515 ** -i|--interactive Prompt the user for the good/bad/skip decision
516 ** after each step, rather than using the exit
517 ** code from COMMAND
518 **
519 ** > fossil bisect skip ?VERSION?
520
+1
--- src/blob.c
+++ src/blob.c
@@ -124,10 +124,11 @@
124124
** Other replacements for ctype.h functions.
125125
*/
126126
int fossil_islower(char c){ return c>='a' && c<='z'; }
127127
int fossil_isupper(char c){ return c>='A' && c<='Z'; }
128128
int fossil_isdigit(char c){ return c>='0' && c<='9'; }
129
+int fossil_isxdigit(char c){ return (c>='0' && c<='9') || (c>='a' && c<='f'); }
129130
int fossil_tolower(char c){
130131
return fossil_isupper(c) ? c - 'A' + 'a' : c;
131132
}
132133
int fossil_toupper(char c){
133134
return fossil_islower(c) ? c - 'a' + 'A' : c;
134135
--- src/blob.c
+++ src/blob.c
@@ -124,10 +124,11 @@
124 ** Other replacements for ctype.h functions.
125 */
126 int fossil_islower(char c){ return c>='a' && c<='z'; }
127 int fossil_isupper(char c){ return c>='A' && c<='Z'; }
128 int fossil_isdigit(char c){ return c>='0' && c<='9'; }
 
129 int fossil_tolower(char c){
130 return fossil_isupper(c) ? c - 'A' + 'a' : c;
131 }
132 int fossil_toupper(char c){
133 return fossil_islower(c) ? c - 'a' + 'A' : c;
134
--- src/blob.c
+++ src/blob.c
@@ -124,10 +124,11 @@
124 ** Other replacements for ctype.h functions.
125 */
126 int fossil_islower(char c){ return c>='a' && c<='z'; }
127 int fossil_isupper(char c){ return c>='A' && c<='Z'; }
128 int fossil_isdigit(char c){ return c>='0' && c<='9'; }
129 int fossil_isxdigit(char c){ return (c>='0' && c<='9') || (c>='a' && c<='f'); }
130 int fossil_tolower(char c){
131 return fossil_isupper(c) ? c - 'A' + 'a' : c;
132 }
133 int fossil_toupper(char c){
134 return fossil_islower(c) ? c - 'a' + 'A' : c;
135
+16 -12
--- src/branch.c
+++ src/branch.c
@@ -586,14 +586,16 @@
586586
** > fossil branch close|reopen ?OPTIONS? BRANCH-NAME ?...BRANCH-NAMES?
587587
**
588588
** Adds or cancels the "closed" tag to one or more branches.
589589
** It accepts arbitrary unambiguous symbolic names but
590590
** will only resolve check-in names and skips any which resolve
591
-** to non-leaf check-ins. Options:
592
-** -n|--dry-run do not commit changes and dump artifact
591
+** to non-leaf check-ins.
592
+**
593
+** Options:
594
+** -n|--dry-run Do not commit changes, but dump artifact
593595
** to stdout
594
-** -v|--verbose output more information
596
+** -v|--verbose Output more information
595597
** --date-override DATE DATE to use instead of 'now'
596598
** --user-override USER USER to use instead of the current default
597599
**
598600
** > fossil branch current
599601
**
@@ -610,14 +612,16 @@
610612
** Print information about a branch
611613
**
612614
** > fossil branch list|ls ?OPTIONS? ?GLOB?
613615
** > fossil branch lsh ?OPTIONS? ?LIMIT?
614616
**
615
-** List all branches. Options:
617
+** List all branches.
618
+**
619
+** Options:
616620
** -a|--all List all branches. Default show only open branches
617
-** -c|--closed List closed branches.
618
-** -p List only private branches.
621
+** -c|--closed List closed branches
622
+** -p List only private branches
619623
** -r Reverse the sort order
620624
** -t Show recently changed branches first
621625
**
622626
** The current branch is marked with an asterisk. Private branches are
623627
** marked with a hash sign.
@@ -630,27 +634,27 @@
630634
** an implied no-op.
631635
**
632636
** > fossil branch new BRANCH-NAME BASIS ?OPTIONS?
633637
**
634638
** Create a new branch BRANCH-NAME off of check-in BASIS.
635
-** Supported options for this subcommand include:
636
-** --private branch is private (i.e., remains local)
637
-** --bgcolor COLOR use COLOR instead of automatic background
639
+**
640
+** Options:
641
+** --private Branch is private (i.e., remains local)
642
+** --bgcolor COLOR Use COLOR instead of automatic background
638643
** ("auto" lets Fossil choose it automatically,
639644
** even for private branches)
640
-** --nosign do not sign contents on this branch
645
+** --nosign Do not sign contents on this branch
641646
** --date-override DATE DATE to use instead of 'now'
642647
** --user-override USER USER to use instead of the current default
643648
**
644649
** DATE may be "now" or "YYYY-MM-DDTHH:MM:SS.SSS". If in
645650
** year-month-day form, it may be truncated, the "T" may be
646651
** replaced by a space, and it may also name a timezone offset
647652
** from UTC as "-HH:MM" (westward) or "+HH:MM" (eastward).
648653
** Either no timezone suffix or "Z" means UTC.
649654
**
650
-** Options valid for all subcommands:
651
-**
655
+** Options:
652656
** -R|--repository REPO Run commands on repository REPO
653657
*/
654658
void branch_cmd(void){
655659
int n;
656660
const char *zCmd = "list";
657661
--- src/branch.c
+++ src/branch.c
@@ -586,14 +586,16 @@
586 ** > fossil branch close|reopen ?OPTIONS? BRANCH-NAME ?...BRANCH-NAMES?
587 **
588 ** Adds or cancels the "closed" tag to one or more branches.
589 ** It accepts arbitrary unambiguous symbolic names but
590 ** will only resolve check-in names and skips any which resolve
591 ** to non-leaf check-ins. Options:
592 ** -n|--dry-run do not commit changes and dump artifact
 
 
593 ** to stdout
594 ** -v|--verbose output more information
595 ** --date-override DATE DATE to use instead of 'now'
596 ** --user-override USER USER to use instead of the current default
597 **
598 ** > fossil branch current
599 **
@@ -610,14 +612,16 @@
610 ** Print information about a branch
611 **
612 ** > fossil branch list|ls ?OPTIONS? ?GLOB?
613 ** > fossil branch lsh ?OPTIONS? ?LIMIT?
614 **
615 ** List all branches. Options:
 
 
616 ** -a|--all List all branches. Default show only open branches
617 ** -c|--closed List closed branches.
618 ** -p List only private branches.
619 ** -r Reverse the sort order
620 ** -t Show recently changed branches first
621 **
622 ** The current branch is marked with an asterisk. Private branches are
623 ** marked with a hash sign.
@@ -630,27 +634,27 @@
630 ** an implied no-op.
631 **
632 ** > fossil branch new BRANCH-NAME BASIS ?OPTIONS?
633 **
634 ** Create a new branch BRANCH-NAME off of check-in BASIS.
635 ** Supported options for this subcommand include:
636 ** --private branch is private (i.e., remains local)
637 ** --bgcolor COLOR use COLOR instead of automatic background
 
638 ** ("auto" lets Fossil choose it automatically,
639 ** even for private branches)
640 ** --nosign do not sign contents on this branch
641 ** --date-override DATE DATE to use instead of 'now'
642 ** --user-override USER USER to use instead of the current default
643 **
644 ** DATE may be "now" or "YYYY-MM-DDTHH:MM:SS.SSS". If in
645 ** year-month-day form, it may be truncated, the "T" may be
646 ** replaced by a space, and it may also name a timezone offset
647 ** from UTC as "-HH:MM" (westward) or "+HH:MM" (eastward).
648 ** Either no timezone suffix or "Z" means UTC.
649 **
650 ** Options valid for all subcommands:
651 **
652 ** -R|--repository REPO Run commands on repository REPO
653 */
654 void branch_cmd(void){
655 int n;
656 const char *zCmd = "list";
657
--- src/branch.c
+++ src/branch.c
@@ -586,14 +586,16 @@
586 ** > fossil branch close|reopen ?OPTIONS? BRANCH-NAME ?...BRANCH-NAMES?
587 **
588 ** Adds or cancels the "closed" tag to one or more branches.
589 ** It accepts arbitrary unambiguous symbolic names but
590 ** will only resolve check-in names and skips any which resolve
591 ** to non-leaf check-ins.
592 **
593 ** Options:
594 ** -n|--dry-run Do not commit changes, but dump artifact
595 ** to stdout
596 ** -v|--verbose Output more information
597 ** --date-override DATE DATE to use instead of 'now'
598 ** --user-override USER USER to use instead of the current default
599 **
600 ** > fossil branch current
601 **
@@ -610,14 +612,16 @@
612 ** Print information about a branch
613 **
614 ** > fossil branch list|ls ?OPTIONS? ?GLOB?
615 ** > fossil branch lsh ?OPTIONS? ?LIMIT?
616 **
617 ** List all branches.
618 **
619 ** Options:
620 ** -a|--all List all branches. Default show only open branches
621 ** -c|--closed List closed branches
622 ** -p List only private branches
623 ** -r Reverse the sort order
624 ** -t Show recently changed branches first
625 **
626 ** The current branch is marked with an asterisk. Private branches are
627 ** marked with a hash sign.
@@ -630,27 +634,27 @@
634 ** an implied no-op.
635 **
636 ** > fossil branch new BRANCH-NAME BASIS ?OPTIONS?
637 **
638 ** Create a new branch BRANCH-NAME off of check-in BASIS.
639 **
640 ** Options:
641 ** --private Branch is private (i.e., remains local)
642 ** --bgcolor COLOR Use COLOR instead of automatic background
643 ** ("auto" lets Fossil choose it automatically,
644 ** even for private branches)
645 ** --nosign Do not sign contents on this branch
646 ** --date-override DATE DATE to use instead of 'now'
647 ** --user-override USER USER to use instead of the current default
648 **
649 ** DATE may be "now" or "YYYY-MM-DDTHH:MM:SS.SSS". If in
650 ** year-month-day form, it may be truncated, the "T" may be
651 ** replaced by a space, and it may also name a timezone offset
652 ** from UTC as "-HH:MM" (westward) or "+HH:MM" (eastward).
653 ** Either no timezone suffix or "Z" means UTC.
654 **
655 ** Options:
 
656 ** -R|--repository REPO Run commands on repository REPO
657 */
658 void branch_cmd(void){
659 int n;
660 const char *zCmd = "list";
661
+1 -1
--- src/checkout.c
+++ src/checkout.c
@@ -397,11 +397,11 @@
397397
** The opposite of "[[open]]". Close the current database connection.
398398
** Require a -f or --force flag if there are unsaved changes in the
399399
** current check-out or if there is non-empty stash.
400400
**
401401
** Options:
402
-** -f|--force necessary to close a check-out with uncommitted changes
402
+** -f|--force Necessary to close a check-out with uncommitted changes
403403
**
404404
** See also: [[open]]
405405
*/
406406
void close_cmd(void){
407407
int forceFlag = find_option("force","f",0)!=0;
408408
--- src/checkout.c
+++ src/checkout.c
@@ -397,11 +397,11 @@
397 ** The opposite of "[[open]]". Close the current database connection.
398 ** Require a -f or --force flag if there are unsaved changes in the
399 ** current check-out or if there is non-empty stash.
400 **
401 ** Options:
402 ** -f|--force necessary to close a check-out with uncommitted changes
403 **
404 ** See also: [[open]]
405 */
406 void close_cmd(void){
407 int forceFlag = find_option("force","f",0)!=0;
408
--- src/checkout.c
+++ src/checkout.c
@@ -397,11 +397,11 @@
397 ** The opposite of "[[open]]". Close the current database connection.
398 ** Require a -f or --force flag if there are unsaved changes in the
399 ** current check-out or if there is non-empty stash.
400 **
401 ** Options:
402 ** -f|--force Necessary to close a check-out with uncommitted changes
403 **
404 ** See also: [[open]]
405 */
406 void close_cmd(void){
407 int forceFlag = find_option("force","f",0)!=0;
408
+1 -1
--- src/clone.c
+++ src/clone.c
@@ -130,11 +130,11 @@
130130
** --nocompress Omit extra delta compression
131131
** --no-open Clone only. Do not open a check-out.
132132
** --once Don't remember the URI.
133133
** --private Also clone private branches
134134
** --save-http-password Remember the HTTP password without asking
135
-** --ssh-command|-c SSH Use SSH as the "ssh" command
135
+** -c|--ssh-command SSH Use SSH as the "ssh" command
136136
** --ssl-identity FILENAME Use the SSL identity if requested by the server
137137
** --transport-command CMD Use CMD to move messages to the server and back
138138
** -u|--unversioned Also sync unversioned content
139139
** -v|--verbose Show more statistics in output
140140
** --workdir DIR Also open a check-out in DIR
141141
--- src/clone.c
+++ src/clone.c
@@ -130,11 +130,11 @@
130 ** --nocompress Omit extra delta compression
131 ** --no-open Clone only. Do not open a check-out.
132 ** --once Don't remember the URI.
133 ** --private Also clone private branches
134 ** --save-http-password Remember the HTTP password without asking
135 ** --ssh-command|-c SSH Use SSH as the "ssh" command
136 ** --ssl-identity FILENAME Use the SSL identity if requested by the server
137 ** --transport-command CMD Use CMD to move messages to the server and back
138 ** -u|--unversioned Also sync unversioned content
139 ** -v|--verbose Show more statistics in output
140 ** --workdir DIR Also open a check-out in DIR
141
--- src/clone.c
+++ src/clone.c
@@ -130,11 +130,11 @@
130 ** --nocompress Omit extra delta compression
131 ** --no-open Clone only. Do not open a check-out.
132 ** --once Don't remember the URI.
133 ** --private Also clone private branches
134 ** --save-http-password Remember the HTTP password without asking
135 ** -c|--ssh-command SSH Use SSH as the "ssh" command
136 ** --ssl-identity FILENAME Use the SSL identity if requested by the server
137 ** --transport-command CMD Use CMD to move messages to the server and back
138 ** -u|--unversioned Also sync unversioned content
139 ** -v|--verbose Show more statistics in output
140 ** --workdir DIR Also open a check-out in DIR
141
+6 -6
--- src/comformat.c
+++ src/comformat.c
@@ -546,19 +546,19 @@
546546
**
547547
** Test comment formatting and printing. Use for testing only.
548548
**
549549
** Options:
550550
** --file The comment text is really just a file name to
551
-** read it from.
551
+** read it from
552552
** --decode Decode the text using the same method used when
553553
** handling the value of a C-card from a manifest.
554
-** --legacy Use the legacy comment printing algorithm.
555
-** --trimcrlf Enable trimming of leading/trailing CR/LF.
556
-** --trimspace Enable trimming of leading/trailing spaces.
557
-** --wordbreak Attempt to break lines on word boundaries.
554
+** --legacy Use the legacy comment printing algorithm
555
+** --trimcrlf Enable trimming of leading/trailing CR/LF
556
+** --trimspace Enable trimming of leading/trailing spaces
557
+** --wordbreak Attempt to break lines on word boundaries
558558
** --origbreak Attempt to break when the original comment text
559
-** is detected.
559
+** is detected
560560
** --indent Number of spaces to indent (default (-1) is to
561561
** auto-detect). Zero means no indent.
562562
** -W|--width NUM Width of lines (default (-1) is to auto-detect).
563563
** Zero means no limit.
564564
*/
565565
--- src/comformat.c
+++ src/comformat.c
@@ -546,19 +546,19 @@
546 **
547 ** Test comment formatting and printing. Use for testing only.
548 **
549 ** Options:
550 ** --file The comment text is really just a file name to
551 ** read it from.
552 ** --decode Decode the text using the same method used when
553 ** handling the value of a C-card from a manifest.
554 ** --legacy Use the legacy comment printing algorithm.
555 ** --trimcrlf Enable trimming of leading/trailing CR/LF.
556 ** --trimspace Enable trimming of leading/trailing spaces.
557 ** --wordbreak Attempt to break lines on word boundaries.
558 ** --origbreak Attempt to break when the original comment text
559 ** is detected.
560 ** --indent Number of spaces to indent (default (-1) is to
561 ** auto-detect). Zero means no indent.
562 ** -W|--width NUM Width of lines (default (-1) is to auto-detect).
563 ** Zero means no limit.
564 */
565
--- src/comformat.c
+++ src/comformat.c
@@ -546,19 +546,19 @@
546 **
547 ** Test comment formatting and printing. Use for testing only.
548 **
549 ** Options:
550 ** --file The comment text is really just a file name to
551 ** read it from
552 ** --decode Decode the text using the same method used when
553 ** handling the value of a C-card from a manifest.
554 ** --legacy Use the legacy comment printing algorithm
555 ** --trimcrlf Enable trimming of leading/trailing CR/LF
556 ** --trimspace Enable trimming of leading/trailing spaces
557 ** --wordbreak Attempt to break lines on word boundaries
558 ** --origbreak Attempt to break when the original comment text
559 ** is detected
560 ** --indent Number of spaces to indent (default (-1) is to
561 ** auto-detect). Zero means no indent.
562 ** -W|--width NUM Width of lines (default (-1) is to auto-detect).
563 ** Zero means no limit.
564 */
565
--- src/content.c
+++ src/content.c
@@ -957,17 +957,14 @@
957957
** Verify that all content can be extracted from the BLOB table correctly.
958958
** If the BLOB table is correct, then the repository can always be
959959
** successfully reconstructed using "fossil rebuild".
960960
**
961961
** Options:
962
-**
963962
** -d|--db-only Run "PRAGMA integrity_check" on the database only.
964963
** No other validation is performed.
965
-**
966964
** --parse Parse all manifests, wikis, tickets, events, and
967965
** so forth, reporting any errors found.
968
-**
969966
** -q|--quick Run "PRAGMA quick_check" on the database only.
970967
** No other validation is performed.
971968
*/
972969
void test_integrity(void){
973970
Stmt q;
@@ -1197,11 +1194,10 @@
11971194
** Look at every artifact in the repository and verify that
11981195
** all references are satisfied. Report any referenced artifacts
11991196
** that are missing or shunned.
12001197
**
12011198
** Options:
1202
-**
12031199
** --notshunned Do not report shunned artifacts
12041200
** --quiet Only show output if there are errors
12051201
*/
12061202
void test_missing(void){
12071203
Stmt q;
12081204
--- src/content.c
+++ src/content.c
@@ -957,17 +957,14 @@
957 ** Verify that all content can be extracted from the BLOB table correctly.
958 ** If the BLOB table is correct, then the repository can always be
959 ** successfully reconstructed using "fossil rebuild".
960 **
961 ** Options:
962 **
963 ** -d|--db-only Run "PRAGMA integrity_check" on the database only.
964 ** No other validation is performed.
965 **
966 ** --parse Parse all manifests, wikis, tickets, events, and
967 ** so forth, reporting any errors found.
968 **
969 ** -q|--quick Run "PRAGMA quick_check" on the database only.
970 ** No other validation is performed.
971 */
972 void test_integrity(void){
973 Stmt q;
@@ -1197,11 +1194,10 @@
1197 ** Look at every artifact in the repository and verify that
1198 ** all references are satisfied. Report any referenced artifacts
1199 ** that are missing or shunned.
1200 **
1201 ** Options:
1202 **
1203 ** --notshunned Do not report shunned artifacts
1204 ** --quiet Only show output if there are errors
1205 */
1206 void test_missing(void){
1207 Stmt q;
1208
--- src/content.c
+++ src/content.c
@@ -957,17 +957,14 @@
957 ** Verify that all content can be extracted from the BLOB table correctly.
958 ** If the BLOB table is correct, then the repository can always be
959 ** successfully reconstructed using "fossil rebuild".
960 **
961 ** Options:
 
962 ** -d|--db-only Run "PRAGMA integrity_check" on the database only.
963 ** No other validation is performed.
 
964 ** --parse Parse all manifests, wikis, tickets, events, and
965 ** so forth, reporting any errors found.
 
966 ** -q|--quick Run "PRAGMA quick_check" on the database only.
967 ** No other validation is performed.
968 */
969 void test_integrity(void){
970 Stmt q;
@@ -1197,11 +1194,10 @@
1194 ** Look at every artifact in the repository and verify that
1195 ** all references are satisfied. Report any referenced artifacts
1196 ** that are missing or shunned.
1197 **
1198 ** Options:
 
1199 ** --notshunned Do not report shunned artifacts
1200 ** --quiet Only show output if there are errors
1201 */
1202 void test_missing(void){
1203 Stmt q;
1204
+14 -8
--- src/db.c
+++ src/db.c
@@ -917,13 +917,12 @@
917917
/*
918918
** COMMAND: test-db-prepare
919919
** Usage: %fossil test-db-prepare ?OPTIONS? SQL-STATEMENT
920920
**
921921
** Options:
922
-**
923
-** --auth-report Enable the ticket report query authorizer.
924
-** --auth-ticket Enable the ticket schema query authorizer.
922
+** --auth-report Enable the ticket report query authorizer
923
+** --auth-ticket Enable the ticket schema query authorizer
925924
**
926925
** Invoke db_prepare() on the SQL input. Report any errors encountered.
927926
** This command is used to verify error detection logic in the db_prepare()
928927
** utility routine.
929928
*/
@@ -4456,13 +4455,14 @@
44564455
** SETTING: pgp-command width=40 sensitive
44574456
** Command used to clear-sign manifests at check-in.
44584457
** Default value is "gpg --clearsign -o"
44594458
*/
44604459
/*
4461
-** SETTING: proxy width=32 default=off
4462
-** URL of the HTTP proxy. If "system", the "http_proxy" environment variable is
4463
-** consulted. If undefined or "off", a direct HTTP connection is used.
4460
+** SETTING: proxy width=32 default=system
4461
+** URL of the HTTP proxy. If undefined or "system", the "http_proxy"
4462
+** environment variable is consulted. If "off", a direct HTTP connection is
4463
+** used.
44644464
*/
44654465
/*
44664466
** SETTING: redirect-to-https default=0 width=-1
44674467
** Specifies whether or not to redirect http:// requests to
44684468
** https:// URIs. A value of 0 (the default) means not to
@@ -4499,10 +4499,17 @@
44994499
** displayed using unadorned HTML ("skinless").
45004500
**
45014501
** If repolist-skin has a value of 2, then the repository is omitted from
45024502
** the list in use cases 1 through 4, but not for 5 and 6.
45034503
*/
4504
+/*
4505
+** SETTING: self-pw-reset boolean default=off sensitive
4506
+** Allow users to request that an email containing a hyperlink
4507
+** to the /resetpw page be sent to their email address of record,
4508
+** thus allowing forgetful users to reset their forgotten passwords
4509
+** without administrator involvement.
4510
+*/
45044511
/*
45054512
** SETTING: self-register boolean default=off sensitive
45064513
** Allow users to register themselves through the HTTP UI.
45074514
** This is useful if you want to see other names than
45084515
** "Anonymous" in e.g. ticketing system. On the other hand
@@ -4694,11 +4701,10 @@
46944701
** on the local settings. Use the --global option to change global settings.
46954702
**
46964703
** Options:
46974704
** --global Set or unset the given property globally instead of
46984705
** setting or unsetting it for the open repository only
4699
-**
47004706
** --exact Only consider exact name matches
47014707
**
47024708
** See also: [[configuration]]
47034709
*/
47044710
void setting_cmd(void){
@@ -4848,11 +4854,11 @@
48484854
**
48494855
** The purpose of this command is for testing the WITHOUT ROWID capabilities
48504856
** of SQLite. There is no big advantage to using WITHOUT ROWID in Fossil.
48514857
**
48524858
** Options:
4853
-** --dry-run | -n No changes. Just print what would happen.
4859
+** -n|--dry-run No changes. Just print what would happen.
48544860
*/
48554861
void test_without_rowid(void){
48564862
int i, j;
48574863
Stmt q;
48584864
Blob allSql;
48594865
--- src/db.c
+++ src/db.c
@@ -917,13 +917,12 @@
917 /*
918 ** COMMAND: test-db-prepare
919 ** Usage: %fossil test-db-prepare ?OPTIONS? SQL-STATEMENT
920 **
921 ** Options:
922 **
923 ** --auth-report Enable the ticket report query authorizer.
924 ** --auth-ticket Enable the ticket schema query authorizer.
925 **
926 ** Invoke db_prepare() on the SQL input. Report any errors encountered.
927 ** This command is used to verify error detection logic in the db_prepare()
928 ** utility routine.
929 */
@@ -4456,13 +4455,14 @@
4456 ** SETTING: pgp-command width=40 sensitive
4457 ** Command used to clear-sign manifests at check-in.
4458 ** Default value is "gpg --clearsign -o"
4459 */
4460 /*
4461 ** SETTING: proxy width=32 default=off
4462 ** URL of the HTTP proxy. If "system", the "http_proxy" environment variable is
4463 ** consulted. If undefined or "off", a direct HTTP connection is used.
 
4464 */
4465 /*
4466 ** SETTING: redirect-to-https default=0 width=-1
4467 ** Specifies whether or not to redirect http:// requests to
4468 ** https:// URIs. A value of 0 (the default) means not to
@@ -4499,10 +4499,17 @@
4499 ** displayed using unadorned HTML ("skinless").
4500 **
4501 ** If repolist-skin has a value of 2, then the repository is omitted from
4502 ** the list in use cases 1 through 4, but not for 5 and 6.
4503 */
 
 
 
 
 
 
 
4504 /*
4505 ** SETTING: self-register boolean default=off sensitive
4506 ** Allow users to register themselves through the HTTP UI.
4507 ** This is useful if you want to see other names than
4508 ** "Anonymous" in e.g. ticketing system. On the other hand
@@ -4694,11 +4701,10 @@
4694 ** on the local settings. Use the --global option to change global settings.
4695 **
4696 ** Options:
4697 ** --global Set or unset the given property globally instead of
4698 ** setting or unsetting it for the open repository only
4699 **
4700 ** --exact Only consider exact name matches
4701 **
4702 ** See also: [[configuration]]
4703 */
4704 void setting_cmd(void){
@@ -4848,11 +4854,11 @@
4848 **
4849 ** The purpose of this command is for testing the WITHOUT ROWID capabilities
4850 ** of SQLite. There is no big advantage to using WITHOUT ROWID in Fossil.
4851 **
4852 ** Options:
4853 ** --dry-run | -n No changes. Just print what would happen.
4854 */
4855 void test_without_rowid(void){
4856 int i, j;
4857 Stmt q;
4858 Blob allSql;
4859
--- src/db.c
+++ src/db.c
@@ -917,13 +917,12 @@
917 /*
918 ** COMMAND: test-db-prepare
919 ** Usage: %fossil test-db-prepare ?OPTIONS? SQL-STATEMENT
920 **
921 ** Options:
922 ** --auth-report Enable the ticket report query authorizer
923 ** --auth-ticket Enable the ticket schema query authorizer
 
924 **
925 ** Invoke db_prepare() on the SQL input. Report any errors encountered.
926 ** This command is used to verify error detection logic in the db_prepare()
927 ** utility routine.
928 */
@@ -4456,13 +4455,14 @@
4455 ** SETTING: pgp-command width=40 sensitive
4456 ** Command used to clear-sign manifests at check-in.
4457 ** Default value is "gpg --clearsign -o"
4458 */
4459 /*
4460 ** SETTING: proxy width=32 default=system
4461 ** URL of the HTTP proxy. If undefined or "system", the "http_proxy"
4462 ** environment variable is consulted. If "off", a direct HTTP connection is
4463 ** used.
4464 */
4465 /*
4466 ** SETTING: redirect-to-https default=0 width=-1
4467 ** Specifies whether or not to redirect http:// requests to
4468 ** https:// URIs. A value of 0 (the default) means not to
@@ -4499,10 +4499,17 @@
4499 ** displayed using unadorned HTML ("skinless").
4500 **
4501 ** If repolist-skin has a value of 2, then the repository is omitted from
4502 ** the list in use cases 1 through 4, but not for 5 and 6.
4503 */
4504 /*
4505 ** SETTING: self-pw-reset boolean default=off sensitive
4506 ** Allow users to request that an email containing a hyperlink
4507 ** to the /resetpw page be sent to their email address of record,
4508 ** thus allowing forgetful users to reset their forgotten passwords
4509 ** without administrator involvement.
4510 */
4511 /*
4512 ** SETTING: self-register boolean default=off sensitive
4513 ** Allow users to register themselves through the HTTP UI.
4514 ** This is useful if you want to see other names than
4515 ** "Anonymous" in e.g. ticketing system. On the other hand
@@ -4694,11 +4701,10 @@
4701 ** on the local settings. Use the --global option to change global settings.
4702 **
4703 ** Options:
4704 ** --global Set or unset the given property globally instead of
4705 ** setting or unsetting it for the open repository only
 
4706 ** --exact Only consider exact name matches
4707 **
4708 ** See also: [[configuration]]
4709 */
4710 void setting_cmd(void){
@@ -4848,11 +4854,11 @@
4854 **
4855 ** The purpose of this command is for testing the WITHOUT ROWID capabilities
4856 ** of SQLite. There is no big advantage to using WITHOUT ROWID in Fossil.
4857 **
4858 ** Options:
4859 ** -n|--dry-run No changes. Just print what would happen.
4860 */
4861 void test_without_rowid(void){
4862 int i, j;
4863 Stmt q;
4864 Blob allSql;
4865
+5 -5
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1042,31 +1042,31 @@
10421042
** -b Show a linear diff in the default web browser
10431043
** -y Show a text side-by-side diff
10441044
** --webpage Format output as HTML
10451045
** --webpage -y HTML output in the side-by-side format
10461046
**
1047
-** The "--from VERSION" option is used it specifies the source check-in
1047
+** The "--from VERSION" option is used to specify the source check-in
10481048
** for the diff operation. If not specified, the source check-in is the
10491049
** base check-in for the current check-out. Similarly, the "--to VERSION"
10501050
** option specifies the check-in from which the second version of the file
10511051
** or files is taken. If there is no "--to" option then the (possibly edited)
10521052
** files in the current check-out are used. The "--checkin VERSION" option
10531053
** shows the changes made by check-in VERSION relative to its primary parent.
10541054
** The "--branch BRANCHNAME" shows all the changes on the branch BRANCHNAME.
10551055
**
1056
-** The "-i" command-line option forces the use of Fossils own the internal
1056
+** The "-i" command-line option forces the use of Fossil's own internal
10571057
** diff logic rather than any external diff program that might be configured
10581058
** using the "setting" command. If no external diff program is configured,
10591059
** then the "-i" option is a no-op. The "-i" option converts "gdiff" into
10601060
** "diff".
10611061
**
10621062
** The "--diff-binary" option enables or disables the inclusion of binary files
10631063
** when using an external diff program.
10641064
**
10651065
** The "--binary" option causes files matching the glob PATTERN to be treated
1066
-** as binary when considering if they should be used with external diff program.
1067
-** This option overrides the "binary-glob" setting.
1066
+** as binary when considering if they should be used with the external diff
1067
+** program. This option overrides the "binary-glob" setting.
10681068
**
10691069
** These command show differences between managed files. Use the "fossil xdiff"
10701070
** command to see differences in unmanaged files.
10711071
**
10721072
** Options:
@@ -1085,11 +1085,11 @@
10851085
** -r|--from VERSION Select VERSION as source for the diff
10861086
** -w|--ignore-all-space Ignore white space when comparing lines
10871087
** -i|--internal Use internal diff logic
10881088
** --json Output formatted as JSON
10891089
** -N|--new-file Alias for --verbose
1090
-** --numstat Show only the number of lines delete and added
1090
+** --numstat Show only the number of added and deleted lines
10911091
** -y|--side-by-side Side-by-side diff
10921092
** --strip-trailing-cr Strip trailing CR
10931093
** --tcl TCL-formated output used internally by --tk
10941094
** --tclsh PATH TCL/TK used for --tk (default: "tclsh")
10951095
** --tk Launch a Tcl/Tk GUI for display
10961096
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1042,31 +1042,31 @@
1042 ** -b Show a linear diff in the default web browser
1043 ** -y Show a text side-by-side diff
1044 ** --webpage Format output as HTML
1045 ** --webpage -y HTML output in the side-by-side format
1046 **
1047 ** The "--from VERSION" option is used it specifies the source check-in
1048 ** for the diff operation. If not specified, the source check-in is the
1049 ** base check-in for the current check-out. Similarly, the "--to VERSION"
1050 ** option specifies the check-in from which the second version of the file
1051 ** or files is taken. If there is no "--to" option then the (possibly edited)
1052 ** files in the current check-out are used. The "--checkin VERSION" option
1053 ** shows the changes made by check-in VERSION relative to its primary parent.
1054 ** The "--branch BRANCHNAME" shows all the changes on the branch BRANCHNAME.
1055 **
1056 ** The "-i" command-line option forces the use of Fossils own the internal
1057 ** diff logic rather than any external diff program that might be configured
1058 ** using the "setting" command. If no external diff program is configured,
1059 ** then the "-i" option is a no-op. The "-i" option converts "gdiff" into
1060 ** "diff".
1061 **
1062 ** The "--diff-binary" option enables or disables the inclusion of binary files
1063 ** when using an external diff program.
1064 **
1065 ** The "--binary" option causes files matching the glob PATTERN to be treated
1066 ** as binary when considering if they should be used with external diff program.
1067 ** This option overrides the "binary-glob" setting.
1068 **
1069 ** These command show differences between managed files. Use the "fossil xdiff"
1070 ** command to see differences in unmanaged files.
1071 **
1072 ** Options:
@@ -1085,11 +1085,11 @@
1085 ** -r|--from VERSION Select VERSION as source for the diff
1086 ** -w|--ignore-all-space Ignore white space when comparing lines
1087 ** -i|--internal Use internal diff logic
1088 ** --json Output formatted as JSON
1089 ** -N|--new-file Alias for --verbose
1090 ** --numstat Show only the number of lines delete and added
1091 ** -y|--side-by-side Side-by-side diff
1092 ** --strip-trailing-cr Strip trailing CR
1093 ** --tcl TCL-formated output used internally by --tk
1094 ** --tclsh PATH TCL/TK used for --tk (default: "tclsh")
1095 ** --tk Launch a Tcl/Tk GUI for display
1096
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -1042,31 +1042,31 @@
1042 ** -b Show a linear diff in the default web browser
1043 ** -y Show a text side-by-side diff
1044 ** --webpage Format output as HTML
1045 ** --webpage -y HTML output in the side-by-side format
1046 **
1047 ** The "--from VERSION" option is used to specify the source check-in
1048 ** for the diff operation. If not specified, the source check-in is the
1049 ** base check-in for the current check-out. Similarly, the "--to VERSION"
1050 ** option specifies the check-in from which the second version of the file
1051 ** or files is taken. If there is no "--to" option then the (possibly edited)
1052 ** files in the current check-out are used. The "--checkin VERSION" option
1053 ** shows the changes made by check-in VERSION relative to its primary parent.
1054 ** The "--branch BRANCHNAME" shows all the changes on the branch BRANCHNAME.
1055 **
1056 ** The "-i" command-line option forces the use of Fossil's own internal
1057 ** diff logic rather than any external diff program that might be configured
1058 ** using the "setting" command. If no external diff program is configured,
1059 ** then the "-i" option is a no-op. The "-i" option converts "gdiff" into
1060 ** "diff".
1061 **
1062 ** The "--diff-binary" option enables or disables the inclusion of binary files
1063 ** when using an external diff program.
1064 **
1065 ** The "--binary" option causes files matching the glob PATTERN to be treated
1066 ** as binary when considering if they should be used with the external diff
1067 ** program. This option overrides the "binary-glob" setting.
1068 **
1069 ** These command show differences between managed files. Use the "fossil xdiff"
1070 ** command to see differences in unmanaged files.
1071 **
1072 ** Options:
@@ -1085,11 +1085,11 @@
1085 ** -r|--from VERSION Select VERSION as source for the diff
1086 ** -w|--ignore-all-space Ignore white space when comparing lines
1087 ** -i|--internal Use internal diff logic
1088 ** --json Output formatted as JSON
1089 ** -N|--new-file Alias for --verbose
1090 ** --numstat Show only the number of added and deleted lines
1091 ** -y|--side-by-side Side-by-side diff
1092 ** --strip-trailing-cr Strip trailing CR
1093 ** --tcl TCL-formated output used internally by --tk
1094 ** --tclsh PATH TCL/TK used for --tk (default: "tclsh")
1095 ** --tk Launch a Tcl/Tk GUI for display
1096
+7 -7
--- src/dispatch.c
+++ src/dispatch.c
@@ -624,19 +624,19 @@
624624
** Show help text for commands and pages. Useful for proof-reading.
625625
** Defaults to just the CLI commands. Specify --www to see only the
626626
** web pages, or --everything to see both commands and pages.
627627
**
628628
** Options:
629
-** -a|--aliases Show aliases.
629
+** -a|--aliases Show aliases
630630
** -e|--everything Show all commands and pages. Omit aliases to
631631
** avoid duplicates.
632
-** -h|--html Transform output to HTML.
633
-** -o|--options Show global options.
634
-** -r|--raw No output formatting.
635
-** -s|--settings Show settings.
636
-** -t|--test Include test- commands.
637
-** -w|--www Show WWW pages.
632
+** -h|--html Transform output to HTML
633
+** -o|--options Show global options
634
+** -r|--raw No output formatting
635
+** -s|--settings Show settings
636
+** -t|--test Include test- commands
637
+** -w|--www Show WWW pages
638638
*/
639639
void test_all_help_cmd(void){
640640
int mask = CMDFLAG_1ST_TIER | CMDFLAG_2ND_TIER;
641641
int useHtml = find_option("html","h",0)!=0;
642642
int rawOut = find_option("raw","r",0)!=0;
643643
--- src/dispatch.c
+++ src/dispatch.c
@@ -624,19 +624,19 @@
624 ** Show help text for commands and pages. Useful for proof-reading.
625 ** Defaults to just the CLI commands. Specify --www to see only the
626 ** web pages, or --everything to see both commands and pages.
627 **
628 ** Options:
629 ** -a|--aliases Show aliases.
630 ** -e|--everything Show all commands and pages. Omit aliases to
631 ** avoid duplicates.
632 ** -h|--html Transform output to HTML.
633 ** -o|--options Show global options.
634 ** -r|--raw No output formatting.
635 ** -s|--settings Show settings.
636 ** -t|--test Include test- commands.
637 ** -w|--www Show WWW pages.
638 */
639 void test_all_help_cmd(void){
640 int mask = CMDFLAG_1ST_TIER | CMDFLAG_2ND_TIER;
641 int useHtml = find_option("html","h",0)!=0;
642 int rawOut = find_option("raw","r",0)!=0;
643
--- src/dispatch.c
+++ src/dispatch.c
@@ -624,19 +624,19 @@
624 ** Show help text for commands and pages. Useful for proof-reading.
625 ** Defaults to just the CLI commands. Specify --www to see only the
626 ** web pages, or --everything to see both commands and pages.
627 **
628 ** Options:
629 ** -a|--aliases Show aliases
630 ** -e|--everything Show all commands and pages. Omit aliases to
631 ** avoid duplicates.
632 ** -h|--html Transform output to HTML
633 ** -o|--options Show global options
634 ** -r|--raw No output formatting
635 ** -s|--settings Show settings
636 ** -t|--test Include test- commands
637 ** -w|--www Show WWW pages
638 */
639 void test_all_help_cmd(void){
640 int mask = CMDFLAG_1ST_TIER | CMDFLAG_2ND_TIER;
641 int useHtml = find_option("html","h",0)!=0;
642 int rawOut = find_option("raw","r",0)!=0;
643
+4 -5
--- src/file.c
+++ src/file.c
@@ -1475,16 +1475,15 @@
14751475
**
14761476
** Display the effective file handling subsystem "settings" and then
14771477
** display file system information about the files specified, if any.
14781478
**
14791479
** Options:
1480
-**
14811480
** --allow-symlinks BOOLEAN Temporarily turn allow-symlinks on/off
1482
-** --open-config Open the configuration database first.
1483
-** --reset Reset cached stat() info for each file.
1481
+** --open-config Open the configuration database first
1482
+** --reset Reset cached stat() info for each file
14841483
** --root ROOT Use ROOT as the root of the check-out
1485
-** --slash Trailing slashes, if any, are retained.
1484
+** --slash Trailing slashes, if any, are retained
14861485
*/
14871486
void cmd_test_file_environment(void){
14881487
int i;
14891488
int slashFlag = find_option("slash",0,0)!=0;
14901489
int resetFlag = find_option("reset",0,0)!=0;
@@ -1774,11 +1773,11 @@
17741773
** COMMAND: test-tree-name
17751774
**
17761775
** Test the operation of the tree name generator.
17771776
**
17781777
** Options:
1779
-** --absolute Return an absolute path instead of a relative one.
1778
+** --absolute Return an absolute path instead of a relative one
17801779
** --case-sensitive B Enable or disable case-sensitive filenames. B is
17811780
** a boolean: "yes", "no", "true", "false", etc.
17821781
*/
17831782
void cmd_test_tree_name(void){
17841783
int i;
17851784
--- src/file.c
+++ src/file.c
@@ -1475,16 +1475,15 @@
1475 **
1476 ** Display the effective file handling subsystem "settings" and then
1477 ** display file system information about the files specified, if any.
1478 **
1479 ** Options:
1480 **
1481 ** --allow-symlinks BOOLEAN Temporarily turn allow-symlinks on/off
1482 ** --open-config Open the configuration database first.
1483 ** --reset Reset cached stat() info for each file.
1484 ** --root ROOT Use ROOT as the root of the check-out
1485 ** --slash Trailing slashes, if any, are retained.
1486 */
1487 void cmd_test_file_environment(void){
1488 int i;
1489 int slashFlag = find_option("slash",0,0)!=0;
1490 int resetFlag = find_option("reset",0,0)!=0;
@@ -1774,11 +1773,11 @@
1774 ** COMMAND: test-tree-name
1775 **
1776 ** Test the operation of the tree name generator.
1777 **
1778 ** Options:
1779 ** --absolute Return an absolute path instead of a relative one.
1780 ** --case-sensitive B Enable or disable case-sensitive filenames. B is
1781 ** a boolean: "yes", "no", "true", "false", etc.
1782 */
1783 void cmd_test_tree_name(void){
1784 int i;
1785
--- src/file.c
+++ src/file.c
@@ -1475,16 +1475,15 @@
1475 **
1476 ** Display the effective file handling subsystem "settings" and then
1477 ** display file system information about the files specified, if any.
1478 **
1479 ** Options:
 
1480 ** --allow-symlinks BOOLEAN Temporarily turn allow-symlinks on/off
1481 ** --open-config Open the configuration database first
1482 ** --reset Reset cached stat() info for each file
1483 ** --root ROOT Use ROOT as the root of the check-out
1484 ** --slash Trailing slashes, if any, are retained
1485 */
1486 void cmd_test_file_environment(void){
1487 int i;
1488 int slashFlag = find_option("slash",0,0)!=0;
1489 int resetFlag = find_option("reset",0,0)!=0;
@@ -1774,11 +1773,11 @@
1773 ** COMMAND: test-tree-name
1774 **
1775 ** Test the operation of the tree name generator.
1776 **
1777 ** Options:
1778 ** --absolute Return an absolute path instead of a relative one
1779 ** --case-sensitive B Enable or disable case-sensitive filenames. B is
1780 ** a boolean: "yes", "no", "true", "false", etc.
1781 */
1782 void cmd_test_tree_name(void){
1783 int i;
1784
+13 -14
--- src/fileedit.c
+++ src/fileedit.c
@@ -698,37 +698,36 @@
698698
**
699699
** where FILENAME is a repo-relative name as it would appear in the
700700
** vfile table.
701701
**
702702
** Options:
703
-**
704
-** -R|--repository REPO The repository file to commit to.
703
+** -R|--repository REPO The repository file to commit to
705704
** --as FILENAME The repository-side name of the input
706705
** file, relative to the top of the
707706
** repository. Default is the same as the
708707
** input file name.
709
-** -m|--comment COMMENT Required check-in comment.
710
-** -M|--comment-file FILE Reads check-in comment from the given file.
708
+** -m|--comment COMMENT Required check-in comment
709
+** -M|--comment-file FILE Reads check-in comment from the given file
711710
** -r|--revision VERSION Commit from this version. Default is
712711
** the check-out version (if available) or
713712
** trunk (if used without a check-out).
714713
** --allow-fork Allows the commit to be made against a
715714
** non-leaf parent. Note that no autosync
716715
** is performed beforehand.
717716
** --allow-merge-conflict Allows check-in of a file even if it
718717
** appears to contain a fossil merge conflict
719
-** marker.
718
+** marker
720719
** --user-override USER USER to use instead of the current
721
-** default.
722
-** --date-override DATETIME DATE to use instead of 'now'.
720
+** default
721
+** --date-override DATETIME DATE to use instead of 'now'
723722
** --allow-older Allow a commit to be older than its
724
-** ancestor.
723
+** ancestor
725724
** --convert-eol-inherit Convert EOL style of the check-in to match
726
-** the previous version's content.
727
-** --convert-eol-unix Convert the EOL style to Unix.
725
+** the previous version's content
726
+** --convert-eol-unix Convert the EOL style to Unix
728727
** --convert-eol-windows Convert the EOL style to Windows.
729
-** (only one of the --convert-eol-X options may be used and they only
728
+** (Only one of the --convert-eol-X options may be used and they only
730729
** modified the saved blob, not the input file.)
731730
** --delta Prefer to generate a delta manifest, if
732731
** able. The forbid-delta-manifests repo
733732
** config option trumps this, as do certain
734733
** heuristics.
@@ -736,14 +735,14 @@
736735
** Disabled by default to avoid that case-
737736
** sensitivity errors inadvertently lead to
738737
** adding a new file where an update is
739738
** intended.
740739
** -d|--dump-manifest Dumps the generated manifest to stdout
741
-** immediately after it's generated.
740
+** immediately after it's generated
742741
** --save-manifest FILE Saves the generated manifest to a file
743
-** after successfully processing it.
744
-** --wet-run Disables the default dry-run mode.
742
+** after successfully processing it
743
+** --wet-run Disables the default dry-run mode
745744
**
746745
** Example:
747746
**
748747
** %fossil test-ci-mini -R REPO -m ... -r foo --as src/myfile.c myfile.c
749748
**
750749
--- src/fileedit.c
+++ src/fileedit.c
@@ -698,37 +698,36 @@
698 **
699 ** where FILENAME is a repo-relative name as it would appear in the
700 ** vfile table.
701 **
702 ** Options:
703 **
704 ** -R|--repository REPO The repository file to commit to.
705 ** --as FILENAME The repository-side name of the input
706 ** file, relative to the top of the
707 ** repository. Default is the same as the
708 ** input file name.
709 ** -m|--comment COMMENT Required check-in comment.
710 ** -M|--comment-file FILE Reads check-in comment from the given file.
711 ** -r|--revision VERSION Commit from this version. Default is
712 ** the check-out version (if available) or
713 ** trunk (if used without a check-out).
714 ** --allow-fork Allows the commit to be made against a
715 ** non-leaf parent. Note that no autosync
716 ** is performed beforehand.
717 ** --allow-merge-conflict Allows check-in of a file even if it
718 ** appears to contain a fossil merge conflict
719 ** marker.
720 ** --user-override USER USER to use instead of the current
721 ** default.
722 ** --date-override DATETIME DATE to use instead of 'now'.
723 ** --allow-older Allow a commit to be older than its
724 ** ancestor.
725 ** --convert-eol-inherit Convert EOL style of the check-in to match
726 ** the previous version's content.
727 ** --convert-eol-unix Convert the EOL style to Unix.
728 ** --convert-eol-windows Convert the EOL style to Windows.
729 ** (only one of the --convert-eol-X options may be used and they only
730 ** modified the saved blob, not the input file.)
731 ** --delta Prefer to generate a delta manifest, if
732 ** able. The forbid-delta-manifests repo
733 ** config option trumps this, as do certain
734 ** heuristics.
@@ -736,14 +735,14 @@
736 ** Disabled by default to avoid that case-
737 ** sensitivity errors inadvertently lead to
738 ** adding a new file where an update is
739 ** intended.
740 ** -d|--dump-manifest Dumps the generated manifest to stdout
741 ** immediately after it's generated.
742 ** --save-manifest FILE Saves the generated manifest to a file
743 ** after successfully processing it.
744 ** --wet-run Disables the default dry-run mode.
745 **
746 ** Example:
747 **
748 ** %fossil test-ci-mini -R REPO -m ... -r foo --as src/myfile.c myfile.c
749 **
750
--- src/fileedit.c
+++ src/fileedit.c
@@ -698,37 +698,36 @@
698 **
699 ** where FILENAME is a repo-relative name as it would appear in the
700 ** vfile table.
701 **
702 ** Options:
703 ** -R|--repository REPO The repository file to commit to
 
704 ** --as FILENAME The repository-side name of the input
705 ** file, relative to the top of the
706 ** repository. Default is the same as the
707 ** input file name.
708 ** -m|--comment COMMENT Required check-in comment
709 ** -M|--comment-file FILE Reads check-in comment from the given file
710 ** -r|--revision VERSION Commit from this version. Default is
711 ** the check-out version (if available) or
712 ** trunk (if used without a check-out).
713 ** --allow-fork Allows the commit to be made against a
714 ** non-leaf parent. Note that no autosync
715 ** is performed beforehand.
716 ** --allow-merge-conflict Allows check-in of a file even if it
717 ** appears to contain a fossil merge conflict
718 ** marker
719 ** --user-override USER USER to use instead of the current
720 ** default
721 ** --date-override DATETIME DATE to use instead of 'now'
722 ** --allow-older Allow a commit to be older than its
723 ** ancestor
724 ** --convert-eol-inherit Convert EOL style of the check-in to match
725 ** the previous version's content
726 ** --convert-eol-unix Convert the EOL style to Unix
727 ** --convert-eol-windows Convert the EOL style to Windows.
728 ** (Only one of the --convert-eol-X options may be used and they only
729 ** modified the saved blob, not the input file.)
730 ** --delta Prefer to generate a delta manifest, if
731 ** able. The forbid-delta-manifests repo
732 ** config option trumps this, as do certain
733 ** heuristics.
@@ -736,14 +735,14 @@
735 ** Disabled by default to avoid that case-
736 ** sensitivity errors inadvertently lead to
737 ** adding a new file where an update is
738 ** intended.
739 ** -d|--dump-manifest Dumps the generated manifest to stdout
740 ** immediately after it's generated
741 ** --save-manifest FILE Saves the generated manifest to a file
742 ** after successfully processing it
743 ** --wet-run Disables the default dry-run mode
744 **
745 ** Example:
746 **
747 ** %fossil test-ci-mini -R REPO -m ... -r foo --as src/myfile.c myfile.c
748 **
749
-1
--- src/http.c
+++ src/http.c
@@ -561,11 +561,10 @@
561561
** is written into that second file instead of being written on standard
562562
** output. Use the "--out OUTPUT" option to specify an output file for
563563
** a GET request where there is no PAYLOAD.
564564
**
565565
** Options:
566
-**
567566
** --compress Use ZLIB compression on the payload
568567
** --mimetype TYPE Mimetype of the payload
569568
** --out FILE Store the reply in FILE
570569
** -v Verbose output
571570
** --xfer PAYLOAD in a Fossil xfer protocol message
572571
--- src/http.c
+++ src/http.c
@@ -561,11 +561,10 @@
561 ** is written into that second file instead of being written on standard
562 ** output. Use the "--out OUTPUT" option to specify an output file for
563 ** a GET request where there is no PAYLOAD.
564 **
565 ** Options:
566 **
567 ** --compress Use ZLIB compression on the payload
568 ** --mimetype TYPE Mimetype of the payload
569 ** --out FILE Store the reply in FILE
570 ** -v Verbose output
571 ** --xfer PAYLOAD in a Fossil xfer protocol message
572
--- src/http.c
+++ src/http.c
@@ -561,11 +561,10 @@
561 ** is written into that second file instead of being written on standard
562 ** output. Use the "--out OUTPUT" option to specify an output file for
563 ** a GET request where there is no PAYLOAD.
564 **
565 ** Options:
 
566 ** --compress Use ZLIB compression on the payload
567 ** --mimetype TYPE Mimetype of the payload
568 ** --out FILE Store the reply in FILE
569 ** -v Verbose output
570 ** --xfer PAYLOAD in a Fossil xfer protocol message
571
-3
--- src/info.c
+++ src/info.c
@@ -187,11 +187,10 @@
187187
**
188188
** Use the "finfo" command to get information about a specific
189189
** file in a check-out.
190190
**
191191
** Options:
192
-**
193192
** -R|--repository REPO Extract info from repository REPO
194193
** -v|--verbose Show extra information about repositories
195194
**
196195
** See also: [[annotate]], [[artifact]], [[finfo]], [[timeline]]
197196
*/
@@ -3471,11 +3470,10 @@
34713470
** Usage: %fossil amend HASH OPTION ?OPTION ...?
34723471
**
34733472
** Amend the tags on check-in HASH to change how it displays in the timeline.
34743473
**
34753474
** Options:
3476
-**
34773475
** --author USER Make USER the author for check-in
34783476
** -m|--comment COMMENT Make COMMENT the check-in comment
34793477
** -M|--message-file FILE Read the amended comment from FILE
34803478
** -e|--edit-comment Launch editor to revise comment
34813479
** --date DATETIME Make DATETIME the check-in time
@@ -3813,11 +3811,10 @@
38133811
** If VERSION and the found ancestor refer to the same commit, the last two
38143812
** components are omitted, unless --long is provided. When no fitting tagged
38153813
** ancestor is found, show only the short hash of VERSION.
38163814
**
38173815
** Options:
3818
-**
38193816
** --digits Display so many hex digits of the hash
38203817
** (default: the larger of 6 and the 'hash-digit' setting)
38213818
** -d|--dirty Show whether there are changes to be committed
38223819
** --long Always show all three components
38233820
** --match GLOB Consider only non-propagating tags matching GLOB
38243821
--- src/info.c
+++ src/info.c
@@ -187,11 +187,10 @@
187 **
188 ** Use the "finfo" command to get information about a specific
189 ** file in a check-out.
190 **
191 ** Options:
192 **
193 ** -R|--repository REPO Extract info from repository REPO
194 ** -v|--verbose Show extra information about repositories
195 **
196 ** See also: [[annotate]], [[artifact]], [[finfo]], [[timeline]]
197 */
@@ -3471,11 +3470,10 @@
3471 ** Usage: %fossil amend HASH OPTION ?OPTION ...?
3472 **
3473 ** Amend the tags on check-in HASH to change how it displays in the timeline.
3474 **
3475 ** Options:
3476 **
3477 ** --author USER Make USER the author for check-in
3478 ** -m|--comment COMMENT Make COMMENT the check-in comment
3479 ** -M|--message-file FILE Read the amended comment from FILE
3480 ** -e|--edit-comment Launch editor to revise comment
3481 ** --date DATETIME Make DATETIME the check-in time
@@ -3813,11 +3811,10 @@
3813 ** If VERSION and the found ancestor refer to the same commit, the last two
3814 ** components are omitted, unless --long is provided. When no fitting tagged
3815 ** ancestor is found, show only the short hash of VERSION.
3816 **
3817 ** Options:
3818 **
3819 ** --digits Display so many hex digits of the hash
3820 ** (default: the larger of 6 and the 'hash-digit' setting)
3821 ** -d|--dirty Show whether there are changes to be committed
3822 ** --long Always show all three components
3823 ** --match GLOB Consider only non-propagating tags matching GLOB
3824
--- src/info.c
+++ src/info.c
@@ -187,11 +187,10 @@
187 **
188 ** Use the "finfo" command to get information about a specific
189 ** file in a check-out.
190 **
191 ** Options:
 
192 ** -R|--repository REPO Extract info from repository REPO
193 ** -v|--verbose Show extra information about repositories
194 **
195 ** See also: [[annotate]], [[artifact]], [[finfo]], [[timeline]]
196 */
@@ -3471,11 +3470,10 @@
3470 ** Usage: %fossil amend HASH OPTION ?OPTION ...?
3471 **
3472 ** Amend the tags on check-in HASH to change how it displays in the timeline.
3473 **
3474 ** Options:
 
3475 ** --author USER Make USER the author for check-in
3476 ** -m|--comment COMMENT Make COMMENT the check-in comment
3477 ** -M|--message-file FILE Read the amended comment from FILE
3478 ** -e|--edit-comment Launch editor to revise comment
3479 ** --date DATETIME Make DATETIME the check-in time
@@ -3813,11 +3811,10 @@
3811 ** If VERSION and the found ancestor refer to the same commit, the last two
3812 ** components are omitted, unless --long is provided. When no fitting tagged
3813 ** ancestor is found, show only the short hash of VERSION.
3814 **
3815 ** Options:
 
3816 ** --digits Display so many hex digits of the hash
3817 ** (default: the larger of 6 and the 'hash-digit' setting)
3818 ** -d|--dirty Show whether there are changes to be committed
3819 ** --long Always show all three components
3820 ** --match GLOB Consider only non-propagating tags matching GLOB
3821
+503 -15
--- src/login.c
+++ src/login.c
@@ -510,10 +510,19 @@
510510
zPattern = mprintf("%s/login*", g.zBaseURL);
511511
rc = sqlite3_strglob(zPattern, zReferer)==0;
512512
fossil_free(zPattern);
513513
return rc;
514514
}
515
+
516
+/*
517
+** Return true if users are allowed to reset their own passwords.
518
+*/
519
+int login_self_password_reset_available(void){
520
+ if( !db_get_boolean("self-pw-reset",0) ) return 0;
521
+ if( !alert_tables_exist() ) return 0;
522
+ return 1;
523
+}
515524
516525
/*
517526
** Return TRUE if self-registration is available. If the zNeeded
518527
** argument is not NULL, then only return true if self-registration is
519528
** available and any of the capabilities named in zNeeded are available
@@ -560,10 +569,16 @@
560569
const int noAnon = P("noanon")!=0;
561570
int rememberMe; /* If true, use persistent cookie, else
562571
session cookie. Toggled per
563572
checkbox. */
564573
574
+ if( P("pwreset")!=0 && login_self_password_reset_available() ){
575
+ /* If the "Reset Password" button in the form was pressed, render
576
+ ** the Request Password Reset page in place of this one. */
577
+ login_reqpwreset_page();
578
+ return;
579
+ }
565580
login_check_credentials();
566581
fossil_redirect_to_https_if_needed(1);
567582
sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
568583
constant_time_cmp_function, 0, 0);
569584
zUsername = P("u");
@@ -613,10 +628,15 @@
613628
char *zNewPw = sha1_shared_secret(zNew1, g.zLogin, 0);
614629
char *zChngPw;
615630
char *zErr;
616631
int rc;
617632
633
+ /* vvvvvvv--- tag-20230106-1 ----vvvvvv
634
+ **
635
+ ** Replicate changes made below to tag-20230106-2
636
+ */
637
+ admin_log("password change for user %s", g.zLogin);
618638
db_unprotect(PROTECT_USER);
619639
db_multi_exec(
620640
"UPDATE user SET pw=%Q WHERE uid=%d", zNewPw, g.userUid
621641
);
622642
zChngPw = mprintf(
@@ -627,10 +647,16 @@
627647
zNew1, g.zLogin, g.zLogin
628648
);
629649
fossil_free(zNewPw);
630650
rc = login_group_sql(zChngPw, "<p>", "</p>\n", &zErr);
631651
db_protect_pop();
652
+ /*
653
+ ** ^^^^^^^^--- tag-20230106-1 ----^^^^^^^^^
654
+ **
655
+ ** Replicate changes above to tag-20230106-2
656
+ */
657
+
632658
if( rc ){
633659
zErrMsg = mprintf("<span class=\"loginError\">%s</span>", zErr);
634660
fossil_free(zErr);
635661
}else{
636662
redirect_to_g();
@@ -770,10 +796,16 @@
770796
if( !noAnon && login_self_register_available(0) ){
771797
@ <tr>
772798
@ <td></td>
773799
@ <td><input type="submit" name="self" value="Create A New Account">
774800
@ </tr>
801
+ }
802
+ if( login_self_password_reset_available() ){
803
+ @ <tr>
804
+ @ <td></td>
805
+ @ <td><input type="submit" name="pwreset" value="Reset My Password">
806
+ @ </tr>
775807
}
776808
@ </table>
777809
if( zAnonPw && !noAnon ){
778810
const char *zDecoded = captcha_decode(uSeed);
779811
int bAutoCaptcha = db_get_boolean("auto-captcha", 0);
@@ -828,10 +860,245 @@
828860
@ </form>
829861
}
830862
}
831863
style_finish_page();
832864
}
865
+
866
+/*
867
+** Construct an appropriate URL suffix for the /resetpw page. The
868
+** suffix will be of the form:
869
+**
870
+** UID-TIMESTAMP-HASH
871
+**
872
+** Where UID and TIMESTAMP are the parameters to this function, and HASH
873
+** is constructed from information that is unique to the user in question
874
+** and which is not publicly available. In particular, the HASH includes
875
+** the existing user password. Thus, in order to construct a URL that can
876
+** change a password, an attacker must know the current password, in which
877
+** case the attacker does not need to construct the URL in order to take
878
+** over the account.
879
+**
880
+** Return a pointer to the resulting string in memory obtained
881
+** from fossil_malloc().
882
+*/
883
+char *login_resetpw_suffix(int uid, i64 timestamp){
884
+ char *zHash;
885
+ char *zInnerSql;
886
+ char *zResult;
887
+ extern int sqlite3_shathree_init(sqlite3*,char**,const sqlite3_api_routines*);
888
+ if( timestamp<=0 ){ timestamp = time(0); }
889
+ sqlite3_shathree_init(g.db, 0, 0);
890
+ if( db_table_exists("repository","subscriber") ){
891
+ zInnerSql = mprintf(
892
+ "SELECT %lld, login, pw, cookie, user.mtime, user.info, subscriberCode"
893
+ " FROM user LEFT JOIN subscriber ON suname=login"
894
+ " WHERE uid=%d", timestamp, uid);
895
+ }else{
896
+ zInnerSql = mprintf(
897
+ "SELECT %lld, login, pw, cookie, user.mtime, user.info"
898
+ " FROM user WHERE uid=%d", timestamp, uid);
899
+ }
900
+ zHash = db_text(0, "SELECT lower(hex(sha3_query(%Q)))", zInnerSql);
901
+ fossil_free(zInnerSql);
902
+ zResult = mprintf("%x-%llx-%s", uid, timestamp, zHash);
903
+ if( strlen(zHash)<64 || strlen(zResult)<70 ){
904
+ /* This should never happen, but if it does, we don't want it to lead
905
+ ** to a security breach. */
906
+ fossil_panic("insecure password reset hash generated\n");
907
+ }
908
+ fossil_free(zHash);
909
+ return zResult;
910
+}
911
+
912
+/*
913
+** Check to see if the "name" query parameter is a valid resetpw suffix
914
+** for a user whose password we are allowed to reset. If it is, then return
915
+** the positive integer UID for that user. If the query parameter is not
916
+** valid, return 0.
917
+*/
918
+static int login_resetpw_suffix_is_valid(const char *zName){
919
+ int i, j;
920
+ int uid;
921
+ i64 timestamp;
922
+ i64 now;
923
+ char *zHash;
924
+ if( zName==0 || strlen(zName)<70 ) goto not_valid_suffix;
925
+ for(i=0; fossil_isxdigit(zName[i]); i++){}
926
+ if( i<1 || zName[i]!='-' ) goto not_valid_suffix;
927
+ for(j=i+1; fossil_isxdigit(zName[j]); j++){}
928
+ if( j<=i+1 || zName[j]!='-' ) goto not_valid_suffix;
929
+ uid = strtol(zName, 0, 16);
930
+ if( uid<=0 ) goto not_valid_suffix;
931
+ if( !db_exists("SELECT 1 FROM user WHERE uid=%d", uid) ){
932
+ goto not_valid_suffix;
933
+ }
934
+ timestamp = strtoll(&zName[i+1], 0, 16);
935
+ now = time(0);
936
+ if( timestamp+3600 <= now ) goto not_valid_suffix;
937
+ zHash = login_resetpw_suffix(uid,timestamp);
938
+ if( fossil_strcmp(zHash, zName)!=0 ){
939
+ fossil_free(zHash);
940
+ goto not_valid_suffix;
941
+ }
942
+ fossil_free(zHash);
943
+ return uid;
944
+
945
+not_valid_suffix:
946
+ return 0;
947
+}
948
+
949
+/*
950
+** COMMAND: test-resetpw-url
951
+** Usage: fossil test-resetpw-url UID
952
+**
953
+** Generate and verify a /resetpw URL for user UID.
954
+**
955
+** This command is intended for unit testing the login_resetpw_suffix()
956
+** and login_resetpw_suffix_is_valid() functions.
957
+*/
958
+void test_resetpw_url(void){
959
+ char *zSuffix;
960
+ int uid;
961
+ int xuid;
962
+ char *zLogin;
963
+ int i;
964
+ db_find_and_open_repository(0, 0);
965
+ verify_all_options();
966
+ if( g.argc<3 ){
967
+ usage("UID ...");
968
+ }
969
+ for(i=2; i<g.argc; i++){
970
+ uid = atoi(g.argv[i]);
971
+ zSuffix = login_resetpw_suffix(uid, 0);
972
+ xuid = login_resetpw_suffix_is_valid(zSuffix);
973
+ if( xuid>0 ){
974
+ zLogin = db_text(0, "SELECT login FROM user WHERE uid=%d", xuid);
975
+ }else{
976
+ zLogin = 0;
977
+ }
978
+ fossil_print("/resetpw/%s %d (%s)\n",
979
+ zSuffix, xuid, zLogin ? zLogin : "???");
980
+ fossil_free(zSuffix);
981
+ fossil_free(zLogin);
982
+ }
983
+}
984
+
985
+/*
986
+** WEBPAGE: resetpw
987
+**
988
+** The URL format must be like this:
989
+**
990
+** /resetpw/UID-TIMESTAMP-HASH
991
+**
992
+** Where UID is the uid of the user whose password is to be reset,
993
+** TIMESTAMP is the unix timestamp when the request was made, and
994
+** HASH is a hash based on UID, TIMESTAMP, and other information that
995
+** is unavailable to an attacher.
996
+**
997
+** With no other arguments, a form is present which allows the user to
998
+** enter a new password. When the SUBMIT button is pressed, a POST request
999
+** back to the same URL that will change the password.
1000
+*/
1001
+void login_resetpw(void){
1002
+ const char *zName;
1003
+ int uid;
1004
+ char *zRPW;
1005
+ const char *zNew1, *zNew2;
1006
+
1007
+ style_set_current_feature("resetpw");
1008
+ style_header("Reset Password");
1009
+ style_adunit_config(ADUNIT_OFF);
1010
+ zName = PD("name","");
1011
+ uid = login_resetpw_suffix_is_valid(zName);
1012
+ if( uid==0 ){
1013
+ @ <p><span class="loginError">
1014
+ @ This password-reset URL is invalid, probably because it has expired.
1015
+ @ Password-reset URLs have a short lifespan.
1016
+ @ </span></p>
1017
+ style_finish_page();
1018
+ sleep(1); /* Introduce a small delay on an invalid suffix as an
1019
+ ** extra defense against search attacks */
1020
+ return;
1021
+ }
1022
+ fossil_redirect_to_https_if_needed(1);
1023
+ login_set_uid(uid, 0);
1024
+ if( g.perm.Setup || g.perm.Admin || !g.perm.Password || g.zLogin==0 ){
1025
+ @ <p><span class="loginError">
1026
+ @ Cannot change the password for user <b>%h(g.zLogin)</b>.
1027
+ @ </span></p>
1028
+ style_finish_page();
1029
+ return;
1030
+ }
1031
+ if( (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 ){
1032
+ if( fossil_strcmp(zNew1,zNew2)!=0 ){
1033
+ @ <p><span class="loginError">
1034
+ @ The two copies of your new passwords do not match.
1035
+ @ Try again.
1036
+ @ </span></p>
1037
+ }else{
1038
+ char *zNewPw = sha1_shared_secret(zNew1, g.zLogin, 0);
1039
+ char *zChngPw;
1040
+ char *zErr;
1041
+ int rc;
1042
+
1043
+ /* vvvvvvv--- tag-20230106-2 ----vvvvvv
1044
+ **
1045
+ ** Replicate changes made below to tag-20230106-1
1046
+ */
1047
+ admin_log("password change for user %s", g.zLogin);
1048
+ db_unprotect(PROTECT_USER);
1049
+ db_multi_exec(
1050
+ "UPDATE user SET pw=%Q WHERE uid=%d", zNewPw, g.userUid
1051
+ );
1052
+ zChngPw = mprintf(
1053
+ "UPDATE user"
1054
+ " SET pw=shared_secret(%Q,%Q,"
1055
+ " (SELECT value FROM config WHERE name='project-code'))"
1056
+ " WHERE login=%Q",
1057
+ zNew1, g.zLogin, g.zLogin
1058
+ );
1059
+ fossil_free(zNewPw);
1060
+ rc = login_group_sql(zChngPw, "<p>", "</p>\n", &zErr);
1061
+ db_protect_pop();
1062
+ /*
1063
+ ** ^^^^^^^^--- tag-20230106-2 ----^^^^^^^^^
1064
+ **
1065
+ ** Replicate changes above to tag-20230106-1
1066
+ */
1067
+
1068
+ if( rc ){
1069
+ @ <p><span class='loginError'>
1070
+ @ %s(zErr);
1071
+ @ </span></p>
1072
+ fossil_free(zErr);
1073
+ }else{
1074
+ @ <p>Password changed successfully. Go to the
1075
+ @ <a href="%R/login?u=%t(g.zLogin)">Login</a> page and log in
1076
+ @ using the new password to continue.
1077
+ @ </p>
1078
+ style_finish_page();
1079
+ return;
1080
+ }
1081
+ }
1082
+ }
1083
+ zRPW = fossil_random_password(12);
1084
+ @ <p>Change Password for user <b>%h(g.zLogin)</b>:</p>
1085
+ form_begin(0, "%R/resetpw");
1086
+ @ <input type='hidden' name='name' value='%h(zName)'>
1087
+ @ <table>
1088
+ @ <tr><td class="form_label" id="newpw">New Password:</td>
1089
+ @ <td><input aria-labelledby="newpw" type="password" name="n1" \
1090
+ @ size="30" /> Suggestion: %z(zRPW)</td></tr>
1091
+ @ <tr><td class="form_label" id="reppw">Repeat New Password:</td>
1092
+ @ <td><input aria-labledby="reppw" type="password" name="n2" \
1093
+ @ size="30" /></td></tr>
1094
+ @ <tr><td></td>
1095
+ @ <td><input type="submit" value="Change Password" /></td></tr>
1096
+ @ </table>
1097
+ @ </form>
1098
+ style_finish_page();
1099
+}
8331100
8341101
/*
8351102
** Attempt to find login credentials for user zLogin on a peer repository
8361103
** with project code zCode. Transfer those credentials to the local
8371104
** repository.
@@ -999,11 +1266,10 @@
9991266
void login_check_credentials(void){
10001267
int uid = 0; /* User id */
10011268
const char *zCookie; /* Text of the login cookie */
10021269
const char *zIpAddr; /* Raw IP address of the requestor */
10031270
const char *zCap = 0; /* Capability string */
1004
- const char *zPublicPages = 0; /* GLOB patterns of public pages */
10051271
const char *zLogin = 0; /* Login user for credentials */
10061272
10071273
/* Only run this check once. */
10081274
if( g.userUid!=0 ) return;
10091275
@@ -1139,10 +1405,21 @@
11391405
zCap = "";
11401406
}
11411407
sqlite3_snprintf(sizeof(g.zCsrfToken), g.zCsrfToken, "none");
11421408
}
11431409
1410
+ login_set_uid(uid, zCap);
1411
+}
1412
+
1413
+/*
1414
+** Set the current logged in user to be uid. zCap is precomputed
1415
+** (override) capabilities. If zCap==0, then look up the capabilities
1416
+** in the USER table.
1417
+*/
1418
+int login_set_uid(int uid, const char *zCap){
1419
+ const char *zPublicPages = 0; /* GLOB patterns of public pages */
1420
+
11441421
/* At this point, we know that uid!=0. Find the privileges associated
11451422
** with user uid.
11461423
*/
11471424
assert( uid!=0 );
11481425
if( zCap==0 ){
@@ -1219,10 +1496,11 @@
12191496
if( glob_match(pGlob, zUri) ){
12201497
login_set_capabilities(db_get("default-perms", "u"), 0);
12211498
}
12221499
glob_free(pGlob);
12231500
}
1501
+ return g.zLogin!=0;
12241502
}
12251503
12261504
/*
12271505
** Memory of settings
12281506
*/
@@ -1557,10 +1835,75 @@
15571835
zUserID, zUserID, zUserID
15581836
);
15591837
return rc;
15601838
}
15611839
1840
+/*
1841
+** zEMail is an email address. (Example: "[email protected]".) This routine
1842
+** searches for a user or subscriber that has that email address. If the
1843
+** email address is used no-where in the system, return 0. If the email
1844
+** address is assigned to a particular user return the UID for that user.
1845
+** If the email address is used, but not by a particular user, return -1.
1846
+*/
1847
+static int email_address_in_use(const char *zEMail){
1848
+ int uid;
1849
+ uid = db_int(0,
1850
+ "SELECT uid FROM user"
1851
+ " WHERE info LIKE '%%<%q>%%'", zEMail);
1852
+ if( uid>0 ){
1853
+ if( db_exists("SELECT 1 FROM user WHERE uid=%d AND ("
1854
+ " cap GLOB '*[as]*' OR"
1855
+ " find_emailaddr(info)<>%Q COLLATE nocase)",
1856
+ uid, zEMail) ){
1857
+ uid = -1;
1858
+ }
1859
+ }
1860
+ if( uid==0 && alert_tables_exist() ){
1861
+ uid = db_int(0,
1862
+ "SELECT user.uid FROM subscriber JOIN user ON login=suname"
1863
+ " WHERE semail=%Q AND sverified", zEMail);
1864
+ if( uid ){
1865
+ if( db_exists("SELECT 1 FROM user WHERE uid=%d AND "
1866
+ " cap GLOB '*[as]*'",
1867
+ uid) ){
1868
+ uid = -1;
1869
+ }
1870
+ }
1871
+ }
1872
+ return uid;
1873
+}
1874
+
1875
+/*
1876
+** COMMAND: test-email-used
1877
+** Usage: fossil test-email-used EMAIL ...
1878
+**
1879
+** Given a list of email addresses, show the UID and LOGIN associated
1880
+** with each one.
1881
+*/
1882
+void test_email_used(void){
1883
+ int i;
1884
+ db_find_and_open_repository(0, 0);
1885
+ verify_all_options();
1886
+ if( g.argc<3 ){
1887
+ usage("EMAIL ...");
1888
+ }
1889
+ for(i=2; i<g.argc; i++){
1890
+ const char *zEMail = g.argv[i];
1891
+ int uid = email_address_in_use(zEMail);
1892
+ if( uid==0 ){
1893
+ fossil_print("%s: not used\n", zEMail);
1894
+ }else if( uid<0 ){
1895
+ fossil_print("%s: used but no password reset is available\n", zEMail);
1896
+ }else{
1897
+ char *zLogin = db_text(0, "SELECT login FROM user WHERE uid=%d", uid);
1898
+ fossil_print("%s: UID %d (%s)\n", zEMail, uid, zLogin);
1899
+ fossil_free(zLogin);
1900
+ }
1901
+ }
1902
+}
1903
+
1904
+
15621905
/*
15631906
** Check an email address and confirm that it is valid for self-registration.
15641907
** The email address is known already to be well-formed. Return true
15651908
** if the email address is on the allowed list.
15661909
**
@@ -1598,21 +1941,29 @@
15981941
const char *zDName;
15991942
unsigned int uSeed;
16001943
const char *zDecoded;
16011944
int iErrLine = -1;
16021945
const char *zErr = 0;
1946
+ int uid = 0; /* User id with the same email */
16031947
int captchaIsCorrect = 0; /* True on a correct captcha */
16041948
char *zCaptcha = ""; /* Value of the captcha text */
16051949
char *zPerms; /* Permissions for the default user */
16061950
int canDoAlerts = 0; /* True if receiving email alerts is possible */
16071951
int doAlerts = 0; /* True if subscription is wanted too */
1952
+
16081953
if( !db_get_boolean("self-register", 0) ){
16091954
style_header("Registration not possible");
16101955
@ <p>This project does not allow user self-registration. Please contact the
16111956
@ project administrator to obtain an account.</p>
16121957
style_finish_page();
16131958
return;
1959
+ }
1960
+ if( P("pwreset")!=0 && login_self_password_reset_available() ){
1961
+ /* The "Request Password Reset" button was pressed, so render the
1962
+ ** "Request Password Reset" page instead of this one. */
1963
+ login_reqpwreset_page();
1964
+ return;
16141965
}
16151966
zPerms = db_get("default-perms", "u");
16161967
16171968
/* Prompt the user for email alerts if this repository is configured for
16181969
** email alerts and if the default permissions include "7" */
@@ -1656,26 +2007,16 @@
16562007
iErrLine = 4;
16572008
zErr = "Password must be at least 6 characters long";
16582009
}else if( fossil_strcmp(zPasswd,zConfirm)!=0 ){
16592010
iErrLine = 5;
16602011
zErr = "Passwords do not match";
2012
+ }else if( (uid = email_address_in_use(zEAddr))!=0 ){
2013
+ iErrLine = 3;
2014
+ zErr = "This email address is already associated with a user";
16612015
}else if( login_self_choosen_userid_already_exists(zUserID) ){
16622016
iErrLine = 1;
16632017
zErr = "This User ID is already taken. Choose something different.";
1664
- }else if(
1665
- /* If the email is found anywhere in USER.INFO... */
1666
- db_exists("SELECT 1 FROM user WHERE info LIKE '%%%q%%'", zEAddr)
1667
- ||
1668
- /* Or if the email is a verify subscriber email with an associated
1669
- ** user... */
1670
- (alert_tables_exist() &&
1671
- db_exists(
1672
- "SELECT 1 FROM subscriber WHERE semail=%Q AND suname IS NOT NULL"
1673
- " AND sverified",zEAddr))
1674
- ){
1675
- iErrLine = 3;
1676
- zErr = "This email address is already claimed by another user";
16772018
}else{
16782019
/* If all of the tests above have passed, that means that the submitted
16792020
** form contains valid data and we can proceed to create the new login */
16802021
Blob sql;
16812022
int uid;
@@ -1809,11 +2150,17 @@
18092150
@ <td class="form_label" align="right" id="emaddr">Email Address:</td>
18102151
@ <td><input aria-labelledby="emaddr" type="text" name="ea" \
18112152
@ value="%h(zEAddr)" size="30"></td>
18122153
@ </tr>
18132154
if( iErrLine==3 ){
1814
- @ <tr><td><td><span class='loginError'>&uarr; %h(zErr)</span></td></tr>
2155
+ @ <tr><td><td><span class='loginError'>&uarr; %h(zErr)</span>
2156
+ if( uid>0 && login_self_password_reset_available() ){
2157
+ @ <br />
2158
+ @ <input type="submit" name="pwreset" \
2159
+ @ value="Request Password Reset For %h(zEAddr)">
2160
+ }
2161
+ @ </td></tr>
18152162
}
18162163
if( canDoAlerts ){
18172164
int a = atoi(PD("alerts","1"));
18182165
@ <tr>
18192166
@ <td class="form_label" align="right" id="emalrt">Email&nbsp;Alerts?</td>
@@ -1865,10 +2212,151 @@
18652212
@ </form>
18662213
style_finish_page();
18672214
18682215
free(zCaptcha);
18692216
}
2217
+
2218
+/*
2219
+** WEBPAGE: reqpwreset
2220
+**
2221
+** A web page to request a password reset.
2222
+*/
2223
+void login_reqpwreset_page(void){
2224
+ const char *zEAddr;
2225
+ const char *zDecoded;
2226
+ unsigned int uSeed;
2227
+ int iErrLine = -1;
2228
+ const char *zErr = 0;
2229
+ int uid = 0; /* User id with the email zEAddr */
2230
+ int captchaIsCorrect = 0; /* True on a correct captcha */
2231
+ char *zCaptcha = ""; /* Value of the captcha text */
2232
+
2233
+ if( !login_self_password_reset_available() ){
2234
+ style_header("Password reset not possible");
2235
+ @ <p>This project does not allow users to reset their own passwords.
2236
+ @ If you need a password reset, you will have to negotiate that directly
2237
+ @ with the project administrator.
2238
+ style_finish_page();
2239
+ return;
2240
+ }
2241
+ zEAddr = PDT("ea","");
2242
+
2243
+ /* Verify user imputs */
2244
+ if( !cgi_csrf_safe(1) || P("reqpwreset")==0 ){
2245
+ /* This is the initial display of the form. No processing or error
2246
+ ** checking is to be done. Fall through into the form display
2247
+ */
2248
+ }else if( (captchaIsCorrect = captcha_is_correct(1))==0 ){
2249
+ iErrLine = 2;
2250
+ zErr = "Incorrect CAPTCHA";
2251
+ }else if( zEAddr[0]==0 ){
2252
+ iErrLine = 1;
2253
+ zErr = "Required";
2254
+ }else if( email_address_is_valid(zEAddr,0)==0 ){
2255
+ iErrLine = 1;
2256
+ zErr = "Not a valid email address";
2257
+ }else if( authorized_subscription_email(zEAddr)==0 ){
2258
+ iErrLine = 1;
2259
+ zErr = "Not an authorized email address";
2260
+ }else if( (uid = email_address_in_use(zEAddr))<=0 ){
2261
+ iErrLine = 1;
2262
+ zErr = "This email address is not associated with a user who has "
2263
+ "password reset privileges.";
2264
+ }else if( login_set_uid(uid,0)==0 || g.perm.Admin || g.perm.Setup
2265
+ || !g.perm.Password ){
2266
+ iErrLine = 1;
2267
+ zErr = "This email address is not associated with a user who has "
2268
+ "password reset privileges.";
2269
+ }else{
2270
+
2271
+ /* If all of the tests above have passed, that means that the submitted
2272
+ ** form contains valid data and we can proceed to issue the password
2273
+ ** reset email. */
2274
+ Blob hdr, body;
2275
+ AlertSender *pSender;
2276
+ char *zUrl = login_resetpw_suffix(uid, 0);
2277
+ pSender = alert_sender_new(0,0);
2278
+ blob_init(&hdr,0,0);
2279
+ blob_init(&body,0,0);
2280
+ blob_appendf(&hdr, "To: <%s>\n", zEAddr);
2281
+ blob_appendf(&hdr, "Subject: Password reset for %s\n", g.zBaseURL);
2282
+ blob_appendf(&body,
2283
+ "Someone has requested to reset the password for user \"%s\"\n",
2284
+ g.zLogin);
2285
+ blob_appendf(&body, "at %s.\n\n", g.zBaseURL);
2286
+ blob_appendf(&body,
2287
+ "If you did not request this password reset, ignore\n"
2288
+ "this email\n\n");
2289
+ blob_appendf(&body,
2290
+ "To reset the password, visit the following link:\n\n"
2291
+ " %s/resetpw/%s\n\n", g.zBaseURL, zUrl);
2292
+ fossil_free(zUrl);
2293
+ alert_send(pSender, &hdr, &body, 0);
2294
+ style_header("Email Verification");
2295
+ if( pSender->zErr ){
2296
+ @ <h1>Internal Error</h1>
2297
+ @ <p>The following internal error was encountered while trying
2298
+ @ to send the confirmation email:
2299
+ @ <blockquote><pre>
2300
+ @ %h(pSender->zErr)
2301
+ @ </pre></blockquote>
2302
+ }else{
2303
+ @ <p>An email containing a hyperlink that can be used to reset
2304
+ @ your password has been sent to "%h(zEAddr)".</p>
2305
+ }
2306
+ alert_sender_free(pSender);
2307
+ style_finish_page();
2308
+ return;
2309
+ }
2310
+
2311
+ /* Prepare the captcha. */
2312
+ if( captchaIsCorrect ){
2313
+ uSeed = strtoul(P("captchaseed"),0,10);
2314
+ }else{
2315
+ uSeed = captcha_seed();
2316
+ }
2317
+ zDecoded = captcha_decode(uSeed);
2318
+ zCaptcha = captcha_render(zDecoded);
2319
+
2320
+ style_header("Request Password Reset");
2321
+ /* Print out the registration form. */
2322
+ g.perm.Hyperlink = 1; /* Artificially enable hyperlinks */
2323
+ form_begin(0, "%R/reqpwreset");
2324
+ @ <p><input type="hidden" name="captchaseed" value="%u(uSeed)" />
2325
+ @ <p><input type="hidden" name="reqpwreset" value="1" />
2326
+ @ <table class="login_out">
2327
+ @ <tr>
2328
+ @ <td class="form_label" align="right" id="emaddr">Email Address:</td>
2329
+ @ <td><input aria-labelledby="emaddr" type="text" name="ea" \
2330
+ @ value="%h(zEAddr)" size="30"></td>
2331
+ @ </tr>
2332
+ if( iErrLine==1 ){
2333
+ @ <tr><td><td><span class='loginError'>&uarr; %h(zErr)</span></td></tr>
2334
+ }
2335
+ @ <tr>
2336
+ @ <td class="form_label" align="right" id="cptcha">Captcha:</td>
2337
+ @ <td><input type="text" name="captcha" aria-labelledby="cptcha" \
2338
+ @ value="%h(captchaIsCorrect?zDecoded:"")" size="30">
2339
+ captcha_speakit_button(uSeed, "Speak the captcha text");
2340
+ @ </td>
2341
+ @ </tr>
2342
+ if( iErrLine==2 ){
2343
+ @ <tr><td><td><span class='loginError'>&uarr; %h(zErr)</span></td></tr>
2344
+ }
2345
+ @ <tr><td></td>
2346
+ @ <td><input type="submit" name="new" value="Request Password Reset"/>\
2347
+ @ </td></tr>
2348
+ @ </table>
2349
+ @ <div class="captcha"><table class="captcha"><tr><td><pre class="captcha">
2350
+ @ %h(zCaptcha)
2351
+ @ </pre>
2352
+ @ Enter this 8-letter code in the "Captcha" box above.
2353
+ @ </td></tr></table></div>
2354
+ @ </form>
2355
+ style_finish_page();
2356
+ free(zCaptcha);
2357
+}
18702358
18712359
/*
18722360
** Run SQL on the repository database for every repository in our
18732361
** login group. The SQL is run in a separate database connection.
18742362
**
18752363
--- src/login.c
+++ src/login.c
@@ -510,10 +510,19 @@
510 zPattern = mprintf("%s/login*", g.zBaseURL);
511 rc = sqlite3_strglob(zPattern, zReferer)==0;
512 fossil_free(zPattern);
513 return rc;
514 }
 
 
 
 
 
 
 
 
 
515
516 /*
517 ** Return TRUE if self-registration is available. If the zNeeded
518 ** argument is not NULL, then only return true if self-registration is
519 ** available and any of the capabilities named in zNeeded are available
@@ -560,10 +569,16 @@
560 const int noAnon = P("noanon")!=0;
561 int rememberMe; /* If true, use persistent cookie, else
562 session cookie. Toggled per
563 checkbox. */
564
 
 
 
 
 
 
565 login_check_credentials();
566 fossil_redirect_to_https_if_needed(1);
567 sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
568 constant_time_cmp_function, 0, 0);
569 zUsername = P("u");
@@ -613,10 +628,15 @@
613 char *zNewPw = sha1_shared_secret(zNew1, g.zLogin, 0);
614 char *zChngPw;
615 char *zErr;
616 int rc;
617
 
 
 
 
 
618 db_unprotect(PROTECT_USER);
619 db_multi_exec(
620 "UPDATE user SET pw=%Q WHERE uid=%d", zNewPw, g.userUid
621 );
622 zChngPw = mprintf(
@@ -627,10 +647,16 @@
627 zNew1, g.zLogin, g.zLogin
628 );
629 fossil_free(zNewPw);
630 rc = login_group_sql(zChngPw, "<p>", "</p>\n", &zErr);
631 db_protect_pop();
 
 
 
 
 
 
632 if( rc ){
633 zErrMsg = mprintf("<span class=\"loginError\">%s</span>", zErr);
634 fossil_free(zErr);
635 }else{
636 redirect_to_g();
@@ -770,10 +796,16 @@
770 if( !noAnon && login_self_register_available(0) ){
771 @ <tr>
772 @ <td></td>
773 @ <td><input type="submit" name="self" value="Create A New Account">
774 @ </tr>
 
 
 
 
 
 
775 }
776 @ </table>
777 if( zAnonPw && !noAnon ){
778 const char *zDecoded = captcha_decode(uSeed);
779 int bAutoCaptcha = db_get_boolean("auto-captcha", 0);
@@ -828,10 +860,245 @@
828 @ </form>
829 }
830 }
831 style_finish_page();
832 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
833
834 /*
835 ** Attempt to find login credentials for user zLogin on a peer repository
836 ** with project code zCode. Transfer those credentials to the local
837 ** repository.
@@ -999,11 +1266,10 @@
999 void login_check_credentials(void){
1000 int uid = 0; /* User id */
1001 const char *zCookie; /* Text of the login cookie */
1002 const char *zIpAddr; /* Raw IP address of the requestor */
1003 const char *zCap = 0; /* Capability string */
1004 const char *zPublicPages = 0; /* GLOB patterns of public pages */
1005 const char *zLogin = 0; /* Login user for credentials */
1006
1007 /* Only run this check once. */
1008 if( g.userUid!=0 ) return;
1009
@@ -1139,10 +1405,21 @@
1139 zCap = "";
1140 }
1141 sqlite3_snprintf(sizeof(g.zCsrfToken), g.zCsrfToken, "none");
1142 }
1143
 
 
 
 
 
 
 
 
 
 
 
1144 /* At this point, we know that uid!=0. Find the privileges associated
1145 ** with user uid.
1146 */
1147 assert( uid!=0 );
1148 if( zCap==0 ){
@@ -1219,10 +1496,11 @@
1219 if( glob_match(pGlob, zUri) ){
1220 login_set_capabilities(db_get("default-perms", "u"), 0);
1221 }
1222 glob_free(pGlob);
1223 }
 
1224 }
1225
1226 /*
1227 ** Memory of settings
1228 */
@@ -1557,10 +1835,75 @@
1557 zUserID, zUserID, zUserID
1558 );
1559 return rc;
1560 }
1561
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1562 /*
1563 ** Check an email address and confirm that it is valid for self-registration.
1564 ** The email address is known already to be well-formed. Return true
1565 ** if the email address is on the allowed list.
1566 **
@@ -1598,21 +1941,29 @@
1598 const char *zDName;
1599 unsigned int uSeed;
1600 const char *zDecoded;
1601 int iErrLine = -1;
1602 const char *zErr = 0;
 
1603 int captchaIsCorrect = 0; /* True on a correct captcha */
1604 char *zCaptcha = ""; /* Value of the captcha text */
1605 char *zPerms; /* Permissions for the default user */
1606 int canDoAlerts = 0; /* True if receiving email alerts is possible */
1607 int doAlerts = 0; /* True if subscription is wanted too */
 
1608 if( !db_get_boolean("self-register", 0) ){
1609 style_header("Registration not possible");
1610 @ <p>This project does not allow user self-registration. Please contact the
1611 @ project administrator to obtain an account.</p>
1612 style_finish_page();
1613 return;
 
 
 
 
 
 
1614 }
1615 zPerms = db_get("default-perms", "u");
1616
1617 /* Prompt the user for email alerts if this repository is configured for
1618 ** email alerts and if the default permissions include "7" */
@@ -1656,26 +2007,16 @@
1656 iErrLine = 4;
1657 zErr = "Password must be at least 6 characters long";
1658 }else if( fossil_strcmp(zPasswd,zConfirm)!=0 ){
1659 iErrLine = 5;
1660 zErr = "Passwords do not match";
 
 
 
1661 }else if( login_self_choosen_userid_already_exists(zUserID) ){
1662 iErrLine = 1;
1663 zErr = "This User ID is already taken. Choose something different.";
1664 }else if(
1665 /* If the email is found anywhere in USER.INFO... */
1666 db_exists("SELECT 1 FROM user WHERE info LIKE '%%%q%%'", zEAddr)
1667 ||
1668 /* Or if the email is a verify subscriber email with an associated
1669 ** user... */
1670 (alert_tables_exist() &&
1671 db_exists(
1672 "SELECT 1 FROM subscriber WHERE semail=%Q AND suname IS NOT NULL"
1673 " AND sverified",zEAddr))
1674 ){
1675 iErrLine = 3;
1676 zErr = "This email address is already claimed by another user";
1677 }else{
1678 /* If all of the tests above have passed, that means that the submitted
1679 ** form contains valid data and we can proceed to create the new login */
1680 Blob sql;
1681 int uid;
@@ -1809,11 +2150,17 @@
1809 @ <td class="form_label" align="right" id="emaddr">Email Address:</td>
1810 @ <td><input aria-labelledby="emaddr" type="text" name="ea" \
1811 @ value="%h(zEAddr)" size="30"></td>
1812 @ </tr>
1813 if( iErrLine==3 ){
1814 @ <tr><td><td><span class='loginError'>&uarr; %h(zErr)</span></td></tr>
 
 
 
 
 
 
1815 }
1816 if( canDoAlerts ){
1817 int a = atoi(PD("alerts","1"));
1818 @ <tr>
1819 @ <td class="form_label" align="right" id="emalrt">Email&nbsp;Alerts?</td>
@@ -1865,10 +2212,151 @@
1865 @ </form>
1866 style_finish_page();
1867
1868 free(zCaptcha);
1869 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1870
1871 /*
1872 ** Run SQL on the repository database for every repository in our
1873 ** login group. The SQL is run in a separate database connection.
1874 **
1875
--- src/login.c
+++ src/login.c
@@ -510,10 +510,19 @@
510 zPattern = mprintf("%s/login*", g.zBaseURL);
511 rc = sqlite3_strglob(zPattern, zReferer)==0;
512 fossil_free(zPattern);
513 return rc;
514 }
515
516 /*
517 ** Return true if users are allowed to reset their own passwords.
518 */
519 int login_self_password_reset_available(void){
520 if( !db_get_boolean("self-pw-reset",0) ) return 0;
521 if( !alert_tables_exist() ) return 0;
522 return 1;
523 }
524
525 /*
526 ** Return TRUE if self-registration is available. If the zNeeded
527 ** argument is not NULL, then only return true if self-registration is
528 ** available and any of the capabilities named in zNeeded are available
@@ -560,10 +569,16 @@
569 const int noAnon = P("noanon")!=0;
570 int rememberMe; /* If true, use persistent cookie, else
571 session cookie. Toggled per
572 checkbox. */
573
574 if( P("pwreset")!=0 && login_self_password_reset_available() ){
575 /* If the "Reset Password" button in the form was pressed, render
576 ** the Request Password Reset page in place of this one. */
577 login_reqpwreset_page();
578 return;
579 }
580 login_check_credentials();
581 fossil_redirect_to_https_if_needed(1);
582 sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
583 constant_time_cmp_function, 0, 0);
584 zUsername = P("u");
@@ -613,10 +628,15 @@
628 char *zNewPw = sha1_shared_secret(zNew1, g.zLogin, 0);
629 char *zChngPw;
630 char *zErr;
631 int rc;
632
633 /* vvvvvvv--- tag-20230106-1 ----vvvvvv
634 **
635 ** Replicate changes made below to tag-20230106-2
636 */
637 admin_log("password change for user %s", g.zLogin);
638 db_unprotect(PROTECT_USER);
639 db_multi_exec(
640 "UPDATE user SET pw=%Q WHERE uid=%d", zNewPw, g.userUid
641 );
642 zChngPw = mprintf(
@@ -627,10 +647,16 @@
647 zNew1, g.zLogin, g.zLogin
648 );
649 fossil_free(zNewPw);
650 rc = login_group_sql(zChngPw, "<p>", "</p>\n", &zErr);
651 db_protect_pop();
652 /*
653 ** ^^^^^^^^--- tag-20230106-1 ----^^^^^^^^^
654 **
655 ** Replicate changes above to tag-20230106-2
656 */
657
658 if( rc ){
659 zErrMsg = mprintf("<span class=\"loginError\">%s</span>", zErr);
660 fossil_free(zErr);
661 }else{
662 redirect_to_g();
@@ -770,10 +796,16 @@
796 if( !noAnon && login_self_register_available(0) ){
797 @ <tr>
798 @ <td></td>
799 @ <td><input type="submit" name="self" value="Create A New Account">
800 @ </tr>
801 }
802 if( login_self_password_reset_available() ){
803 @ <tr>
804 @ <td></td>
805 @ <td><input type="submit" name="pwreset" value="Reset My Password">
806 @ </tr>
807 }
808 @ </table>
809 if( zAnonPw && !noAnon ){
810 const char *zDecoded = captcha_decode(uSeed);
811 int bAutoCaptcha = db_get_boolean("auto-captcha", 0);
@@ -828,10 +860,245 @@
860 @ </form>
861 }
862 }
863 style_finish_page();
864 }
865
866 /*
867 ** Construct an appropriate URL suffix for the /resetpw page. The
868 ** suffix will be of the form:
869 **
870 ** UID-TIMESTAMP-HASH
871 **
872 ** Where UID and TIMESTAMP are the parameters to this function, and HASH
873 ** is constructed from information that is unique to the user in question
874 ** and which is not publicly available. In particular, the HASH includes
875 ** the existing user password. Thus, in order to construct a URL that can
876 ** change a password, an attacker must know the current password, in which
877 ** case the attacker does not need to construct the URL in order to take
878 ** over the account.
879 **
880 ** Return a pointer to the resulting string in memory obtained
881 ** from fossil_malloc().
882 */
883 char *login_resetpw_suffix(int uid, i64 timestamp){
884 char *zHash;
885 char *zInnerSql;
886 char *zResult;
887 extern int sqlite3_shathree_init(sqlite3*,char**,const sqlite3_api_routines*);
888 if( timestamp<=0 ){ timestamp = time(0); }
889 sqlite3_shathree_init(g.db, 0, 0);
890 if( db_table_exists("repository","subscriber") ){
891 zInnerSql = mprintf(
892 "SELECT %lld, login, pw, cookie, user.mtime, user.info, subscriberCode"
893 " FROM user LEFT JOIN subscriber ON suname=login"
894 " WHERE uid=%d", timestamp, uid);
895 }else{
896 zInnerSql = mprintf(
897 "SELECT %lld, login, pw, cookie, user.mtime, user.info"
898 " FROM user WHERE uid=%d", timestamp, uid);
899 }
900 zHash = db_text(0, "SELECT lower(hex(sha3_query(%Q)))", zInnerSql);
901 fossil_free(zInnerSql);
902 zResult = mprintf("%x-%llx-%s", uid, timestamp, zHash);
903 if( strlen(zHash)<64 || strlen(zResult)<70 ){
904 /* This should never happen, but if it does, we don't want it to lead
905 ** to a security breach. */
906 fossil_panic("insecure password reset hash generated\n");
907 }
908 fossil_free(zHash);
909 return zResult;
910 }
911
912 /*
913 ** Check to see if the "name" query parameter is a valid resetpw suffix
914 ** for a user whose password we are allowed to reset. If it is, then return
915 ** the positive integer UID for that user. If the query parameter is not
916 ** valid, return 0.
917 */
918 static int login_resetpw_suffix_is_valid(const char *zName){
919 int i, j;
920 int uid;
921 i64 timestamp;
922 i64 now;
923 char *zHash;
924 if( zName==0 || strlen(zName)<70 ) goto not_valid_suffix;
925 for(i=0; fossil_isxdigit(zName[i]); i++){}
926 if( i<1 || zName[i]!='-' ) goto not_valid_suffix;
927 for(j=i+1; fossil_isxdigit(zName[j]); j++){}
928 if( j<=i+1 || zName[j]!='-' ) goto not_valid_suffix;
929 uid = strtol(zName, 0, 16);
930 if( uid<=0 ) goto not_valid_suffix;
931 if( !db_exists("SELECT 1 FROM user WHERE uid=%d", uid) ){
932 goto not_valid_suffix;
933 }
934 timestamp = strtoll(&zName[i+1], 0, 16);
935 now = time(0);
936 if( timestamp+3600 <= now ) goto not_valid_suffix;
937 zHash = login_resetpw_suffix(uid,timestamp);
938 if( fossil_strcmp(zHash, zName)!=0 ){
939 fossil_free(zHash);
940 goto not_valid_suffix;
941 }
942 fossil_free(zHash);
943 return uid;
944
945 not_valid_suffix:
946 return 0;
947 }
948
949 /*
950 ** COMMAND: test-resetpw-url
951 ** Usage: fossil test-resetpw-url UID
952 **
953 ** Generate and verify a /resetpw URL for user UID.
954 **
955 ** This command is intended for unit testing the login_resetpw_suffix()
956 ** and login_resetpw_suffix_is_valid() functions.
957 */
958 void test_resetpw_url(void){
959 char *zSuffix;
960 int uid;
961 int xuid;
962 char *zLogin;
963 int i;
964 db_find_and_open_repository(0, 0);
965 verify_all_options();
966 if( g.argc<3 ){
967 usage("UID ...");
968 }
969 for(i=2; i<g.argc; i++){
970 uid = atoi(g.argv[i]);
971 zSuffix = login_resetpw_suffix(uid, 0);
972 xuid = login_resetpw_suffix_is_valid(zSuffix);
973 if( xuid>0 ){
974 zLogin = db_text(0, "SELECT login FROM user WHERE uid=%d", xuid);
975 }else{
976 zLogin = 0;
977 }
978 fossil_print("/resetpw/%s %d (%s)\n",
979 zSuffix, xuid, zLogin ? zLogin : "???");
980 fossil_free(zSuffix);
981 fossil_free(zLogin);
982 }
983 }
984
985 /*
986 ** WEBPAGE: resetpw
987 **
988 ** The URL format must be like this:
989 **
990 ** /resetpw/UID-TIMESTAMP-HASH
991 **
992 ** Where UID is the uid of the user whose password is to be reset,
993 ** TIMESTAMP is the unix timestamp when the request was made, and
994 ** HASH is a hash based on UID, TIMESTAMP, and other information that
995 ** is unavailable to an attacher.
996 **
997 ** With no other arguments, a form is present which allows the user to
998 ** enter a new password. When the SUBMIT button is pressed, a POST request
999 ** back to the same URL that will change the password.
1000 */
1001 void login_resetpw(void){
1002 const char *zName;
1003 int uid;
1004 char *zRPW;
1005 const char *zNew1, *zNew2;
1006
1007 style_set_current_feature("resetpw");
1008 style_header("Reset Password");
1009 style_adunit_config(ADUNIT_OFF);
1010 zName = PD("name","");
1011 uid = login_resetpw_suffix_is_valid(zName);
1012 if( uid==0 ){
1013 @ <p><span class="loginError">
1014 @ This password-reset URL is invalid, probably because it has expired.
1015 @ Password-reset URLs have a short lifespan.
1016 @ </span></p>
1017 style_finish_page();
1018 sleep(1); /* Introduce a small delay on an invalid suffix as an
1019 ** extra defense against search attacks */
1020 return;
1021 }
1022 fossil_redirect_to_https_if_needed(1);
1023 login_set_uid(uid, 0);
1024 if( g.perm.Setup || g.perm.Admin || !g.perm.Password || g.zLogin==0 ){
1025 @ <p><span class="loginError">
1026 @ Cannot change the password for user <b>%h(g.zLogin)</b>.
1027 @ </span></p>
1028 style_finish_page();
1029 return;
1030 }
1031 if( (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 ){
1032 if( fossil_strcmp(zNew1,zNew2)!=0 ){
1033 @ <p><span class="loginError">
1034 @ The two copies of your new passwords do not match.
1035 @ Try again.
1036 @ </span></p>
1037 }else{
1038 char *zNewPw = sha1_shared_secret(zNew1, g.zLogin, 0);
1039 char *zChngPw;
1040 char *zErr;
1041 int rc;
1042
1043 /* vvvvvvv--- tag-20230106-2 ----vvvvvv
1044 **
1045 ** Replicate changes made below to tag-20230106-1
1046 */
1047 admin_log("password change for user %s", g.zLogin);
1048 db_unprotect(PROTECT_USER);
1049 db_multi_exec(
1050 "UPDATE user SET pw=%Q WHERE uid=%d", zNewPw, g.userUid
1051 );
1052 zChngPw = mprintf(
1053 "UPDATE user"
1054 " SET pw=shared_secret(%Q,%Q,"
1055 " (SELECT value FROM config WHERE name='project-code'))"
1056 " WHERE login=%Q",
1057 zNew1, g.zLogin, g.zLogin
1058 );
1059 fossil_free(zNewPw);
1060 rc = login_group_sql(zChngPw, "<p>", "</p>\n", &zErr);
1061 db_protect_pop();
1062 /*
1063 ** ^^^^^^^^--- tag-20230106-2 ----^^^^^^^^^
1064 **
1065 ** Replicate changes above to tag-20230106-1
1066 */
1067
1068 if( rc ){
1069 @ <p><span class='loginError'>
1070 @ %s(zErr);
1071 @ </span></p>
1072 fossil_free(zErr);
1073 }else{
1074 @ <p>Password changed successfully. Go to the
1075 @ <a href="%R/login?u=%t(g.zLogin)">Login</a> page and log in
1076 @ using the new password to continue.
1077 @ </p>
1078 style_finish_page();
1079 return;
1080 }
1081 }
1082 }
1083 zRPW = fossil_random_password(12);
1084 @ <p>Change Password for user <b>%h(g.zLogin)</b>:</p>
1085 form_begin(0, "%R/resetpw");
1086 @ <input type='hidden' name='name' value='%h(zName)'>
1087 @ <table>
1088 @ <tr><td class="form_label" id="newpw">New Password:</td>
1089 @ <td><input aria-labelledby="newpw" type="password" name="n1" \
1090 @ size="30" /> Suggestion: %z(zRPW)</td></tr>
1091 @ <tr><td class="form_label" id="reppw">Repeat New Password:</td>
1092 @ <td><input aria-labledby="reppw" type="password" name="n2" \
1093 @ size="30" /></td></tr>
1094 @ <tr><td></td>
1095 @ <td><input type="submit" value="Change Password" /></td></tr>
1096 @ </table>
1097 @ </form>
1098 style_finish_page();
1099 }
1100
1101 /*
1102 ** Attempt to find login credentials for user zLogin on a peer repository
1103 ** with project code zCode. Transfer those credentials to the local
1104 ** repository.
@@ -999,11 +1266,10 @@
1266 void login_check_credentials(void){
1267 int uid = 0; /* User id */
1268 const char *zCookie; /* Text of the login cookie */
1269 const char *zIpAddr; /* Raw IP address of the requestor */
1270 const char *zCap = 0; /* Capability string */
 
1271 const char *zLogin = 0; /* Login user for credentials */
1272
1273 /* Only run this check once. */
1274 if( g.userUid!=0 ) return;
1275
@@ -1139,10 +1405,21 @@
1405 zCap = "";
1406 }
1407 sqlite3_snprintf(sizeof(g.zCsrfToken), g.zCsrfToken, "none");
1408 }
1409
1410 login_set_uid(uid, zCap);
1411 }
1412
1413 /*
1414 ** Set the current logged in user to be uid. zCap is precomputed
1415 ** (override) capabilities. If zCap==0, then look up the capabilities
1416 ** in the USER table.
1417 */
1418 int login_set_uid(int uid, const char *zCap){
1419 const char *zPublicPages = 0; /* GLOB patterns of public pages */
1420
1421 /* At this point, we know that uid!=0. Find the privileges associated
1422 ** with user uid.
1423 */
1424 assert( uid!=0 );
1425 if( zCap==0 ){
@@ -1219,10 +1496,11 @@
1496 if( glob_match(pGlob, zUri) ){
1497 login_set_capabilities(db_get("default-perms", "u"), 0);
1498 }
1499 glob_free(pGlob);
1500 }
1501 return g.zLogin!=0;
1502 }
1503
1504 /*
1505 ** Memory of settings
1506 */
@@ -1557,10 +1835,75 @@
1835 zUserID, zUserID, zUserID
1836 );
1837 return rc;
1838 }
1839
1840 /*
1841 ** zEMail is an email address. (Example: "[email protected]".) This routine
1842 ** searches for a user or subscriber that has that email address. If the
1843 ** email address is used no-where in the system, return 0. If the email
1844 ** address is assigned to a particular user return the UID for that user.
1845 ** If the email address is used, but not by a particular user, return -1.
1846 */
1847 static int email_address_in_use(const char *zEMail){
1848 int uid;
1849 uid = db_int(0,
1850 "SELECT uid FROM user"
1851 " WHERE info LIKE '%%<%q>%%'", zEMail);
1852 if( uid>0 ){
1853 if( db_exists("SELECT 1 FROM user WHERE uid=%d AND ("
1854 " cap GLOB '*[as]*' OR"
1855 " find_emailaddr(info)<>%Q COLLATE nocase)",
1856 uid, zEMail) ){
1857 uid = -1;
1858 }
1859 }
1860 if( uid==0 && alert_tables_exist() ){
1861 uid = db_int(0,
1862 "SELECT user.uid FROM subscriber JOIN user ON login=suname"
1863 " WHERE semail=%Q AND sverified", zEMail);
1864 if( uid ){
1865 if( db_exists("SELECT 1 FROM user WHERE uid=%d AND "
1866 " cap GLOB '*[as]*'",
1867 uid) ){
1868 uid = -1;
1869 }
1870 }
1871 }
1872 return uid;
1873 }
1874
1875 /*
1876 ** COMMAND: test-email-used
1877 ** Usage: fossil test-email-used EMAIL ...
1878 **
1879 ** Given a list of email addresses, show the UID and LOGIN associated
1880 ** with each one.
1881 */
1882 void test_email_used(void){
1883 int i;
1884 db_find_and_open_repository(0, 0);
1885 verify_all_options();
1886 if( g.argc<3 ){
1887 usage("EMAIL ...");
1888 }
1889 for(i=2; i<g.argc; i++){
1890 const char *zEMail = g.argv[i];
1891 int uid = email_address_in_use(zEMail);
1892 if( uid==0 ){
1893 fossil_print("%s: not used\n", zEMail);
1894 }else if( uid<0 ){
1895 fossil_print("%s: used but no password reset is available\n", zEMail);
1896 }else{
1897 char *zLogin = db_text(0, "SELECT login FROM user WHERE uid=%d", uid);
1898 fossil_print("%s: UID %d (%s)\n", zEMail, uid, zLogin);
1899 fossil_free(zLogin);
1900 }
1901 }
1902 }
1903
1904
1905 /*
1906 ** Check an email address and confirm that it is valid for self-registration.
1907 ** The email address is known already to be well-formed. Return true
1908 ** if the email address is on the allowed list.
1909 **
@@ -1598,21 +1941,29 @@
1941 const char *zDName;
1942 unsigned int uSeed;
1943 const char *zDecoded;
1944 int iErrLine = -1;
1945 const char *zErr = 0;
1946 int uid = 0; /* User id with the same email */
1947 int captchaIsCorrect = 0; /* True on a correct captcha */
1948 char *zCaptcha = ""; /* Value of the captcha text */
1949 char *zPerms; /* Permissions for the default user */
1950 int canDoAlerts = 0; /* True if receiving email alerts is possible */
1951 int doAlerts = 0; /* True if subscription is wanted too */
1952
1953 if( !db_get_boolean("self-register", 0) ){
1954 style_header("Registration not possible");
1955 @ <p>This project does not allow user self-registration. Please contact the
1956 @ project administrator to obtain an account.</p>
1957 style_finish_page();
1958 return;
1959 }
1960 if( P("pwreset")!=0 && login_self_password_reset_available() ){
1961 /* The "Request Password Reset" button was pressed, so render the
1962 ** "Request Password Reset" page instead of this one. */
1963 login_reqpwreset_page();
1964 return;
1965 }
1966 zPerms = db_get("default-perms", "u");
1967
1968 /* Prompt the user for email alerts if this repository is configured for
1969 ** email alerts and if the default permissions include "7" */
@@ -1656,26 +2007,16 @@
2007 iErrLine = 4;
2008 zErr = "Password must be at least 6 characters long";
2009 }else if( fossil_strcmp(zPasswd,zConfirm)!=0 ){
2010 iErrLine = 5;
2011 zErr = "Passwords do not match";
2012 }else if( (uid = email_address_in_use(zEAddr))!=0 ){
2013 iErrLine = 3;
2014 zErr = "This email address is already associated with a user";
2015 }else if( login_self_choosen_userid_already_exists(zUserID) ){
2016 iErrLine = 1;
2017 zErr = "This User ID is already taken. Choose something different.";
 
 
 
 
 
 
 
 
 
 
 
 
 
2018 }else{
2019 /* If all of the tests above have passed, that means that the submitted
2020 ** form contains valid data and we can proceed to create the new login */
2021 Blob sql;
2022 int uid;
@@ -1809,11 +2150,17 @@
2150 @ <td class="form_label" align="right" id="emaddr">Email Address:</td>
2151 @ <td><input aria-labelledby="emaddr" type="text" name="ea" \
2152 @ value="%h(zEAddr)" size="30"></td>
2153 @ </tr>
2154 if( iErrLine==3 ){
2155 @ <tr><td><td><span class='loginError'>&uarr; %h(zErr)</span>
2156 if( uid>0 && login_self_password_reset_available() ){
2157 @ <br />
2158 @ <input type="submit" name="pwreset" \
2159 @ value="Request Password Reset For %h(zEAddr)">
2160 }
2161 @ </td></tr>
2162 }
2163 if( canDoAlerts ){
2164 int a = atoi(PD("alerts","1"));
2165 @ <tr>
2166 @ <td class="form_label" align="right" id="emalrt">Email&nbsp;Alerts?</td>
@@ -1865,10 +2212,151 @@
2212 @ </form>
2213 style_finish_page();
2214
2215 free(zCaptcha);
2216 }
2217
2218 /*
2219 ** WEBPAGE: reqpwreset
2220 **
2221 ** A web page to request a password reset.
2222 */
2223 void login_reqpwreset_page(void){
2224 const char *zEAddr;
2225 const char *zDecoded;
2226 unsigned int uSeed;
2227 int iErrLine = -1;
2228 const char *zErr = 0;
2229 int uid = 0; /* User id with the email zEAddr */
2230 int captchaIsCorrect = 0; /* True on a correct captcha */
2231 char *zCaptcha = ""; /* Value of the captcha text */
2232
2233 if( !login_self_password_reset_available() ){
2234 style_header("Password reset not possible");
2235 @ <p>This project does not allow users to reset their own passwords.
2236 @ If you need a password reset, you will have to negotiate that directly
2237 @ with the project administrator.
2238 style_finish_page();
2239 return;
2240 }
2241 zEAddr = PDT("ea","");
2242
2243 /* Verify user imputs */
2244 if( !cgi_csrf_safe(1) || P("reqpwreset")==0 ){
2245 /* This is the initial display of the form. No processing or error
2246 ** checking is to be done. Fall through into the form display
2247 */
2248 }else if( (captchaIsCorrect = captcha_is_correct(1))==0 ){
2249 iErrLine = 2;
2250 zErr = "Incorrect CAPTCHA";
2251 }else if( zEAddr[0]==0 ){
2252 iErrLine = 1;
2253 zErr = "Required";
2254 }else if( email_address_is_valid(zEAddr,0)==0 ){
2255 iErrLine = 1;
2256 zErr = "Not a valid email address";
2257 }else if( authorized_subscription_email(zEAddr)==0 ){
2258 iErrLine = 1;
2259 zErr = "Not an authorized email address";
2260 }else if( (uid = email_address_in_use(zEAddr))<=0 ){
2261 iErrLine = 1;
2262 zErr = "This email address is not associated with a user who has "
2263 "password reset privileges.";
2264 }else if( login_set_uid(uid,0)==0 || g.perm.Admin || g.perm.Setup
2265 || !g.perm.Password ){
2266 iErrLine = 1;
2267 zErr = "This email address is not associated with a user who has "
2268 "password reset privileges.";
2269 }else{
2270
2271 /* If all of the tests above have passed, that means that the submitted
2272 ** form contains valid data and we can proceed to issue the password
2273 ** reset email. */
2274 Blob hdr, body;
2275 AlertSender *pSender;
2276 char *zUrl = login_resetpw_suffix(uid, 0);
2277 pSender = alert_sender_new(0,0);
2278 blob_init(&hdr,0,0);
2279 blob_init(&body,0,0);
2280 blob_appendf(&hdr, "To: <%s>\n", zEAddr);
2281 blob_appendf(&hdr, "Subject: Password reset for %s\n", g.zBaseURL);
2282 blob_appendf(&body,
2283 "Someone has requested to reset the password for user \"%s\"\n",
2284 g.zLogin);
2285 blob_appendf(&body, "at %s.\n\n", g.zBaseURL);
2286 blob_appendf(&body,
2287 "If you did not request this password reset, ignore\n"
2288 "this email\n\n");
2289 blob_appendf(&body,
2290 "To reset the password, visit the following link:\n\n"
2291 " %s/resetpw/%s\n\n", g.zBaseURL, zUrl);
2292 fossil_free(zUrl);
2293 alert_send(pSender, &hdr, &body, 0);
2294 style_header("Email Verification");
2295 if( pSender->zErr ){
2296 @ <h1>Internal Error</h1>
2297 @ <p>The following internal error was encountered while trying
2298 @ to send the confirmation email:
2299 @ <blockquote><pre>
2300 @ %h(pSender->zErr)
2301 @ </pre></blockquote>
2302 }else{
2303 @ <p>An email containing a hyperlink that can be used to reset
2304 @ your password has been sent to "%h(zEAddr)".</p>
2305 }
2306 alert_sender_free(pSender);
2307 style_finish_page();
2308 return;
2309 }
2310
2311 /* Prepare the captcha. */
2312 if( captchaIsCorrect ){
2313 uSeed = strtoul(P("captchaseed"),0,10);
2314 }else{
2315 uSeed = captcha_seed();
2316 }
2317 zDecoded = captcha_decode(uSeed);
2318 zCaptcha = captcha_render(zDecoded);
2319
2320 style_header("Request Password Reset");
2321 /* Print out the registration form. */
2322 g.perm.Hyperlink = 1; /* Artificially enable hyperlinks */
2323 form_begin(0, "%R/reqpwreset");
2324 @ <p><input type="hidden" name="captchaseed" value="%u(uSeed)" />
2325 @ <p><input type="hidden" name="reqpwreset" value="1" />
2326 @ <table class="login_out">
2327 @ <tr>
2328 @ <td class="form_label" align="right" id="emaddr">Email Address:</td>
2329 @ <td><input aria-labelledby="emaddr" type="text" name="ea" \
2330 @ value="%h(zEAddr)" size="30"></td>
2331 @ </tr>
2332 if( iErrLine==1 ){
2333 @ <tr><td><td><span class='loginError'>&uarr; %h(zErr)</span></td></tr>
2334 }
2335 @ <tr>
2336 @ <td class="form_label" align="right" id="cptcha">Captcha:</td>
2337 @ <td><input type="text" name="captcha" aria-labelledby="cptcha" \
2338 @ value="%h(captchaIsCorrect?zDecoded:"")" size="30">
2339 captcha_speakit_button(uSeed, "Speak the captcha text");
2340 @ </td>
2341 @ </tr>
2342 if( iErrLine==2 ){
2343 @ <tr><td><td><span class='loginError'>&uarr; %h(zErr)</span></td></tr>
2344 }
2345 @ <tr><td></td>
2346 @ <td><input type="submit" name="new" value="Request Password Reset"/>\
2347 @ </td></tr>
2348 @ </table>
2349 @ <div class="captcha"><table class="captcha"><tr><td><pre class="captcha">
2350 @ %h(zCaptcha)
2351 @ </pre>
2352 @ Enter this 8-letter code in the "Captcha" box above.
2353 @ </td></tr></table></div>
2354 @ </form>
2355 style_finish_page();
2356 free(zCaptcha);
2357 }
2358
2359 /*
2360 ** Run SQL on the repository database for every repository in our
2361 ** login group. The SQL is run in a separate database connection.
2362 **
2363
+1 -1
--- src/main.c
+++ src/main.c
@@ -2902,11 +2902,11 @@
29022902
** to use a different command for "ssh" sync, but we cannot do that without
29032903
** breaking legacy.
29042904
**
29052905
** Options:
29062906
** --test Do not do special "sync" processing when operating
2907
-** over an SSH link.
2907
+** over an SSH link
29082908
** --th-trace Trace TH1 execution (for debugging purposes)
29092909
** --usercap CAP User capability string (Default: "sxy")
29102910
**
29112911
*/
29122912
void cmd_test_http(void){
29132913
--- src/main.c
+++ src/main.c
@@ -2902,11 +2902,11 @@
2902 ** to use a different command for "ssh" sync, but we cannot do that without
2903 ** breaking legacy.
2904 **
2905 ** Options:
2906 ** --test Do not do special "sync" processing when operating
2907 ** over an SSH link.
2908 ** --th-trace Trace TH1 execution (for debugging purposes)
2909 ** --usercap CAP User capability string (Default: "sxy")
2910 **
2911 */
2912 void cmd_test_http(void){
2913
--- src/main.c
+++ src/main.c
@@ -2902,11 +2902,11 @@
2902 ** to use a different command for "ssh" sync, but we cannot do that without
2903 ** breaking legacy.
2904 **
2905 ** Options:
2906 ** --test Do not do special "sync" processing when operating
2907 ** over an SSH link
2908 ** --th-trace Trace TH1 execution (for debugging purposes)
2909 ** --usercap CAP User capability string (Default: "sxy")
2910 **
2911 */
2912 void cmd_test_http(void){
2913
--- src/manifest.c
+++ src/manifest.c
@@ -1290,11 +1290,10 @@
12901290
** artifacts and report any errors. Run this test command on historical
12911291
** repositories after making any changes to the manifest_parse()
12921292
** implementation to confirm that the changes did not break anything.
12931293
**
12941294
** Options:
1295
-**
12961295
** --limit N Parse no more than N artifacts before stopping
12971296
** --wellformed Use all BLOB table entries as input, not just
12981297
** those entries that are believed to be valid
12991298
** artifacts, and verify that the result the
13001299
** manifest_is_well_formed() agrees with the
13011300
--- src/manifest.c
+++ src/manifest.c
@@ -1290,11 +1290,10 @@
1290 ** artifacts and report any errors. Run this test command on historical
1291 ** repositories after making any changes to the manifest_parse()
1292 ** implementation to confirm that the changes did not break anything.
1293 **
1294 ** Options:
1295 **
1296 ** --limit N Parse no more than N artifacts before stopping
1297 ** --wellformed Use all BLOB table entries as input, not just
1298 ** those entries that are believed to be valid
1299 ** artifacts, and verify that the result the
1300 ** manifest_is_well_formed() agrees with the
1301
--- src/manifest.c
+++ src/manifest.c
@@ -1290,11 +1290,10 @@
1290 ** artifacts and report any errors. Run this test command on historical
1291 ** repositories after making any changes to the manifest_parse()
1292 ** implementation to confirm that the changes did not break anything.
1293 **
1294 ** Options:
 
1295 ** --limit N Parse no more than N artifacts before stopping
1296 ** --wellformed Use all BLOB table entries as input, not just
1297 ** those entries that are believed to be valid
1298 ** artifacts, and verify that the result the
1299 ** manifest_is_well_formed() agrees with the
1300
-10
--- src/merge.c
+++ src/merge.c
@@ -295,41 +295,31 @@
295295
** Only file content is merged. The result continues to use the
296296
** file and directory names from the current check-out even if those
297297
** names might have been changed in the branch being merged in.
298298
**
299299
** Options:
300
-**
301300
** --backout Do a reverse cherrypick merge against VERSION.
302301
** In other words, back out the changes that were
303302
** added by VERSION.
304
-**
305303
** --baseline BASELINE Use BASELINE as the "pivot" of the merge instead
306304
** of the nearest common ancestor. This allows
307305
** a sequence of changes in a branch to be merged
308306
** without having to merge the entire branch.
309
-**
310307
** --binary GLOBPATTERN Treat files that match GLOBPATTERN as binary
311308
** and do not try to merge parallel changes. This
312309
** option overrides the "binary-glob" setting.
313
-**
314310
** --cherrypick Do a cherrypick merge VERSION into the current
315311
** check-out. A cherrypick merge pulls in the changes
316312
** of the single check-in VERSION, rather than all
317313
** changes back to the nearest common ancestor.
318
-**
319314
** -f|--force Force the merge even if it would be a no-op
320
-**
321315
** --force-missing Force the merge even if there is missing content
322
-**
323316
** --integrate Merged branch will be closed when committing
324
-**
325317
** -K|--keep-merge-files On merge conflict, retain the temporary files
326318
** used for merging, named *-baseline, *-original,
327319
** and *-merge.
328
-**
329320
** -n|--dry-run If given, display instead of run actions
330
-**
331321
** -v|--verbose Show additional details of the merge
332322
*/
333323
void merge_cmd(void){
334324
int vid; /* Current version "V" */
335325
int mid; /* Version we are merging from "M" */
336326
--- src/merge.c
+++ src/merge.c
@@ -295,41 +295,31 @@
295 ** Only file content is merged. The result continues to use the
296 ** file and directory names from the current check-out even if those
297 ** names might have been changed in the branch being merged in.
298 **
299 ** Options:
300 **
301 ** --backout Do a reverse cherrypick merge against VERSION.
302 ** In other words, back out the changes that were
303 ** added by VERSION.
304 **
305 ** --baseline BASELINE Use BASELINE as the "pivot" of the merge instead
306 ** of the nearest common ancestor. This allows
307 ** a sequence of changes in a branch to be merged
308 ** without having to merge the entire branch.
309 **
310 ** --binary GLOBPATTERN Treat files that match GLOBPATTERN as binary
311 ** and do not try to merge parallel changes. This
312 ** option overrides the "binary-glob" setting.
313 **
314 ** --cherrypick Do a cherrypick merge VERSION into the current
315 ** check-out. A cherrypick merge pulls in the changes
316 ** of the single check-in VERSION, rather than all
317 ** changes back to the nearest common ancestor.
318 **
319 ** -f|--force Force the merge even if it would be a no-op
320 **
321 ** --force-missing Force the merge even if there is missing content
322 **
323 ** --integrate Merged branch will be closed when committing
324 **
325 ** -K|--keep-merge-files On merge conflict, retain the temporary files
326 ** used for merging, named *-baseline, *-original,
327 ** and *-merge.
328 **
329 ** -n|--dry-run If given, display instead of run actions
330 **
331 ** -v|--verbose Show additional details of the merge
332 */
333 void merge_cmd(void){
334 int vid; /* Current version "V" */
335 int mid; /* Version we are merging from "M" */
336
--- src/merge.c
+++ src/merge.c
@@ -295,41 +295,31 @@
295 ** Only file content is merged. The result continues to use the
296 ** file and directory names from the current check-out even if those
297 ** names might have been changed in the branch being merged in.
298 **
299 ** Options:
 
300 ** --backout Do a reverse cherrypick merge against VERSION.
301 ** In other words, back out the changes that were
302 ** added by VERSION.
 
303 ** --baseline BASELINE Use BASELINE as the "pivot" of the merge instead
304 ** of the nearest common ancestor. This allows
305 ** a sequence of changes in a branch to be merged
306 ** without having to merge the entire branch.
 
307 ** --binary GLOBPATTERN Treat files that match GLOBPATTERN as binary
308 ** and do not try to merge parallel changes. This
309 ** option overrides the "binary-glob" setting.
 
310 ** --cherrypick Do a cherrypick merge VERSION into the current
311 ** check-out. A cherrypick merge pulls in the changes
312 ** of the single check-in VERSION, rather than all
313 ** changes back to the nearest common ancestor.
 
314 ** -f|--force Force the merge even if it would be a no-op
 
315 ** --force-missing Force the merge even if there is missing content
 
316 ** --integrate Merged branch will be closed when committing
 
317 ** -K|--keep-merge-files On merge conflict, retain the temporary files
318 ** used for merging, named *-baseline, *-original,
319 ** and *-merge.
 
320 ** -n|--dry-run If given, display instead of run actions
 
321 ** -v|--verbose Show additional details of the merge
322 */
323 void merge_cmd(void){
324 int vid; /* Current version "V" */
325 int mid; /* Version we are merging from "M" */
326
-1
--- src/name.c
+++ src/name.c
@@ -1063,11 +1063,10 @@
10631063
** Resolve the symbol NAME into its canonical artifact hash
10641064
** artifact name and provide a description of what role that artifact
10651065
** plays.
10661066
**
10671067
** Options:
1068
-**
10691068
** -f|--file Find artifacts with the same hash as file NAME.
10701069
** If NAME is "-", read content from standard input.
10711070
** --type TYPE Only find artifacts of TYPE (one of: 'ci', 't',
10721071
** 'w', 'g', or 'e')
10731072
** -v|--verbose Provide extra information (such as the RID)
10741073
--- src/name.c
+++ src/name.c
@@ -1063,11 +1063,10 @@
1063 ** Resolve the symbol NAME into its canonical artifact hash
1064 ** artifact name and provide a description of what role that artifact
1065 ** plays.
1066 **
1067 ** Options:
1068 **
1069 ** -f|--file Find artifacts with the same hash as file NAME.
1070 ** If NAME is "-", read content from standard input.
1071 ** --type TYPE Only find artifacts of TYPE (one of: 'ci', 't',
1072 ** 'w', 'g', or 'e')
1073 ** -v|--verbose Provide extra information (such as the RID)
1074
--- src/name.c
+++ src/name.c
@@ -1063,11 +1063,10 @@
1063 ** Resolve the symbol NAME into its canonical artifact hash
1064 ** artifact name and provide a description of what role that artifact
1065 ** plays.
1066 **
1067 ** Options:
 
1068 ** -f|--file Find artifacts with the same hash as file NAME.
1069 ** If NAME is "-", read content from standard input.
1070 ** --type TYPE Only find artifacts of TYPE (one of: 'ci', 't',
1071 ** 'w', 'g', or 'e')
1072 ** -v|--verbose Provide extra information (such as the RID)
1073
+3 -1
--- src/patch.c
+++ src/patch.c
@@ -845,17 +845,19 @@
845845
** Create a new binary patch in FILENAME that captures all uncommitted
846846
** changes in the check-out at DIRECTORY, or the current directory if
847847
** DIRECTORY is omitted. If FILENAME is "-" then the binary patch
848848
** is written to standard output.
849849
**
850
+** Options:
850851
** -f|--force Overwrite an existing patch with the same name
851852
**
852853
** > fossil patch apply [DIRECTORY] FILENAME
853854
**
854855
** Apply the changes in FILENAME to the check-out at DIRECTORY, or
855
-** in the current directory if DIRECTORY is omitted. Options:
856
+** in the current directory if DIRECTORY is omitted.
856857
**
858
+** Options:
857859
** -f|--force Apply the patch even though there are unsaved
858860
** changes in the current check-out. Unsaved changes
859861
** are reverted and permanently lost.
860862
** -n|--dry-run Do nothing, but print what would have happened
861863
** -v|--verbose Extra output explaining what happens
862864
--- src/patch.c
+++ src/patch.c
@@ -845,17 +845,19 @@
845 ** Create a new binary patch in FILENAME that captures all uncommitted
846 ** changes in the check-out at DIRECTORY, or the current directory if
847 ** DIRECTORY is omitted. If FILENAME is "-" then the binary patch
848 ** is written to standard output.
849 **
 
850 ** -f|--force Overwrite an existing patch with the same name
851 **
852 ** > fossil patch apply [DIRECTORY] FILENAME
853 **
854 ** Apply the changes in FILENAME to the check-out at DIRECTORY, or
855 ** in the current directory if DIRECTORY is omitted. Options:
856 **
 
857 ** -f|--force Apply the patch even though there are unsaved
858 ** changes in the current check-out. Unsaved changes
859 ** are reverted and permanently lost.
860 ** -n|--dry-run Do nothing, but print what would have happened
861 ** -v|--verbose Extra output explaining what happens
862
--- src/patch.c
+++ src/patch.c
@@ -845,17 +845,19 @@
845 ** Create a new binary patch in FILENAME that captures all uncommitted
846 ** changes in the check-out at DIRECTORY, or the current directory if
847 ** DIRECTORY is omitted. If FILENAME is "-" then the binary patch
848 ** is written to standard output.
849 **
850 ** Options:
851 ** -f|--force Overwrite an existing patch with the same name
852 **
853 ** > fossil patch apply [DIRECTORY] FILENAME
854 **
855 ** Apply the changes in FILENAME to the check-out at DIRECTORY, or
856 ** in the current directory if DIRECTORY is omitted.
857 **
858 ** Options:
859 ** -f|--force Apply the patch even though there are unsaved
860 ** changes in the current check-out. Unsaved changes
861 ** are reverted and permanently lost.
862 ** -n|--dry-run Do nothing, but print what would have happened
863 ** -v|--verbose Extra output explaining what happens
864
--- src/pikchrshow.c
+++ src/pikchrshow.c
@@ -525,11 +525,10 @@
525525
** an SVG graphic. The INFILE and OUTFILE options default to stdin
526526
** resp. stdout, and the names "-" can be used as aliases for those
527527
** streams.
528528
**
529529
** Options:
530
-**
531530
** -div On success, add a DIV wrapper around the
532531
** resulting SVG output which limits its max-width to
533532
** its computed maximum ideal size
534533
**
535534
** -div-indent Like -div but indent the div
536535
--- src/pikchrshow.c
+++ src/pikchrshow.c
@@ -525,11 +525,10 @@
525 ** an SVG graphic. The INFILE and OUTFILE options default to stdin
526 ** resp. stdout, and the names "-" can be used as aliases for those
527 ** streams.
528 **
529 ** Options:
530 **
531 ** -div On success, add a DIV wrapper around the
532 ** resulting SVG output which limits its max-width to
533 ** its computed maximum ideal size
534 **
535 ** -div-indent Like -div but indent the div
536
--- src/pikchrshow.c
+++ src/pikchrshow.c
@@ -525,11 +525,10 @@
525 ** an SVG graphic. The INFILE and OUTFILE options default to stdin
526 ** resp. stdout, and the names "-" can be used as aliases for those
527 ** streams.
528 **
529 ** Options:
 
530 ** -div On success, add a DIV wrapper around the
531 ** resulting SVG output which limits its max-width to
532 ** its computed maximum ideal size
533 **
534 ** -div-indent Like -div but indent the div
535
+1 -1
--- src/publish.c
+++ src/publish.c
@@ -31,11 +31,11 @@
3131
** will never push and hence will not be shared with collaborators.
3232
**
3333
** By default, this command only shows unpublished check-ins. To show
3434
** all unpublished artifacts, use the --all command-line option.
3535
**
36
-** OPTIONS:
36
+** Options:
3737
** --all Show all artifacts, not just check-ins
3838
*/
3939
void unpublished_cmd(void){
4040
int bAll = find_option("all",0,0)!=0;
4141
4242
--- src/publish.c
+++ src/publish.c
@@ -31,11 +31,11 @@
31 ** will never push and hence will not be shared with collaborators.
32 **
33 ** By default, this command only shows unpublished check-ins. To show
34 ** all unpublished artifacts, use the --all command-line option.
35 **
36 ** OPTIONS:
37 ** --all Show all artifacts, not just check-ins
38 */
39 void unpublished_cmd(void){
40 int bAll = find_option("all",0,0)!=0;
41
42
--- src/publish.c
+++ src/publish.c
@@ -31,11 +31,11 @@
31 ** will never push and hence will not be shared with collaborators.
32 **
33 ** By default, this command only shows unpublished check-ins. To show
34 ** all unpublished artifacts, use the --all command-line option.
35 **
36 ** Options:
37 ** --all Show all artifacts, not just check-ins
38 */
39 void unpublished_cmd(void){
40 int bAll = find_option("all",0,0)!=0;
41
42
--- src/regexp.c
+++ src/regexp.c
@@ -809,11 +809,10 @@
809809
**
810810
** Run a regular expression match over the named disk files, or against
811811
** standard input if no disk files are named on the command-line.
812812
**
813813
** Options:
814
-**
815814
** -i|--ignore-case Ignore case
816815
*/
817816
void re_test_grep(void){
818817
ReCompiled *pRe;
819818
const char *zErr;
@@ -853,11 +852,10 @@
853852
**
854853
** For details of the supported regular expression dialect, see
855854
** https://fossil-scm.org/fossil/doc/trunk/www/grep.md
856855
**
857856
** Options:
858
-**
859857
** -c|--count Suppress normal output; instead print a count
860858
** of the number of matching files
861859
** -i|--ignore-case Ignore case
862860
** -l|--files-with-matches List only hash for each match
863861
** --once Stop searching after the first match
864862
--- src/regexp.c
+++ src/regexp.c
@@ -809,11 +809,10 @@
809 **
810 ** Run a regular expression match over the named disk files, or against
811 ** standard input if no disk files are named on the command-line.
812 **
813 ** Options:
814 **
815 ** -i|--ignore-case Ignore case
816 */
817 void re_test_grep(void){
818 ReCompiled *pRe;
819 const char *zErr;
@@ -853,11 +852,10 @@
853 **
854 ** For details of the supported regular expression dialect, see
855 ** https://fossil-scm.org/fossil/doc/trunk/www/grep.md
856 **
857 ** Options:
858 **
859 ** -c|--count Suppress normal output; instead print a count
860 ** of the number of matching files
861 ** -i|--ignore-case Ignore case
862 ** -l|--files-with-matches List only hash for each match
863 ** --once Stop searching after the first match
864
--- src/regexp.c
+++ src/regexp.c
@@ -809,11 +809,10 @@
809 **
810 ** Run a regular expression match over the named disk files, or against
811 ** standard input if no disk files are named on the command-line.
812 **
813 ** Options:
 
814 ** -i|--ignore-case Ignore case
815 */
816 void re_test_grep(void){
817 ReCompiled *pRe;
818 const char *zErr;
@@ -853,11 +852,10 @@
852 **
853 ** For details of the supported regular expression dialect, see
854 ** https://fossil-scm.org/fossil/doc/trunk/www/grep.md
855 **
856 ** Options:
 
857 ** -c|--count Suppress normal output; instead print a count
858 ** of the number of matching files
859 ** -i|--ignore-case Ignore case
860 ** -l|--files-with-matches List only hash for each match
861 ** --once Stop searching after the first match
862
+2 -1
--- src/rss.c
+++ src/rss.c
@@ -230,12 +230,13 @@
230230
** COMMAND: rss*
231231
**
232232
** Usage: %fossil rss ?OPTIONS?
233233
**
234234
** The CLI variant of the /timeline.rss page, this produces an RSS
235
-** feed of the timeline to stdout. Options:
235
+** feed of the timeline to stdout.
236236
**
237
+** Options:
237238
** -type|y FLAG May be: all (default), ci (show check-ins only),
238239
** t (show tickets only), w (show wiki only)
239240
**
240241
** -limit|n LIMIT The maximum number of items to show
241242
**
242243
--- src/rss.c
+++ src/rss.c
@@ -230,12 +230,13 @@
230 ** COMMAND: rss*
231 **
232 ** Usage: %fossil rss ?OPTIONS?
233 **
234 ** The CLI variant of the /timeline.rss page, this produces an RSS
235 ** feed of the timeline to stdout. Options:
236 **
 
237 ** -type|y FLAG May be: all (default), ci (show check-ins only),
238 ** t (show tickets only), w (show wiki only)
239 **
240 ** -limit|n LIMIT The maximum number of items to show
241 **
242
--- src/rss.c
+++ src/rss.c
@@ -230,12 +230,13 @@
230 ** COMMAND: rss*
231 **
232 ** Usage: %fossil rss ?OPTIONS?
233 **
234 ** The CLI variant of the /timeline.rss page, this produces an RSS
235 ** feed of the timeline to stdout.
236 **
237 ** Options:
238 ** -type|y FLAG May be: all (default), ci (show check-ins only),
239 ** t (show tickets only), w (show wiki only)
240 **
241 ** -limit|n LIMIT The maximum number of items to show
242 **
243
--- src/search.c
+++ src/search.c
@@ -334,11 +334,10 @@
334334
**
335335
** Run the full-scan search algorithm using SEARCHSTRING against
336336
** the text of the files listed. Output matches and snippets.
337337
**
338338
** Options:
339
-**
340339
** --begin TEXT Text to insert before each match
341340
** --end TEXT Text to insert after each match
342341
** --gap TEXT Text to indicate elided content
343342
** --html Input is HTML
344343
** --static Use the static Search object
@@ -583,11 +582,10 @@
583582
** score. The -limit option can be used to limit the number of entries
584583
** returned. The -width option can be used to set the output width used
585584
** when printing matches.
586585
**
587586
** Options:
588
-**
589587
** -a|--all Output all matches, not just best matches
590588
** -n|--limit N Limit output to N matches
591589
** -W|--width WIDTH Set display width to WIDTH columns, 0 for
592590
** unlimited. Defaults the terminal's width.
593591
*/
594592
--- src/search.c
+++ src/search.c
@@ -334,11 +334,10 @@
334 **
335 ** Run the full-scan search algorithm using SEARCHSTRING against
336 ** the text of the files listed. Output matches and snippets.
337 **
338 ** Options:
339 **
340 ** --begin TEXT Text to insert before each match
341 ** --end TEXT Text to insert after each match
342 ** --gap TEXT Text to indicate elided content
343 ** --html Input is HTML
344 ** --static Use the static Search object
@@ -583,11 +582,10 @@
583 ** score. The -limit option can be used to limit the number of entries
584 ** returned. The -width option can be used to set the output width used
585 ** when printing matches.
586 **
587 ** Options:
588 **
589 ** -a|--all Output all matches, not just best matches
590 ** -n|--limit N Limit output to N matches
591 ** -W|--width WIDTH Set display width to WIDTH columns, 0 for
592 ** unlimited. Defaults the terminal's width.
593 */
594
--- src/search.c
+++ src/search.c
@@ -334,11 +334,10 @@
334 **
335 ** Run the full-scan search algorithm using SEARCHSTRING against
336 ** the text of the files listed. Output matches and snippets.
337 **
338 ** Options:
 
339 ** --begin TEXT Text to insert before each match
340 ** --end TEXT Text to insert after each match
341 ** --gap TEXT Text to indicate elided content
342 ** --html Input is HTML
343 ** --static Use the static Search object
@@ -583,11 +582,10 @@
582 ** score. The -limit option can be used to limit the number of entries
583 ** returned. The -width option can be used to set the output width used
584 ** when printing matches.
585 **
586 ** Options:
 
587 ** -a|--all Output all matches, not just best matches
588 ** -n|--limit N Limit output to N matches
589 ** -W|--width WIDTH Set display width to WIDTH columns, 0 for
590 ** unlimited. Defaults the terminal's width.
591 */
592
--- src/security_audit.c
+++ src/security_audit.c
@@ -761,10 +761,14 @@
761761
return;
762762
}
763763
style_header("Server Error Log");
764764
style_submenu_element("Test", "%R/test-warning");
765765
style_submenu_element("Refresh", "%R/errorlog");
766
+ style_submenu_element("Admin-Log", "admin_log");
767
+ style_submenu_element("User-Log", "access_log");
768
+ style_submenu_element("Artifact-Log", "rcvfromlist");
769
+
766770
if( g.zErrlog==0 || fossil_strcmp(g.zErrlog,"-")==0 ){
767771
@ <p>To create a server error log:
768772
@ <ol>
769773
@ <li><p>
770774
@ If the server is running as CGI, then create a line in the CGI file
771775
--- src/security_audit.c
+++ src/security_audit.c
@@ -761,10 +761,14 @@
761 return;
762 }
763 style_header("Server Error Log");
764 style_submenu_element("Test", "%R/test-warning");
765 style_submenu_element("Refresh", "%R/errorlog");
 
 
 
 
766 if( g.zErrlog==0 || fossil_strcmp(g.zErrlog,"-")==0 ){
767 @ <p>To create a server error log:
768 @ <ol>
769 @ <li><p>
770 @ If the server is running as CGI, then create a line in the CGI file
771
--- src/security_audit.c
+++ src/security_audit.c
@@ -761,10 +761,14 @@
761 return;
762 }
763 style_header("Server Error Log");
764 style_submenu_element("Test", "%R/test-warning");
765 style_submenu_element("Refresh", "%R/errorlog");
766 style_submenu_element("Admin-Log", "admin_log");
767 style_submenu_element("User-Log", "access_log");
768 style_submenu_element("Artifact-Log", "rcvfromlist");
769
770 if( g.zErrlog==0 || fossil_strcmp(g.zErrlog,"-")==0 ){
771 @ <p>To create a server error log:
772 @ <ol>
773 @ <li><p>
774 @ If the server is running as CGI, then create a line in the CGI file
775
+12
--- src/setup.c
+++ src/setup.c
@@ -594,10 +594,19 @@
594594
@ A self-registration creates a new entry in the USER table and
595595
@ perhaps also in the SUBSCRIBER table if email notification is
596596
@ enabled.
597597
@ (Property: "self-register")</p>
598598
599
+ @ <hr />
600
+ onoff_attribute("Allow users to reset their own passwords",
601
+ "self-pw-reset", "selfpw", 0, 0);
602
+ @ <p>Allow users to request that an email contains a hyperlink to a
603
+ @ password reset page be sent to their email address of record. This
604
+ @ enables forgetful users to recover their forgotten passwords without
605
+ @ administrator intervention.
606
+ @ (Property: "self-pw-reset")</p>
607
+
599608
@ <hr />
600609
onoff_attribute("Email verification required for self-registration",
601610
"selfreg-verify", "sfverify", 0, 0);
602611
@ <p>If enabled, self-registration creates a new entry in the USER table
603612
@ with only capabilities "7". The default user capabilities are not
@@ -1943,10 +1952,13 @@
19431952
login_needed(0);
19441953
return;
19451954
}
19461955
style_set_current_feature("setup");
19471956
style_header("Admin Log");
1957
+ style_submenu_element("User-Log", "access_log");
1958
+ style_submenu_element("Artifact-Log", "rcvfromlist");
1959
+ style_submenu_element("Error-Log", "errorlog");
19481960
create_admin_log_table();
19491961
limit = atoi(PD("n","200"));
19501962
ofst = atoi(PD("x","0"));
19511963
fLogEnabled = db_get_boolean("admin-log", 0);
19521964
@ <div>Admin logging is %s(fLogEnabled?"on":"off").
19531965
--- src/setup.c
+++ src/setup.c
@@ -594,10 +594,19 @@
594 @ A self-registration creates a new entry in the USER table and
595 @ perhaps also in the SUBSCRIBER table if email notification is
596 @ enabled.
597 @ (Property: "self-register")</p>
598
 
 
 
 
 
 
 
 
 
599 @ <hr />
600 onoff_attribute("Email verification required for self-registration",
601 "selfreg-verify", "sfverify", 0, 0);
602 @ <p>If enabled, self-registration creates a new entry in the USER table
603 @ with only capabilities "7". The default user capabilities are not
@@ -1943,10 +1952,13 @@
1943 login_needed(0);
1944 return;
1945 }
1946 style_set_current_feature("setup");
1947 style_header("Admin Log");
 
 
 
1948 create_admin_log_table();
1949 limit = atoi(PD("n","200"));
1950 ofst = atoi(PD("x","0"));
1951 fLogEnabled = db_get_boolean("admin-log", 0);
1952 @ <div>Admin logging is %s(fLogEnabled?"on":"off").
1953
--- src/setup.c
+++ src/setup.c
@@ -594,10 +594,19 @@
594 @ A self-registration creates a new entry in the USER table and
595 @ perhaps also in the SUBSCRIBER table if email notification is
596 @ enabled.
597 @ (Property: "self-register")</p>
598
599 @ <hr />
600 onoff_attribute("Allow users to reset their own passwords",
601 "self-pw-reset", "selfpw", 0, 0);
602 @ <p>Allow users to request that an email contains a hyperlink to a
603 @ password reset page be sent to their email address of record. This
604 @ enables forgetful users to recover their forgotten passwords without
605 @ administrator intervention.
606 @ (Property: "self-pw-reset")</p>
607
608 @ <hr />
609 onoff_attribute("Email verification required for self-registration",
610 "selfreg-verify", "sfverify", 0, 0);
611 @ <p>If enabled, self-registration creates a new entry in the USER table
612 @ with only capabilities "7". The default user capabilities are not
@@ -1943,10 +1952,13 @@
1952 login_needed(0);
1953 return;
1954 }
1955 style_set_current_feature("setup");
1956 style_header("Admin Log");
1957 style_submenu_element("User-Log", "access_log");
1958 style_submenu_element("Artifact-Log", "rcvfromlist");
1959 style_submenu_element("Error-Log", "errorlog");
1960 create_admin_log_table();
1961 limit = atoi(PD("n","200"));
1962 ofst = atoi(PD("x","0"));
1963 fLogEnabled = db_get_boolean("admin-log", 0);
1964 @ <div>Admin logging is %s(fLogEnabled?"on":"off").
1965
+1 -1
--- src/sha1.c
+++ src/sha1.c
@@ -501,12 +501,12 @@
501501
**
502502
** Usage: %fossil sha1sum FILE...
503503
**
504504
** Compute an SHA1 checksum of all files named on the command-line.
505505
** If a file is named "-" then take its content from standard input.
506
-** Options:
507506
**
507
+** Options:
508508
** -h|--dereference If FILE is a symbolic link, compute the hash
509509
** on the object that the link points to. Normally,
510510
** the hash is over the name of the object that
511511
** the link points to.
512512
**
513513
--- src/sha1.c
+++ src/sha1.c
@@ -501,12 +501,12 @@
501 **
502 ** Usage: %fossil sha1sum FILE...
503 **
504 ** Compute an SHA1 checksum of all files named on the command-line.
505 ** If a file is named "-" then take its content from standard input.
506 ** Options:
507 **
 
508 ** -h|--dereference If FILE is a symbolic link, compute the hash
509 ** on the object that the link points to. Normally,
510 ** the hash is over the name of the object that
511 ** the link points to.
512 **
513
--- src/sha1.c
+++ src/sha1.c
@@ -501,12 +501,12 @@
501 **
502 ** Usage: %fossil sha1sum FILE...
503 **
504 ** Compute an SHA1 checksum of all files named on the command-line.
505 ** If a file is named "-" then take its content from standard input.
 
506 **
507 ** Options:
508 ** -h|--dereference If FILE is a symbolic link, compute the hash
509 ** on the object that the link points to. Normally,
510 ** the hash is over the name of the object that
511 ** the link points to.
512 **
513
-1
--- src/sha3.c
+++ src/sha3.c
@@ -628,11 +628,10 @@
628628
**
629629
** To be clear: The official NIST FIPS-202 implementation of SHA3
630630
** with the added 01 padding is used, not the original Keccak submission.
631631
**
632632
** Options:
633
-**
634633
** --224 Compute a SHA3-224 hash
635634
** --256 Compute a SHA3-256 hash (the default)
636635
** --384 Compute a SHA3-384 hash
637636
** --512 Compute a SHA3-512 hash
638637
** --size N An N-bit hash. N must be a multiple of 32 between
639638
--- src/sha3.c
+++ src/sha3.c
@@ -628,11 +628,10 @@
628 **
629 ** To be clear: The official NIST FIPS-202 implementation of SHA3
630 ** with the added 01 padding is used, not the original Keccak submission.
631 **
632 ** Options:
633 **
634 ** --224 Compute a SHA3-224 hash
635 ** --256 Compute a SHA3-256 hash (the default)
636 ** --384 Compute a SHA3-384 hash
637 ** --512 Compute a SHA3-512 hash
638 ** --size N An N-bit hash. N must be a multiple of 32 between
639
--- src/sha3.c
+++ src/sha3.c
@@ -628,11 +628,10 @@
628 **
629 ** To be clear: The official NIST FIPS-202 implementation of SHA3
630 ** with the added 01 padding is used, not the original Keccak submission.
631 **
632 ** Options:
 
633 ** --224 Compute a SHA3-224 hash
634 ** --256 Compute a SHA3-256 hash (the default)
635 ** --384 Compute a SHA3-384 hash
636 ** --512 Compute a SHA3-512 hash
637 ** --size N An N-bit hash. N must be a multiple of 32 between
638
+3
--- src/shun.c
+++ src/shun.c
@@ -316,10 +316,13 @@
316316
if( !g.perm.Admin ){
317317
login_needed(0);
318318
return;
319319
}
320320
style_header("Artifact Receipts");
321
+ style_submenu_element("Admin-Log", "admin_log");
322
+ style_submenu_element("User-Log", "access_log");
323
+ style_submenu_element("Error-Log", "errorlog");
321324
if( showAll ){
322325
ofst = 0;
323326
}else{
324327
style_submenu_element("All", "rcvfromlist?all=1");
325328
}
326329
--- src/shun.c
+++ src/shun.c
@@ -316,10 +316,13 @@
316 if( !g.perm.Admin ){
317 login_needed(0);
318 return;
319 }
320 style_header("Artifact Receipts");
 
 
 
321 if( showAll ){
322 ofst = 0;
323 }else{
324 style_submenu_element("All", "rcvfromlist?all=1");
325 }
326
--- src/shun.c
+++ src/shun.c
@@ -316,10 +316,13 @@
316 if( !g.perm.Admin ){
317 login_needed(0);
318 return;
319 }
320 style_header("Artifact Receipts");
321 style_submenu_element("Admin-Log", "admin_log");
322 style_submenu_element("User-Log", "access_log");
323 style_submenu_element("Error-Log", "errorlog");
324 if( showAll ){
325 ofst = 0;
326 }else{
327 style_submenu_element("All", "rcvfromlist?all=1");
328 }
329
-2
--- src/smtp.c
+++ src/smtp.c
@@ -423,11 +423,10 @@
423423
** Interact with the SMTP server for DOMAIN by setting up a connection
424424
** and then immediately shutting it back down. Log all interaction
425425
** on the console. Use ME as the domain name of the sender.
426426
**
427427
** Options:
428
-**
429428
** --direct Use DOMAIN directly without going through MX
430429
** --port N Talk on TCP port N
431430
*/
432431
void test_smtp_probe(void){
433432
SmtpSession *p;
@@ -596,11 +595,10 @@
596595
**
597596
** Use SMTP to send the email message contained in the file named EMAIL
598597
** to the list of users TO. FROM is the sender of the email.
599598
**
600599
** Options:
601
-**
602600
** --direct Go directly to the TO domain. Bypass MX lookup
603601
** --relayhost R Use R as relay host directly for delivery.
604602
** --port N Use TCP port N instead of 25
605603
** --trace Show the SMTP conversation on the console
606604
*/
607605
--- src/smtp.c
+++ src/smtp.c
@@ -423,11 +423,10 @@
423 ** Interact with the SMTP server for DOMAIN by setting up a connection
424 ** and then immediately shutting it back down. Log all interaction
425 ** on the console. Use ME as the domain name of the sender.
426 **
427 ** Options:
428 **
429 ** --direct Use DOMAIN directly without going through MX
430 ** --port N Talk on TCP port N
431 */
432 void test_smtp_probe(void){
433 SmtpSession *p;
@@ -596,11 +595,10 @@
596 **
597 ** Use SMTP to send the email message contained in the file named EMAIL
598 ** to the list of users TO. FROM is the sender of the email.
599 **
600 ** Options:
601 **
602 ** --direct Go directly to the TO domain. Bypass MX lookup
603 ** --relayhost R Use R as relay host directly for delivery.
604 ** --port N Use TCP port N instead of 25
605 ** --trace Show the SMTP conversation on the console
606 */
607
--- src/smtp.c
+++ src/smtp.c
@@ -423,11 +423,10 @@
423 ** Interact with the SMTP server for DOMAIN by setting up a connection
424 ** and then immediately shutting it back down. Log all interaction
425 ** on the console. Use ME as the domain name of the sender.
426 **
427 ** Options:
 
428 ** --direct Use DOMAIN directly without going through MX
429 ** --port N Talk on TCP port N
430 */
431 void test_smtp_probe(void){
432 SmtpSession *p;
@@ -596,11 +595,10 @@
595 **
596 ** Use SMTP to send the email message contained in the file named EMAIL
597 ** to the list of users TO. FROM is the sender of the email.
598 **
599 ** Options:
 
600 ** --direct Go directly to the TO domain. Bypass MX lookup
601 ** --relayhost R Use R as relay host directly for delivery.
602 ** --port N Use TCP port N instead of 25
603 ** --trace Show the SMTP conversation on the console
604 */
605
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -332,19 +332,15 @@
332332
** in ways that are unrecoverable. Be sure you know what you are doing before
333333
** running any SQL commands that modify the repository database. Use the
334334
** --readonly option to prevent accidental damage to the repository.
335335
**
336336
** Options:
337
-**
338337
** --no-repository Skip opening the repository database
339
-**
340338
** --readonly Open the repository read-only. No changes
341339
** are allowed. This is a recommended safety
342340
** precaution to prevent repository damage.
343
-**
344341
** -R REPOSITORY Use REPOSITORY as the repository database
345
-**
346342
** --test Enable some testing and analysis features
347343
** that are normally disabled.
348344
**
349345
** All of the standard sqlite3 command-line shell options should also
350346
** work.
351347
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -332,19 +332,15 @@
332 ** in ways that are unrecoverable. Be sure you know what you are doing before
333 ** running any SQL commands that modify the repository database. Use the
334 ** --readonly option to prevent accidental damage to the repository.
335 **
336 ** Options:
337 **
338 ** --no-repository Skip opening the repository database
339 **
340 ** --readonly Open the repository read-only. No changes
341 ** are allowed. This is a recommended safety
342 ** precaution to prevent repository damage.
343 **
344 ** -R REPOSITORY Use REPOSITORY as the repository database
345 **
346 ** --test Enable some testing and analysis features
347 ** that are normally disabled.
348 **
349 ** All of the standard sqlite3 command-line shell options should also
350 ** work.
351
--- src/sqlcmd.c
+++ src/sqlcmd.c
@@ -332,19 +332,15 @@
332 ** in ways that are unrecoverable. Be sure you know what you are doing before
333 ** running any SQL commands that modify the repository database. Use the
334 ** --readonly option to prevent accidental damage to the repository.
335 **
336 ** Options:
 
337 ** --no-repository Skip opening the repository database
 
338 ** --readonly Open the repository read-only. No changes
339 ** are allowed. This is a recommended safety
340 ** precaution to prevent repository damage.
 
341 ** -R REPOSITORY Use REPOSITORY as the repository database
 
342 ** --test Enable some testing and analysis features
343 ** that are normally disabled.
344 **
345 ** All of the standard sqlite3 command-line shell options should also
346 ** work.
347
-1
--- src/stat.c
+++ src/stat.c
@@ -333,11 +333,10 @@
333333
**
334334
** Shows statistics and global information about the repository and/or
335335
** verify the integrity of a repository.
336336
**
337337
** Options:
338
-**
339338
** -b|--brief Only show essential elements
340339
** --db-check Run "PRAGMA quick_check" on the repository database
341340
** --db-verify Run a full verification of the repository integrity.
342341
** This involves decoding and reparsing all artifacts
343342
** and can take significant time.
344343
--- src/stat.c
+++ src/stat.c
@@ -333,11 +333,10 @@
333 **
334 ** Shows statistics and global information about the repository and/or
335 ** verify the integrity of a repository.
336 **
337 ** Options:
338 **
339 ** -b|--brief Only show essential elements
340 ** --db-check Run "PRAGMA quick_check" on the repository database
341 ** --db-verify Run a full verification of the repository integrity.
342 ** This involves decoding and reparsing all artifacts
343 ** and can take significant time.
344
--- src/stat.c
+++ src/stat.c
@@ -333,11 +333,10 @@
333 **
334 ** Shows statistics and global information about the repository and/or
335 ** verify the integrity of a repository.
336 **
337 ** Options:
 
338 ** -b|--brief Only show essential elements
339 ** --db-check Run "PRAGMA quick_check" on the repository database
340 ** --db-verify Run a full verification of the repository integrity.
341 ** This involves decoding and reparsing all artifacts
342 ** and can take significant time.
343
-4
--- src/sync.c
+++ src/sync.c
@@ -319,11 +319,10 @@
319319
** If URL is not specified, then the URL from the most recent clone, push,
320320
** pull, remote, or sync command is used. See "fossil help clone" for
321321
** details on the URL formats.
322322
**
323323
** Options:
324
-**
325324
** --all Pull from all remotes, not just the default
326325
** -B|--httpauth USER:PASS Credentials for the simple HTTP auth protocol,
327326
** if required by the remote website
328327
** --from-parent-project Pull content from the parent project
329328
** --ipv4 Use only IPv4, not IPv6
@@ -374,11 +373,10 @@
374373
** If URL is not specified, then the URL from the most recent clone, push,
375374
** pull, remote, or sync command is used. See "fossil help clone" for
376375
** details on the URL formats.
377376
**
378377
** Options:
379
-**
380378
** --all Push to all remotes, not just the default
381379
** -B|--httpauth USER:PASS Credentials for the simple HTTP auth protocol,
382380
** if required by the remote website
383381
** --ipv4 Use only IPv4, not IPv6
384382
** --no-http-compression Do not compress HTTP traffic
@@ -423,11 +421,10 @@
423421
** If URL is not specified, then the URL from the most recent clone, push,
424422
** pull, remote, or sync command is used. See "fossil help clone" for
425423
** details on the URL formats.
426424
**
427425
** Options:
428
-**
429426
** --all Sync with all remotes, not just the default
430427
** -B|--httpauth USER:PASS Credentials for the simple HTTP auth protocol,
431428
** if required by the remote website
432429
** --ipv4 Use only IPv4, not IPv6
433430
** --no-http-compression Do not compress HTTP traffic
@@ -831,11 +828,10 @@
831828
** Only the main repository database is backed up by this command. The
832829
** open check-out file (if any) is not saved. Nor is the global configuration
833830
** database.
834831
**
835832
** Options:
836
-**
837833
** --overwrite OK to overwrite an existing file
838834
** -R NAME Filename of the repository to backup
839835
*/
840836
void backup_cmd(void){
841837
char *zDest;
842838
--- src/sync.c
+++ src/sync.c
@@ -319,11 +319,10 @@
319 ** If URL is not specified, then the URL from the most recent clone, push,
320 ** pull, remote, or sync command is used. See "fossil help clone" for
321 ** details on the URL formats.
322 **
323 ** Options:
324 **
325 ** --all Pull from all remotes, not just the default
326 ** -B|--httpauth USER:PASS Credentials for the simple HTTP auth protocol,
327 ** if required by the remote website
328 ** --from-parent-project Pull content from the parent project
329 ** --ipv4 Use only IPv4, not IPv6
@@ -374,11 +373,10 @@
374 ** If URL is not specified, then the URL from the most recent clone, push,
375 ** pull, remote, or sync command is used. See "fossil help clone" for
376 ** details on the URL formats.
377 **
378 ** Options:
379 **
380 ** --all Push to all remotes, not just the default
381 ** -B|--httpauth USER:PASS Credentials for the simple HTTP auth protocol,
382 ** if required by the remote website
383 ** --ipv4 Use only IPv4, not IPv6
384 ** --no-http-compression Do not compress HTTP traffic
@@ -423,11 +421,10 @@
423 ** If URL is not specified, then the URL from the most recent clone, push,
424 ** pull, remote, or sync command is used. See "fossil help clone" for
425 ** details on the URL formats.
426 **
427 ** Options:
428 **
429 ** --all Sync with all remotes, not just the default
430 ** -B|--httpauth USER:PASS Credentials for the simple HTTP auth protocol,
431 ** if required by the remote website
432 ** --ipv4 Use only IPv4, not IPv6
433 ** --no-http-compression Do not compress HTTP traffic
@@ -831,11 +828,10 @@
831 ** Only the main repository database is backed up by this command. The
832 ** open check-out file (if any) is not saved. Nor is the global configuration
833 ** database.
834 **
835 ** Options:
836 **
837 ** --overwrite OK to overwrite an existing file
838 ** -R NAME Filename of the repository to backup
839 */
840 void backup_cmd(void){
841 char *zDest;
842
--- src/sync.c
+++ src/sync.c
@@ -319,11 +319,10 @@
319 ** If URL is not specified, then the URL from the most recent clone, push,
320 ** pull, remote, or sync command is used. See "fossil help clone" for
321 ** details on the URL formats.
322 **
323 ** Options:
 
324 ** --all Pull from all remotes, not just the default
325 ** -B|--httpauth USER:PASS Credentials for the simple HTTP auth protocol,
326 ** if required by the remote website
327 ** --from-parent-project Pull content from the parent project
328 ** --ipv4 Use only IPv4, not IPv6
@@ -374,11 +373,10 @@
373 ** If URL is not specified, then the URL from the most recent clone, push,
374 ** pull, remote, or sync command is used. See "fossil help clone" for
375 ** details on the URL formats.
376 **
377 ** Options:
 
378 ** --all Push to all remotes, not just the default
379 ** -B|--httpauth USER:PASS Credentials for the simple HTTP auth protocol,
380 ** if required by the remote website
381 ** --ipv4 Use only IPv4, not IPv6
382 ** --no-http-compression Do not compress HTTP traffic
@@ -423,11 +421,10 @@
421 ** If URL is not specified, then the URL from the most recent clone, push,
422 ** pull, remote, or sync command is used. See "fossil help clone" for
423 ** details on the URL formats.
424 **
425 ** Options:
 
426 ** --all Sync with all remotes, not just the default
427 ** -B|--httpauth USER:PASS Credentials for the simple HTTP auth protocol,
428 ** if required by the remote website
429 ** --ipv4 Use only IPv4, not IPv6
430 ** --no-http-compression Do not compress HTTP traffic
@@ -831,11 +828,10 @@
828 ** Only the main repository database is backed up by this command. The
829 ** open check-out file (if any) is not saved. Nor is the global configuration
830 ** database.
831 **
832 ** Options:
 
833 ** --overwrite OK to overwrite an existing file
834 ** -R NAME Filename of the repository to backup
835 */
836 void backup_cmd(void){
837 char *zDest;
838
--- src/th_main.c
+++ src/th_main.c
@@ -2939,11 +2939,10 @@
29392939
** Read the content of the file named "FILE" as if it were a header or
29402940
** footer or ticket rendering script, evaluate it, and show the results
29412941
** on standard output.
29422942
**
29432943
** Options:
2944
-**
29452944
** --cgi Include a CGI response header in the output
29462945
** --http Include an HTTP response header in the output
29472946
** --open-config Open the configuration database
29482947
** --set-anon-caps Set anonymous login capabilities
29492948
** --set-user-caps Set user login capabilities
@@ -2989,11 +2988,10 @@
29892988
** Evaluate SCRIPT as if it were a header or footer or ticket rendering
29902989
** script and show the results on standard output. SCRIPT may be either
29912990
** a filename or a string of th1 script code.
29922991
**
29932992
** Options:
2994
-**
29952993
** --cgi Include a CGI response header in the output
29962994
** --http Include an HTTP response header in the output
29972995
** --open-config Open the configuration database
29982996
** --set-anon-caps Set anonymous login capabilities
29992997
** --set-user-caps Set user login capabilities
@@ -3050,11 +3048,10 @@
30503048
** Evaluate the contents of the file named "FILE" as if it were a header
30513049
** or footer or ticket rendering script and show the results on standard
30523050
** output.
30533051
**
30543052
** Options:
3055
-**
30563053
** --cgi Include a CGI response header in the output
30573054
** --http Include an HTTP response header in the output
30583055
** --open-config Open the configuration database
30593056
** --set-anon-caps Set anonymous login capabilities
30603057
** --set-user-caps Set user login capabilities
@@ -3133,11 +3130,10 @@
31333130
** webnotify Executes the TH1 procedure [webpage_notify], after
31343131
** setting the TH1 variables "web_name", "web_args",
31353132
** and "web_flags" to appropriate values.
31363133
**
31373134
** Options:
3138
-**
31393135
** --cgi Include a CGI response header in the output
31403136
** --http Include an HTTP response header in the output
31413137
** --th-trace Trace TH1 execution (for debugging purposes)
31423138
*/
31433139
void test_th_hook(void){
31443140
--- src/th_main.c
+++ src/th_main.c
@@ -2939,11 +2939,10 @@
2939 ** Read the content of the file named "FILE" as if it were a header or
2940 ** footer or ticket rendering script, evaluate it, and show the results
2941 ** on standard output.
2942 **
2943 ** Options:
2944 **
2945 ** --cgi Include a CGI response header in the output
2946 ** --http Include an HTTP response header in the output
2947 ** --open-config Open the configuration database
2948 ** --set-anon-caps Set anonymous login capabilities
2949 ** --set-user-caps Set user login capabilities
@@ -2989,11 +2988,10 @@
2989 ** Evaluate SCRIPT as if it were a header or footer or ticket rendering
2990 ** script and show the results on standard output. SCRIPT may be either
2991 ** a filename or a string of th1 script code.
2992 **
2993 ** Options:
2994 **
2995 ** --cgi Include a CGI response header in the output
2996 ** --http Include an HTTP response header in the output
2997 ** --open-config Open the configuration database
2998 ** --set-anon-caps Set anonymous login capabilities
2999 ** --set-user-caps Set user login capabilities
@@ -3050,11 +3048,10 @@
3050 ** Evaluate the contents of the file named "FILE" as if it were a header
3051 ** or footer or ticket rendering script and show the results on standard
3052 ** output.
3053 **
3054 ** Options:
3055 **
3056 ** --cgi Include a CGI response header in the output
3057 ** --http Include an HTTP response header in the output
3058 ** --open-config Open the configuration database
3059 ** --set-anon-caps Set anonymous login capabilities
3060 ** --set-user-caps Set user login capabilities
@@ -3133,11 +3130,10 @@
3133 ** webnotify Executes the TH1 procedure [webpage_notify], after
3134 ** setting the TH1 variables "web_name", "web_args",
3135 ** and "web_flags" to appropriate values.
3136 **
3137 ** Options:
3138 **
3139 ** --cgi Include a CGI response header in the output
3140 ** --http Include an HTTP response header in the output
3141 ** --th-trace Trace TH1 execution (for debugging purposes)
3142 */
3143 void test_th_hook(void){
3144
--- src/th_main.c
+++ src/th_main.c
@@ -2939,11 +2939,10 @@
2939 ** Read the content of the file named "FILE" as if it were a header or
2940 ** footer or ticket rendering script, evaluate it, and show the results
2941 ** on standard output.
2942 **
2943 ** Options:
 
2944 ** --cgi Include a CGI response header in the output
2945 ** --http Include an HTTP response header in the output
2946 ** --open-config Open the configuration database
2947 ** --set-anon-caps Set anonymous login capabilities
2948 ** --set-user-caps Set user login capabilities
@@ -2989,11 +2988,10 @@
2988 ** Evaluate SCRIPT as if it were a header or footer or ticket rendering
2989 ** script and show the results on standard output. SCRIPT may be either
2990 ** a filename or a string of th1 script code.
2991 **
2992 ** Options:
 
2993 ** --cgi Include a CGI response header in the output
2994 ** --http Include an HTTP response header in the output
2995 ** --open-config Open the configuration database
2996 ** --set-anon-caps Set anonymous login capabilities
2997 ** --set-user-caps Set user login capabilities
@@ -3050,11 +3048,10 @@
3048 ** Evaluate the contents of the file named "FILE" as if it were a header
3049 ** or footer or ticket rendering script and show the results on standard
3050 ** output.
3051 **
3052 ** Options:
 
3053 ** --cgi Include a CGI response header in the output
3054 ** --http Include an HTTP response header in the output
3055 ** --open-config Open the configuration database
3056 ** --set-anon-caps Set anonymous login capabilities
3057 ** --set-user-caps Set user login capabilities
@@ -3133,11 +3130,10 @@
3130 ** webnotify Executes the TH1 procedure [webpage_notify], after
3131 ** setting the TH1 variables "web_name", "web_args",
3132 ** and "web_flags" to appropriate values.
3133 **
3134 ** Options:
 
3135 ** --cgi Include a CGI response header in the output
3136 ** --http Include an HTTP response header in the output
3137 ** --th-trace Trace TH1 execution (for debugging purposes)
3138 */
3139 void test_th_hook(void){
3140
--- src/unversioned.c
+++ src/unversioned.c
@@ -250,12 +250,13 @@
250250
** edit FILE Bring up FILE in a text editor for modification.
251251
**
252252
** export FILE OUTPUT Write the content of FILE into OUTPUT on disk
253253
**
254254
** list | ls Show all unversioned files held in the local
255
-** repository. Options:
255
+** repository.
256256
**
257
+** Options:
257258
** --glob PATTERN Show only files that match
258259
** --like PATTERN Show only files that match
259260
** -l Show additional details for
260261
** files that match. Implied
261262
** when 'list' is used.
@@ -269,12 +270,13 @@
269270
** -n|--dry-run Show what would have happened
270271
**
271272
** remove|rm|delete FILE ...
272273
** Remove unversioned files from the local repository.
273274
** Changes are not pushed to other repositories until
274
-** the next sync. Options:
275
+** the next sync.
275276
**
277
+** Options:
276278
** --glob PATTERN Remove files that match
277279
** --like PATTERN Remove files that match
278280
**
279281
** sync ?URL? Synchronize the state of all unversioned files with
280282
** the remote repository URL. The most recent version
@@ -286,11 +288,10 @@
286288
** -n|--dry-run Show what would have happened
287289
**
288290
** touch FILE ... Update the TIMESTAMP on all of the listed files
289291
**
290292
** Options:
291
-**
292293
** --mtime TIMESTAMP Use TIMESTAMP instead of "now" for the "add",
293294
** "edit", "remove", and "touch" subcommands.
294295
** -R|--repository REPO Use FILE as the repository
295296
*/
296297
void unversioned_cmd(void){
297298
--- src/unversioned.c
+++ src/unversioned.c
@@ -250,12 +250,13 @@
250 ** edit FILE Bring up FILE in a text editor for modification.
251 **
252 ** export FILE OUTPUT Write the content of FILE into OUTPUT on disk
253 **
254 ** list | ls Show all unversioned files held in the local
255 ** repository. Options:
256 **
 
257 ** --glob PATTERN Show only files that match
258 ** --like PATTERN Show only files that match
259 ** -l Show additional details for
260 ** files that match. Implied
261 ** when 'list' is used.
@@ -269,12 +270,13 @@
269 ** -n|--dry-run Show what would have happened
270 **
271 ** remove|rm|delete FILE ...
272 ** Remove unversioned files from the local repository.
273 ** Changes are not pushed to other repositories until
274 ** the next sync. Options:
275 **
 
276 ** --glob PATTERN Remove files that match
277 ** --like PATTERN Remove files that match
278 **
279 ** sync ?URL? Synchronize the state of all unversioned files with
280 ** the remote repository URL. The most recent version
@@ -286,11 +288,10 @@
286 ** -n|--dry-run Show what would have happened
287 **
288 ** touch FILE ... Update the TIMESTAMP on all of the listed files
289 **
290 ** Options:
291 **
292 ** --mtime TIMESTAMP Use TIMESTAMP instead of "now" for the "add",
293 ** "edit", "remove", and "touch" subcommands.
294 ** -R|--repository REPO Use FILE as the repository
295 */
296 void unversioned_cmd(void){
297
--- src/unversioned.c
+++ src/unversioned.c
@@ -250,12 +250,13 @@
250 ** edit FILE Bring up FILE in a text editor for modification.
251 **
252 ** export FILE OUTPUT Write the content of FILE into OUTPUT on disk
253 **
254 ** list | ls Show all unversioned files held in the local
255 ** repository.
256 **
257 ** Options:
258 ** --glob PATTERN Show only files that match
259 ** --like PATTERN Show only files that match
260 ** -l Show additional details for
261 ** files that match. Implied
262 ** when 'list' is used.
@@ -269,12 +270,13 @@
270 ** -n|--dry-run Show what would have happened
271 **
272 ** remove|rm|delete FILE ...
273 ** Remove unversioned files from the local repository.
274 ** Changes are not pushed to other repositories until
275 ** the next sync.
276 **
277 ** Options:
278 ** --glob PATTERN Remove files that match
279 ** --like PATTERN Remove files that match
280 **
281 ** sync ?URL? Synchronize the state of all unversioned files with
282 ** the remote repository URL. The most recent version
@@ -286,11 +288,10 @@
288 ** -n|--dry-run Show what would have happened
289 **
290 ** touch FILE ... Update the TIMESTAMP on all of the listed files
291 **
292 ** Options:
 
293 ** --mtime TIMESTAMP Use TIMESTAMP instead of "now" for the "add",
294 ** "edit", "remove", and "touch" subcommands.
295 ** -R|--repository REPO Use FILE as the repository
296 */
297 void unversioned_cmd(void){
298
+1 -1
--- src/url.c
+++ src/url.c
@@ -560,11 +560,11 @@
560560
*/
561561
void url_enable_proxy(const char *zMsg){
562562
const char *zProxy;
563563
zProxy = zProxyOpt;
564564
if( zProxy==0 ){
565
- zProxy = db_get("proxy", 0);
565
+ zProxy = db_get("proxy", "system");
566566
if( fossil_strcmp(zProxy, "system")==0 ){
567567
zProxy = fossil_getenv("http_proxy");
568568
}
569569
}
570570
if( zProxy && zProxy[0] && !is_false(zProxy)
571571
--- src/url.c
+++ src/url.c
@@ -560,11 +560,11 @@
560 */
561 void url_enable_proxy(const char *zMsg){
562 const char *zProxy;
563 zProxy = zProxyOpt;
564 if( zProxy==0 ){
565 zProxy = db_get("proxy", 0);
566 if( fossil_strcmp(zProxy, "system")==0 ){
567 zProxy = fossil_getenv("http_proxy");
568 }
569 }
570 if( zProxy && zProxy[0] && !is_false(zProxy)
571
--- src/url.c
+++ src/url.c
@@ -560,11 +560,11 @@
560 */
561 void url_enable_proxy(const char *zMsg){
562 const char *zProxy;
563 zProxy = zProxyOpt;
564 if( zProxy==0 ){
565 zProxy = db_get("proxy", "system");
566 if( fossil_strcmp(zProxy, "system")==0 ){
567 zProxy = fossil_getenv("http_proxy");
568 }
569 }
570 if( zProxy && zProxy[0] && !is_false(zProxy)
571
+4
--- src/user.c
+++ src/user.c
@@ -701,10 +701,14 @@
701701
" LIMIT -1 OFFSET 200)");
702702
cgi_redirectf("%R/access_log?y=%d&n=%d", y, n);
703703
return;
704704
}
705705
style_header("Access Log");
706
+ style_submenu_element("Admin-Log", "admin_log");
707
+ style_submenu_element("Artifact-Log", "rcvfromlist");
708
+ style_submenu_element("Error-Log", "errorlog");
709
+
706710
blob_zero(&sql);
707711
blob_append_sql(&sql,
708712
"SELECT uname, ipaddr, datetime(mtime,toLocal()), success"
709713
" FROM accesslog"
710714
);
711715
--- src/user.c
+++ src/user.c
@@ -701,10 +701,14 @@
701 " LIMIT -1 OFFSET 200)");
702 cgi_redirectf("%R/access_log?y=%d&n=%d", y, n);
703 return;
704 }
705 style_header("Access Log");
 
 
 
 
706 blob_zero(&sql);
707 blob_append_sql(&sql,
708 "SELECT uname, ipaddr, datetime(mtime,toLocal()), success"
709 " FROM accesslog"
710 );
711
--- src/user.c
+++ src/user.c
@@ -701,10 +701,14 @@
701 " LIMIT -1 OFFSET 200)");
702 cgi_redirectf("%R/access_log?y=%d&n=%d", y, n);
703 return;
704 }
705 style_header("Access Log");
706 style_submenu_element("Admin-Log", "admin_log");
707 style_submenu_element("Artifact-Log", "rcvfromlist");
708 style_submenu_element("Error-Log", "errorlog");
709
710 blob_zero(&sql);
711 blob_append_sql(&sql,
712 "SELECT uname, ipaddr, datetime(mtime,toLocal()), success"
713 " FROM accesslog"
714 );
715
-1
--- src/xfer.c
+++ src/xfer.c
@@ -1874,11 +1874,10 @@
18741874
** as necessary to generate an appropriate XFERFILE test case. Then run:
18751875
**
18761876
** fossil test-xfer xferfile.txt
18771877
**
18781878
** Options:
1879
-**
18801879
** --host HOSTNAME Supply a server hostname used to populate
18811880
** g.zBaseURL and similar.
18821881
*/
18831882
void cmd_test_xfer(void){
18841883
const char *zHost;
18851884
--- src/xfer.c
+++ src/xfer.c
@@ -1874,11 +1874,10 @@
1874 ** as necessary to generate an appropriate XFERFILE test case. Then run:
1875 **
1876 ** fossil test-xfer xferfile.txt
1877 **
1878 ** Options:
1879 **
1880 ** --host HOSTNAME Supply a server hostname used to populate
1881 ** g.zBaseURL and similar.
1882 */
1883 void cmd_test_xfer(void){
1884 const char *zHost;
1885
--- src/xfer.c
+++ src/xfer.c
@@ -1874,11 +1874,10 @@
1874 ** as necessary to generate an appropriate XFERFILE test case. Then run:
1875 **
1876 ** fossil test-xfer xferfile.txt
1877 **
1878 ** Options:
 
1879 ** --host HOSTNAME Supply a server hostname used to populate
1880 ** g.zBaseURL and similar.
1881 */
1882 void cmd_test_xfer(void){
1883 const char *zHost;
1884
-1
--- src/xfer.c
+++ src/xfer.c
@@ -1874,11 +1874,10 @@
18741874
** as necessary to generate an appropriate XFERFILE test case. Then run:
18751875
**
18761876
** fossil test-xfer xferfile.txt
18771877
**
18781878
** Options:
1879
-**
18801879
** --host HOSTNAME Supply a server hostname used to populate
18811880
** g.zBaseURL and similar.
18821881
*/
18831882
void cmd_test_xfer(void){
18841883
const char *zHost;
18851884
--- src/xfer.c
+++ src/xfer.c
@@ -1874,11 +1874,10 @@
1874 ** as necessary to generate an appropriate XFERFILE test case. Then run:
1875 **
1876 ** fossil test-xfer xferfile.txt
1877 **
1878 ** Options:
1879 **
1880 ** --host HOSTNAME Supply a server hostname used to populate
1881 ** g.zBaseURL and similar.
1882 */
1883 void cmd_test_xfer(void){
1884 const char *zHost;
1885
--- src/xfer.c
+++ src/xfer.c
@@ -1874,11 +1874,10 @@
1874 ** as necessary to generate an appropriate XFERFILE test case. Then run:
1875 **
1876 ** fossil test-xfer xferfile.txt
1877 **
1878 ** Options:
 
1879 ** --host HOSTNAME Supply a server hostname used to populate
1880 ** g.zBaseURL and similar.
1881 */
1882 void cmd_test_xfer(void){
1883 const char *zHost;
1884
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,14 +1,22 @@
11
<title>Change Log</title>
22
33
<h2 id='v2_21'>Changes for version 2.21 (pending)</h2>
4
+ * Add the [/help?cmd=self-pw-reset|self-pw-reset property] and the
5
+ [/help?cmd=/resetpw|/resetpw page] and the [/help?cmd=/reqpwreset|/reqpwreset page]
6
+ while all work together to give users the ability to request a password
7
+ reset without administrator involvement.
48
* Add the ability to put text descriptions on ticket report formats.
59
* Upgrade the test-find-pivot command to the [/help/merge-base|merge-base command].
610
* The [/help?cmd=/chat|/chat page] can now embed fossil-rendered
711
views of wiki/markdown/pikchr file attachments with the caveat that such
812
embedding happens in an iframe and thus does not inherit styles and such
913
from the containing browser window.
14
+ * Passwords for remembered remote repositories are now stored as irreversible
15
+ hashes rather than obscured clear-text, for improved security.
16
+ * As additional defense-in-depth against attack, writes to the database
17
+ are disabled by default if the HTTP request does not come from the same origin.
1018
1119
<h2 id='v2_20'>Changes for version 2.20 (2022-11-16)</h2>
1220
* Added the [/help?cmd=chat-timeline-user|chat-timeline-user setting]. If
1321
it is not an empty string, then any changes that would appear on the timeline
1422
are announced in [./chat.md|the chat room].
1523
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,14 +1,22 @@
1 <title>Change Log</title>
2
3 <h2 id='v2_21'>Changes for version 2.21 (pending)</h2>
 
 
 
 
4 * Add the ability to put text descriptions on ticket report formats.
5 * Upgrade the test-find-pivot command to the [/help/merge-base|merge-base command].
6 * The [/help?cmd=/chat|/chat page] can now embed fossil-rendered
7 views of wiki/markdown/pikchr file attachments with the caveat that such
8 embedding happens in an iframe and thus does not inherit styles and such
9 from the containing browser window.
 
 
 
 
10
11 <h2 id='v2_20'>Changes for version 2.20 (2022-11-16)</h2>
12 * Added the [/help?cmd=chat-timeline-user|chat-timeline-user setting]. If
13 it is not an empty string, then any changes that would appear on the timeline
14 are announced in [./chat.md|the chat room].
15
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,14 +1,22 @@
1 <title>Change Log</title>
2
3 <h2 id='v2_21'>Changes for version 2.21 (pending)</h2>
4 * Add the [/help?cmd=self-pw-reset|self-pw-reset property] and the
5 [/help?cmd=/resetpw|/resetpw page] and the [/help?cmd=/reqpwreset|/reqpwreset page]
6 while all work together to give users the ability to request a password
7 reset without administrator involvement.
8 * Add the ability to put text descriptions on ticket report formats.
9 * Upgrade the test-find-pivot command to the [/help/merge-base|merge-base command].
10 * The [/help?cmd=/chat|/chat page] can now embed fossil-rendered
11 views of wiki/markdown/pikchr file attachments with the caveat that such
12 embedding happens in an iframe and thus does not inherit styles and such
13 from the containing browser window.
14 * Passwords for remembered remote repositories are now stored as irreversible
15 hashes rather than obscured clear-text, for improved security.
16 * As additional defense-in-depth against attack, writes to the database
17 are disabled by default if the HTTP request does not come from the same origin.
18
19 <h2 id='v2_20'>Changes for version 2.20 (2022-11-16)</h2>
20 * Added the [/help?cmd=chat-timeline-user|chat-timeline-user setting]. If
21 it is not an empty string, then any changes that would appear on the timeline
22 are announced in [./chat.md|the chat room].
23
--- www/relatedwork.md
+++ www/relatedwork.md
@@ -1,26 +1,28 @@
11
# Related Work
22
33
## Support Projects
44
5
-* [SQLite]: a C-language library that implements a small, fast,
5
+* [SQLite]: C-language library that implements a small, fast,
66
self-contained, high-reliability, full-featured, SQL database engine
7
-* [pikchr]: a PIC-like markup language for diagrams in technical
7
+* [pikchr]: PIC-like markup language for diagrams in technical
88
documentation
9
-* [althttpd]: a simple, secure, and low resource usage webserver
9
+* [althttpd]: simple, secure, and low resource usage webserver
1010
that has run the https://sqlite.org/ website since 2004
11
-* [Lemon Parser Generator][lemon]: an LALR(1), re-entrant, and thread-safe
12
- parser with a less error-prone grammar syntax than YACC or BISON
11
+* [Lemon Parser Generator][lemon]: re-entrant and thread-safe
12
+ LALR(1) parser with a less error-prone grammar syntax than YACC or BISON
1313
* [Makeheaders]: automatically generate header files for C/C++ projects
1414
1515
## Fossil Inspired Projects
1616
1717
* [libfossil]: 3rd party Fossil SCM Library API
18
-* [fnc]: an interactive text-based user interface for Fossil
19
-* [ChiselApp][chisel]: Free Fossil SCM hosting!
18
+* [fnc]: interactive text-based user interface for Fossil
19
+* [ChiselApp]: Free Fossil SCM hosting!
2020
* [Inskinerator]: The Fossil Skin Generator
21
-* [Fuel][fuel]: a cross-platform GUI front-end for the excellent Fossil SCM
21
+* [Fuel]: cross-platform GUI front-end for the excellent Fossil SCM
22
+* [fsl]: Tcl/Expect wrapper script extending Fossil functionality
23
+
2224
2325
## Editor Plugins
2426
2527
* [Emacs-Fossil][emacsfsl]: GNU Emacs VC backend for the Fossil version
2628
control system
@@ -57,18 +59,19 @@
5759
5860
[althttpd]: https://sqlite.org/althttpd/doc/trunk/althttpd.md
5961
[bsdtalk]: https://bsdtalk.blogspot.com/2010/07/bsdtalk194-fossil-scm-with-d-richard.html
6062
[changelog201]: https://changelog.com/podcast/201
6163
[changelog454]: https://changelog.com/podcast/454
62
-[chisel]: https://chiselapp.com/
64
+[ChiselApp]: https://chiselapp.com/
6365
[CLion]: https://www.jetbrains.com/clion/
6466
[corec66]: https://corecursive.com/066-sqlite-with-richard-hipp/
6567
[Darcs]: http://darcs.net/
6668
[db2w]: https://youtu.be/2eaQzahCeh4
6769
[emacsfsl]: https://chiselapp.com/user/venks/repository/emacs-fossil/doc/tip/README.md
6870
[floss26]: https://twit.tv/shows/floss-weekly/episodes/26
6971
[fnc]: https://fnc.bsdbox.org
72
+[fsl]: http://fossil.0branch.com/fsl
7073
[Fuel]: https://fuel-scm.org/fossil/index
7174
[Git]: https://git-scm.com
7275
[GoLand]: https://www.jetbrains.com/go/
7376
[got]: https://gameoftrees.org
7477
[Inskinerator]: https://tangentsoft.com/inskinerator
7578
--- www/relatedwork.md
+++ www/relatedwork.md
@@ -1,26 +1,28 @@
1 # Related Work
2
3 ## Support Projects
4
5 * [SQLite]: a C-language library that implements a small, fast,
6 self-contained, high-reliability, full-featured, SQL database engine
7 * [pikchr]: a PIC-like markup language for diagrams in technical
8 documentation
9 * [althttpd]: a simple, secure, and low resource usage webserver
10 that has run the https://sqlite.org/ website since 2004
11 * [Lemon Parser Generator][lemon]: an LALR(1), re-entrant, and thread-safe
12 parser with a less error-prone grammar syntax than YACC or BISON
13 * [Makeheaders]: automatically generate header files for C/C++ projects
14
15 ## Fossil Inspired Projects
16
17 * [libfossil]: 3rd party Fossil SCM Library API
18 * [fnc]: an interactive text-based user interface for Fossil
19 * [ChiselApp][chisel]: Free Fossil SCM hosting!
20 * [Inskinerator]: The Fossil Skin Generator
21 * [Fuel][fuel]: a cross-platform GUI front-end for the excellent Fossil SCM
 
 
22
23 ## Editor Plugins
24
25 * [Emacs-Fossil][emacsfsl]: GNU Emacs VC backend for the Fossil version
26 control system
@@ -57,18 +59,19 @@
57
58 [althttpd]: https://sqlite.org/althttpd/doc/trunk/althttpd.md
59 [bsdtalk]: https://bsdtalk.blogspot.com/2010/07/bsdtalk194-fossil-scm-with-d-richard.html
60 [changelog201]: https://changelog.com/podcast/201
61 [changelog454]: https://changelog.com/podcast/454
62 [chisel]: https://chiselapp.com/
63 [CLion]: https://www.jetbrains.com/clion/
64 [corec66]: https://corecursive.com/066-sqlite-with-richard-hipp/
65 [Darcs]: http://darcs.net/
66 [db2w]: https://youtu.be/2eaQzahCeh4
67 [emacsfsl]: https://chiselapp.com/user/venks/repository/emacs-fossil/doc/tip/README.md
68 [floss26]: https://twit.tv/shows/floss-weekly/episodes/26
69 [fnc]: https://fnc.bsdbox.org
 
70 [Fuel]: https://fuel-scm.org/fossil/index
71 [Git]: https://git-scm.com
72 [GoLand]: https://www.jetbrains.com/go/
73 [got]: https://gameoftrees.org
74 [Inskinerator]: https://tangentsoft.com/inskinerator
75
--- www/relatedwork.md
+++ www/relatedwork.md
@@ -1,26 +1,28 @@
1 # Related Work
2
3 ## Support Projects
4
5 * [SQLite]: C-language library that implements a small, fast,
6 self-contained, high-reliability, full-featured, SQL database engine
7 * [pikchr]: PIC-like markup language for diagrams in technical
8 documentation
9 * [althttpd]: simple, secure, and low resource usage webserver
10 that has run the https://sqlite.org/ website since 2004
11 * [Lemon Parser Generator][lemon]: re-entrant and thread-safe
12 LALR(1) parser with a less error-prone grammar syntax than YACC or BISON
13 * [Makeheaders]: automatically generate header files for C/C++ projects
14
15 ## Fossil Inspired Projects
16
17 * [libfossil]: 3rd party Fossil SCM Library API
18 * [fnc]: interactive text-based user interface for Fossil
19 * [ChiselApp]: Free Fossil SCM hosting!
20 * [Inskinerator]: The Fossil Skin Generator
21 * [Fuel]: cross-platform GUI front-end for the excellent Fossil SCM
22 * [fsl]: Tcl/Expect wrapper script extending Fossil functionality
23
24
25 ## Editor Plugins
26
27 * [Emacs-Fossil][emacsfsl]: GNU Emacs VC backend for the Fossil version
28 control system
@@ -57,18 +59,19 @@
59
60 [althttpd]: https://sqlite.org/althttpd/doc/trunk/althttpd.md
61 [bsdtalk]: https://bsdtalk.blogspot.com/2010/07/bsdtalk194-fossil-scm-with-d-richard.html
62 [changelog201]: https://changelog.com/podcast/201
63 [changelog454]: https://changelog.com/podcast/454
64 [ChiselApp]: https://chiselapp.com/
65 [CLion]: https://www.jetbrains.com/clion/
66 [corec66]: https://corecursive.com/066-sqlite-with-richard-hipp/
67 [Darcs]: http://darcs.net/
68 [db2w]: https://youtu.be/2eaQzahCeh4
69 [emacsfsl]: https://chiselapp.com/user/venks/repository/emacs-fossil/doc/tip/README.md
70 [floss26]: https://twit.tv/shows/floss-weekly/episodes/26
71 [fnc]: https://fnc.bsdbox.org
72 [fsl]: http://fossil.0branch.com/fsl
73 [Fuel]: https://fuel-scm.org/fossil/index
74 [Git]: https://git-scm.com
75 [GoLand]: https://www.jetbrains.com/go/
76 [got]: https://gameoftrees.org
77 [Inskinerator]: https://tangentsoft.com/inskinerator
78

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button